From ee26173b273ca5c57fd6f22e0db5d2dd6e7ea50d Mon Sep 17 00:00:00 2001 From: MKirova Date: Tue, 27 May 2025 17:30:23 +0300 Subject: [PATCH 01/29] fix(igxGrid): Make sure track changes resolves to string and tracks size change. --- projects/igniteui-angular/src/lib/grids/grid-base.directive.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts b/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts index 51a15d4eedc..92b257d5403 100644 --- a/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts +++ b/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts @@ -6137,7 +6137,7 @@ export abstract class IgxGridBaseDirective implements GridType, * @hidden @internal */ public trackColumnChanges(_index, col) { - return col.field + col._calcWidth; + return col.field + col._calcWidth.toString(); } /** From fef1c1ae63dd9d11bcb16f9d2a7b02223b805507 Mon Sep 17 00:00:00 2001 From: MKirova Date: Thu, 29 May 2025 17:22:41 +0300 Subject: [PATCH 02/29] fix(igxGrid): Adjust expandable cell styles. --- .../core/styles/components/grid/_grid-theme.scss | 14 +++++++++----- .../lib/grids/grid/expandable-cell.component.html | 3 +++ 2 files changed, 12 insertions(+), 5 deletions(-) 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..89d26a18d45 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 @@ -1514,6 +1514,9 @@ } %igx-grid__td--bool { + display: flex; + flex-grow: 1; + igx-icon { --component-size: #{if($variant == 'indigo', 2, 1)}; } @@ -2084,7 +2087,7 @@ .sort-icon { color: var-get($theme, 'header-selected-text-color'); - + ::after { background: var-get($theme, 'header-selected-background'); } @@ -2112,7 +2115,7 @@ &%igx-grid-th--sorted { .sort-icon { color: var-get($theme, 'header-selected-text-color'); - + > igx-icon { color: inherit; } @@ -2120,7 +2123,7 @@ &:focus, &:hover { color: var-get($theme, 'header-selected-text-color'); - + > igx-icon { color: inherit; } @@ -2177,14 +2180,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; } @@ -2220,6 +2223,7 @@ %grid-cell-number { text-align: $grid-cell-align-num; justify-content: flex-end; + flex-grow: 1; %grid-cell-header-icons { justify-content: flex-start; diff --git a/projects/igniteui-angular/src/lib/grids/grid/expandable-cell.component.html b/projects/igniteui-angular/src/lib/grids/grid/expandable-cell.component.html index e241c39710b..c6fca1627c8 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/expandable-cell.component.html +++ b/projects/igniteui-angular/src/lib/grids/grid/expandable-cell.component.html @@ -8,6 +8,7 @@
+
} @if (column.dataType === 'image') { From a5c8fb17a081db36b68867742abb9beaecfab67f Mon Sep 17 00:00:00 2001 From: Bozhidara Pachilova <35433937+ddaribo@users.noreply.github.com> Date: Tue, 10 Jun 2025 10:58:00 +0300 Subject: [PATCH 03/29] fix(grids): correct column position after unpinning when there are hidden columns - master (#15543) * chore(col-pinning-tests): remove duplicated test * test(column-pinning): order of columns after unpinning w/ hidden cols * fix(column): account for hidden cols with _unpinnedColumns for indices logic --------- Co-authored-by: Hristo --- .../src/lib/grids/columns/column.component.ts | 2 +- .../src/lib/grids/grid/column-pinning.spec.ts | 51 +++++++++++-------- 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/projects/igniteui-angular/src/lib/grids/columns/column.component.ts b/projects/igniteui-angular/src/lib/grids/columns/column.component.ts index 3482a5076f1..641c2fb5a0c 100644 --- a/projects/igniteui-angular/src/lib/grids/columns/column.component.ts +++ b/projects/igniteui-angular/src/lib/grids/columns/column.component.ts @@ -2310,7 +2310,7 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy // estimate the exact index at which column will be inserted // takes into account initial unpinned index of the column if (!hasIndex) { - const indices = grid.unpinnedColumns.map(col => col.index); + const indices = grid._unpinnedColumns.map(col => col.index); indices.push(this.index); indices.sort((a, b) => a - b); index = indices.indexOf(this.index); diff --git a/projects/igniteui-angular/src/lib/grids/grid/column-pinning.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/column-pinning.spec.ts index 4868ab888ff..ba56c6e63ca 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/column-pinning.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/column-pinning.spec.ts @@ -108,27 +108,6 @@ describe('Column Pinning UI #grid', () => { verifyColumnIsPinned(column, false, 0); }); - it('Checks order of columns after unpinning', () => { - for (const column of grid.columnList) { - column.pin(); - } - fix.detectChanges(); - grid.getColumnByName('ID').unpin(); - grid.getColumnByName('ReleaseDate').unpin(); - grid.getColumnByName('Downloads').unpin(); - grid.getColumnByName('ProductName').unpin(); - grid.getColumnByName('Released').unpin(); - fix.detectChanges(); - grid.unpinnedColumns.forEach((column, index) => { - if (index === grid.unpinnedColumns.length - 1) { - return; - } - expect( - column.index < grid.unpinnedColumns[index + 1].index - ).toBe(true); - }); - }); - it('reflects properly grid column pinned value changes.', () => { const name = 'ReleaseDate'; verifyCheckbox(name, false, false, columnChooserElement); @@ -307,6 +286,36 @@ describe('Column Pinning UI #grid', () => { ).toBe(true); }); }); + + it('Checks order of columns after unpinning if there are hidden columns', () => { + // Columns are ordered like this: ID, ProductName, Downloads, Released, ReleaseDate + expect(grid.getColumnByName('Downloads').index).toBe(2); + expect(grid.getColumnByName('Released').index).toBe(3); + + grid.getColumnByName('ID').hidden = true; + grid.getColumnByName('Downloads').pin(); + grid.getColumnByName('Released').pin(); + fix.detectChanges(); + + // unpinnedColumns contains only visible cols + expect(grid.unpinnedColumns.length).toBe(2); + // _unpinnedColumns contains all unpinned cols (including hidden) + expect((grid as any)._unpinnedColumns.length).toBe(3); + + grid.getColumnByName('Released').unpin(); + fix.detectChanges(); + + expect(grid.unpinnedColumns.length).toBe(3); + expect((grid as any)._unpinnedColumns.length).toBe(4); + // Downloads is still pinned; ID is not part of unpinnedColumns + expect(grid.getColumnByName('Released').field).toEqual((grid as any).unpinnedColumns[1].field); + expect(grid.getColumnByName('Released').field).toEqual((grid as any)._unpinnedColumns[2].field); + + grid.getColumnByName('Downloads').unpin(); + fix.detectChanges(); + expect(grid.getColumnByName('Downloads').field).toEqual((grid as any).unpinnedColumns[1].field); + expect(grid.getColumnByName('Downloads').field).toEqual((grid as any)._unpinnedColumns[2].field); + }); }); describe('Pinning with Column Groups', () => { From 9f22e44e7c57ae8710a78e220572b5082d29df00 Mon Sep 17 00:00:00 2001 From: Galina Edinakova Date: Tue, 10 Jun 2025 16:27:17 +0300 Subject: [PATCH 04/29] fix(Toolbar): Cancel export should hide the progress indicator. (#15923) --- .../src/lib/grids/grid/grid-toolbar.spec.ts | 21 ++++++++++++++++++- .../grid-toolbar-exporter.component.ts | 5 +++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid-toolbar.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/grid-toolbar.spec.ts index a1e0c06b827..4c94a942292 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid-toolbar.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/grid-toolbar.spec.ts @@ -173,6 +173,18 @@ describe('IgxGrid - Grid Toolbar #grid - ', () => { expect($('#csvEntry').textContent).toMatch(instance.customCSVText); }); + it('progress indicator should stop on canceling the export', () => { + fixture.componentInstance.exportStartCancelled = true; + fixture.detectChanges(); + $(TOOLBAR_EXPORTER_TAG).querySelector('button').click(); + fixture.detectChanges(); + $('#excelEntry').click(); + fixture.detectChanges(); + + expect(instance.exporterAction.isExporting).toBeFalse(); + expect(instance.exporterAction.toolbar.showProgress).toBeFalse(); + }); + it('Setting overlaySettings for each toolbar columns action', () => { const defaultSettings = instance.pinningAction.overlaySettings; const defaultFiltSettings = instance.advancedFiltAction.overlaySettings; @@ -297,7 +309,7 @@ export class DefaultToolbarComponent { {{ advancedFilteringTitle }} - + {{ exporterText }} {{ customExcelText }} {{ customCSVText }} @@ -346,8 +358,15 @@ export class ToolbarActionsComponent { modal: true, closeOnEscape: false }; + public exportStartCancelled = false; constructor() { this.data = [...DATA]; } + + public exportStarted(args) { + if (this.exportStartCancelled) { + args.cancel = true; + } + } } diff --git a/projects/igniteui-angular/src/lib/grids/toolbar/grid-toolbar-exporter.component.ts b/projects/igniteui-angular/src/lib/grids/toolbar/grid-toolbar-exporter.component.ts index fa0886cd237..f2b63fd0f65 100644 --- a/projects/igniteui-angular/src/lib/grids/toolbar/grid-toolbar-exporter.component.ts +++ b/projects/igniteui-angular/src/lib/grids/toolbar/grid-toolbar-exporter.component.ts @@ -126,13 +126,14 @@ export class IgxGridToolbarExporterComponent extends BaseToolbarDirective { this.exportStarted.emit(args); this.grid.toolbarExporting.emit(args); - this.isExporting = true; - this.toolbar.showProgress = true; if (args.cancel) { return; } + this.isExporting = true; + this.toolbar.showProgress = true; + exporter.exportEnded.pipe(first()).subscribe(() => { this.exportEnded.emit(); this.isExporting = false; From ba9380d2f6ef1f2b8d4f93977124ed2083e10b03 Mon Sep 17 00:00:00 2001 From: Adrian Petrov <99720888+adrianptrv@users.noreply.github.com> Date: Wed, 11 Jun 2025 16:49:37 +0300 Subject: [PATCH 05/29] fix(button): active-shadow property is not applied (#15914) Co-authored-by: Simeon Simeonoff --- .../lib/core/styles/components/button/_button-theme.scss | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/projects/igniteui-angular/src/lib/core/styles/components/button/_button-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/button/_button-theme.scss index e431e1bb1a4..93f0ba40041 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/button/_button-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/button/_button-theme.scss @@ -39,7 +39,7 @@ /// @param {Color} $resting-shadow [null] - The shadow of the button in its idle state. /// @param {Color} $hover-shadow [null] - The shadow of the button in its hover state. /// @param {Color} $focus-shadow [null] - The shadow of the button in its focus state. -/// @param {Color} $active-shadow [null] - The shadow of the button in its focus state. +/// @param {Color} $active-shadow [null] - The shadow of the button in its active state. /// @param {Color} $disabled-background [null] - The disabled background color of the button. /// @param {Color} $disabled-foreground [null] - The disabled text color of the button. /// @param {Color} $disabled-icon-color [null] - The disabled icon color of the button. @@ -771,7 +771,7 @@ color: var-get($contained-theme, 'active-foreground'); background: var-get($contained-theme, 'active-background'); border-color: var-get($contained-theme, 'active-border-color'); - box-shadow: var-get($contained-theme, 'hover-shadow'); + box-shadow: var-get($contained-theme, 'active-shadow'); igx-icon { color: var-get($contained-theme, 'active-foreground'); @@ -911,7 +911,7 @@ color: var-get($fab-theme, 'active-foreground'); background: var-get($fab-theme, 'active-background'); border-color: var-get($fab-theme, 'active-border-color'); - box-shadow: var-get($fab-theme, 'focus-shadow'); + box-shadow: var-get($fab-theme, 'active-shadow'); igx-icon { color: var-get($fab-theme, 'active-foreground'); From a7e30cf9ba977484eb7b32ed976bb7eb4e736eb2 Mon Sep 17 00:00:00 2001 From: Silvia Ivanova <59446295+SisIvanova@users.noreply.github.com> Date: Wed, 11 Jun 2025 17:43:57 +0300 Subject: [PATCH 06/29] fix(combo): prefix/suffix directives not working (#15898) Co-authored-by: Simeon Simeonoff --- projects/igniteui-angular/src/lib/combo/combo.component.html | 4 ++-- .../src/lib/simple-combo/simple-combo.component.html | 4 ++-- src/app/input-group-showcase/input-group-showcase.sample.html | 2 ++ 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/projects/igniteui-angular/src/lib/combo/combo.component.html b/projects/igniteui-angular/src/lib/combo/combo.component.html index 03fd08b909f..e9603f47cb4 100644 --- a/projects/igniteui-angular/src/lib/combo/combo.component.html +++ b/projects/igniteui-angular/src/lib/combo/combo.component.html @@ -3,7 +3,7 @@ - + @@ -15,7 +15,7 @@ [attr.aria-labelledby]="ariaLabelledBy || label?.id || placeholder" (blur)="onBlur()" /> - + @if (displayValue) { - + @@ -21,7 +21,7 @@ (keyup)="handleKeyUp($event)" (keydown)="handleKeyDown($event)" (blur)="onBlur()" (paste)="handleInputChange($event)"/> - + @if (hasSelectedItem) { diff --git a/src/app/input-group-showcase/input-group-showcase.sample.html b/src/app/input-group-showcase/input-group-showcase.sample.html index d9e7a86b826..f3561b9729d 100644 --- a/src/app/input-group-showcase/input-group-showcase.sample.html +++ b/src/app/input-group-showcase/input-group-showcase.sample.html @@ -87,6 +87,8 @@

Angular

@if (getLabel()) { } + favorite + favorite Select a unique falsy value From c7a077a524691ccb542da773c55cc36286534bff Mon Sep 17 00:00:00 2001 From: Adrian Petrov <99720888+adrianptrv@users.noreply.github.com> Date: Thu, 12 Jun 2025 07:51:37 +0300 Subject: [PATCH 07/29] fix(combo): align case sensitive icon styling with WC (#15902) * fix(combo): align case sensitive icon styling with WC * fix(combo): remove !important --------- Co-authored-by: Simeon Simeonoff --- .../styles/components/combo/_combo-theme.scss | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/projects/igniteui-angular/src/lib/core/styles/components/combo/_combo-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/combo/_combo-theme.scss index 9b76e6ebbc4..58e551cb3c5 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/combo/_combo-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/combo/_combo-theme.scss @@ -165,18 +165,15 @@ %igx-combo__case-icon, %igx-combo__case-icon--active { line-height: 0; - - igx-icon { - --size: rem(18px); - } } // The wrapping element here is needed // in order to override the !important rule of .igx-icon--inactive. %igx-combo__case-icon { igx-icon { - // Important is needed since the .igx-icon--inactive has !important - color: color($color: 'gray', $variant: 600) !important; + --igx-icon-disabled-color: var(--ig-gray-600); + + opacity: 1; } } @@ -244,6 +241,13 @@ } } + @if $variant == 'fluent' or $variant == 'bootstrap' { + %igx-combo__search { + --igx-input-group-input-suffix-background: transparent; + --igx-input-group-input-suffix-background--focused: transparent; + } + } + .igx-input-group { %igx-combo__toggle-button { background: var-get($theme, 'toggle-button-background'); From c6199e50519f3721803fd09a50fa20d1412cec12 Mon Sep 17 00:00:00 2001 From: Marin Popov Date: Thu, 12 Jun 2025 11:02:43 +0300 Subject: [PATCH 08/29] fix(input-group): remove unused interim-bottom-line-color property (#15854) --- .../migrations/migration-collection.json | 5 +++ .../update-20_0_2/changes/theme-changes.json | 11 ++++++ .../migrations/update-20_0_2/index.spec.ts | 37 +++++++++++++++++++ .../migrations/update-20_0_2/index.ts | 14 +++++++ .../components/input/_input-group-theme.scss | 3 -- 5 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 projects/igniteui-angular/migrations/update-20_0_2/changes/theme-changes.json create mode 100644 projects/igniteui-angular/migrations/update-20_0_2/index.spec.ts create mode 100644 projects/igniteui-angular/migrations/update-20_0_2/index.ts diff --git a/projects/igniteui-angular/migrations/migration-collection.json b/projects/igniteui-angular/migrations/migration-collection.json index bc3bf8f3377..a151f709c6c 100644 --- a/projects/igniteui-angular/migrations/migration-collection.json +++ b/projects/igniteui-angular/migrations/migration-collection.json @@ -231,6 +231,11 @@ "version": "20.0.0", "description": "Updates Ignite UI for Angular from v19.2.0 to v20.0.0", "factory": "./update-20_0_0" + }, + "migration-47": { + "version": "20.0.2", + "description": "Updates Ignite UI for Angular from v20.0.0 to v20.0.2", + "factory": "./update-20_0_2" } } } diff --git a/projects/igniteui-angular/migrations/update-20_0_2/changes/theme-changes.json b/projects/igniteui-angular/migrations/update-20_0_2/changes/theme-changes.json new file mode 100644 index 00000000000..4d7be302ea8 --- /dev/null +++ b/projects/igniteui-angular/migrations/update-20_0_2/changes/theme-changes.json @@ -0,0 +1,11 @@ +{ + "$schema": "../../common/schema/theme-changes.schema.json", + "changes": [ + { + "name": "$interim-bottom-line-color", + "remove": true, + "owner": "input-group-theme", + "type": "property" + } + ] +} diff --git a/projects/igniteui-angular/migrations/update-20_0_2/index.spec.ts b/projects/igniteui-angular/migrations/update-20_0_2/index.spec.ts new file mode 100644 index 00000000000..c4429655a90 --- /dev/null +++ b/projects/igniteui-angular/migrations/update-20_0_2/index.spec.ts @@ -0,0 +1,37 @@ +import * as path from 'path'; + +import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing'; +import { setupTestTree } from '../common/setup.spec'; + +const version = '20.0.2'; + +describe(`Update to ${version}`, () => { + let appTree: UnitTestTree; + const schematicRunner = new SchematicTestRunner('ig-migrate', path.join(__dirname, '../migration-collection.json')); + + beforeEach(() => { + appTree = setupTestTree(); + }); + + const migrationName = 'migration-47'; + + it('should remove the $interim-bottom-line-color property from the input-group theme', async () => { + const testFilePath = `/testSrc/appPrefix/component/test.component.scss`; + + appTree.create( + testFilePath, + `$my-input-group-theme: input-group-theme( + $box-background: #ccc, + $interim-bottom-line-color: orange, + );` + ); + + const tree = await schematicRunner.runSchematic(migrationName, {}, appTree); + + expect(tree.readContent(testFilePath)).toEqual( + `$my-input-group-theme: input-group-theme( + $box-background: #ccc, + );` + ); + }); +}); diff --git a/projects/igniteui-angular/migrations/update-20_0_2/index.ts b/projects/igniteui-angular/migrations/update-20_0_2/index.ts new file mode 100644 index 00000000000..ea597b390a9 --- /dev/null +++ b/projects/igniteui-angular/migrations/update-20_0_2/index.ts @@ -0,0 +1,14 @@ +import type { + Rule, + SchematicContext, + Tree +} from '@angular-devkit/schematics'; +import { UpdateChanges } from '../common/UpdateChanges'; + +const version = '20.0.2'; + +export default (): Rule => async (host: Tree, context: SchematicContext) => { + context.logger.info(`Applying migration for Ignite UI for Angular to version ${version}`); + const update = new UpdateChanges(__dirname, host, context); + update.applyChanges(); +}; diff --git a/projects/igniteui-angular/src/lib/core/styles/components/input/_input-group-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/input/_input-group-theme.scss index e26faf1f8bc..7c301ffee81 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/input/_input-group-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/input/_input-group-theme.scss @@ -34,7 +34,6 @@ /// @param {Color} $idle-bottom-line-color [null] - The bottom line and border colors in the idle state. /// @param {Color} $hover-bottom-line-color [null] - The bottom line and border colors in the hover state. /// @param {Color} $focused-bottom-line-color [null] - The bottom line and border colors in the focused state. -/// @param {Color} $interim-bottom-line-color [null] - The bottom line and border colors during the to-focused transition. /// @param {Color} $disabled-bottom-line-color [null] - The bottom line and border colors in the disabled state. /// @param {Color} $border-color [null] - The border color for input groups of type border and fluent. /// @param {Color} $hover-border-color [null] - The hover input border for input groups of type border and fluent. @@ -86,7 +85,6 @@ $idle-bottom-line-color: null, $hover-bottom-line-color: null, $focused-bottom-line-color: null, - $interim-bottom-line-color: null, $disabled-bottom-line-color: null, $border-color: null, @@ -234,7 +232,6 @@ idle-bottom-line-color: $idle-bottom-line-color, hover-bottom-line-color: $hover-bottom-line-color, focused-bottom-line-color: $focused-bottom-line-color, - interim-bottom-line-color: $interim-bottom-line-color, disabled-bottom-line-color: $disabled-bottom-line-color, border-color: $border-color, hover-border-color: $hover-border-color, From 6156bceee174470fdb3fa66bbbaf68b79c6a491a Mon Sep 17 00:00:00 2001 From: Dilyana Yarabanova <45598235+didimmova@users.noreply.github.com> Date: Thu, 12 Jun 2025 14:20:02 +0300 Subject: [PATCH 09/29] feat(igx-vhelper): create and use css var for scrollbar size (#15918) --- .../lib/core/styles/components/_common/_igx-vhelper.scss | 1 + .../core/styles/components/drop-down/_drop-down-theme.scss | 4 ++++ .../igniteui-angular/src/lib/core/styles/themes/_core.scss | 6 ++++++ .../src/lib/directives/for-of/virtual.helper.component.ts | 6 ++++-- 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/projects/igniteui-angular/src/lib/core/styles/components/_common/_igx-vhelper.scss b/projects/igniteui-angular/src/lib/core/styles/components/_common/_igx-vhelper.scss index 74ec6b3b066..5c623bf1e34 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/_common/_igx-vhelper.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/_common/_igx-vhelper.scss @@ -12,6 +12,7 @@ position: absolute; top: 0; inset-inline-end: 0; + width: var(--vhelper-scrollbar-size); } %vhelper--horizontal { diff --git a/projects/igniteui-angular/src/lib/core/styles/components/drop-down/_drop-down-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/drop-down/_drop-down-theme.scss index f0cbccbc4a9..19b442dfdbe 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/drop-down/_drop-down-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/drop-down/_drop-down-theme.scss @@ -242,6 +242,10 @@ overflow-x: hidden; -webkit-overflow-scrolling: touch; position: relative; + + igx-display-container { + padding-inline-end: var(--vhelper-scrollbar-size); + } } %igx-drop-down__content { diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/_core.scss b/projects/igniteui-angular/src/lib/core/styles/themes/_core.scss index 5a8d5a8d420..7f13940af1f 100644 --- a/projects/igniteui-angular/src/lib/core/styles/themes/_core.scss +++ b/projects/igniteui-angular/src/lib/core/styles/themes/_core.scss @@ -124,6 +124,12 @@ inherits: true; } + @property --vhelper-scollbar-size { + syntax: ''; + initial-value: 16px; + inherits: true; + } + // Component styles @include ripple.component(); @include action-strip.component(); diff --git a/projects/igniteui-angular/src/lib/directives/for-of/virtual.helper.component.ts b/projects/igniteui-angular/src/lib/directives/for-of/virtual.helper.component.ts index 80bee29c7ab..e75b602c201 100644 --- a/projects/igniteui-angular/src/lib/directives/for-of/virtual.helper.component.ts +++ b/projects/igniteui-angular/src/lib/directives/for-of/virtual.helper.component.ts @@ -12,13 +12,11 @@ export class VirtualHelperComponent extends VirtualHelperBaseDirective implement @HostBinding('scrollTop') public scrollTop; - @HostBinding('style.width.px') public scrollWidth; @ViewChild('container', { read: ViewContainerRef, static: true }) public _vcr; @Input() public itemsLength: number; - @HostBinding('class') public cssClasses = 'igx-vhelper--vertical'; @@ -28,6 +26,10 @@ export class VirtualHelperComponent extends VirtualHelperBaseDirective implement public ngOnInit() { this.scrollWidth = this.scrollNativeSize; + this.document.documentElement.style.setProperty( + '--vhelper-scrollbar-size', + `${this.scrollNativeSize}px` + ); } protected override restoreScroll() { From 78585745786908e68e3cd3422e53385d361c8742 Mon Sep 17 00:00:00 2001 From: Dilyana Yarabanova <45598235+didimmova@users.noreply.github.com> Date: Thu, 12 Jun 2025 14:56:03 +0300 Subject: [PATCH 10/29] Improve Component Themes (#15729) --- CHANGELOG.md | 11 + .../src/app/wrapper/wrapper.component.ts | 3 +- .../action-strip/_action-strip-theme.scss | 9 +- .../components/avatar/_avatar-theme.scss | 15 +- .../styles/components/badge/_badge-theme.scss | 11 +- .../components/banner/_banner-theme.scss | 13 +- .../bottom-nav/_bottom-nav-theme.scss | 45 +- .../button-group/_button-group-theme.scss | 142 +++- .../components/button/_button-theme.scss | 371 ++++++----- .../button/_contained-button-theme.scss | 302 +++++++++ .../components/button/_fab-button-theme.scss | 296 +++++++++ .../components/button/_flat-button-theme.scss | 356 ++++++++++ .../button/_outlined-button-theme.scss | 419 ++++++++++++ .../components/calendar/_calendar-theme.scss | 614 ++++++++++++++---- .../styles/components/card/_card-theme.scss | 21 +- .../components/carousel/_carousel-theme.scss | 126 +++- .../checkbox/_checkbox-component.scss | 2 +- .../components/checkbox/_checkbox-theme.scss | 74 ++- .../styles/components/chip/_chip-theme.scss | 111 ++-- .../column-actions/_column-actions-theme.scss | 9 +- .../styles/components/combo/_combo-theme.scss | 50 +- .../components/dialog/_dialog-theme.scss | 21 +- .../components/divider/_divider-theme.scss | 7 +- .../drop-down/_drop-down-theme.scss | 80 ++- .../_expansion-panel-theme.scss | 31 +- .../grid-summary/_grid-summary-theme.scss | 25 +- .../grid-toolbar/_grid-toolbar-theme.scss | 19 +- .../styles/components/grid/_grid-theme.scss | 209 +++--- .../grid/_pivot-data-selector-theme.scss | 7 +- .../components/highlight/highlight-theme.scss | 5 +- .../_contained-icon-button-theme.scss | 196 ++++++ .../icon-button/_flat-icon-button-theme.scss | 188 ++++++ .../icon-button/_icon-button-theme.scss | 77 ++- .../_outlined-icon-button-theme.scss | 232 +++++++ .../styles/components/icon/_icon-theme.scss | 1 - .../components/input/_input-group-theme.scss | 290 ++++++++- .../styles/components/label/_label-theme.scss | 6 +- .../styles/components/list/_list-theme.scss | 108 ++- .../components/navbar/_navbar-theme.scss | 40 +- .../navdrawer/_navdrawer-theme.scss | 46 +- .../components/overlay/_overlay-theme.scss | 1 - .../paginator/_paginator-theme.scss | 9 +- .../progress/circular/_circular-theme.scss | 11 +- .../progress/linear/_linear-theme.scss | 7 +- .../query-builder/_query-builder-theme.scss | 39 +- .../styles/components/radio/_radio-theme.scss | 64 +- .../components/ripple/_ripple-theme.scss | 1 - .../components/scrollbar/scrollbar-theme.scss | 1 - .../components/select/_select-theme.scss | 42 +- .../components/slider/_slider-theme.scss | 99 ++- .../components/snackbar/_snackbar-theme.scss | 11 +- .../components/splitter/_splitter-theme.scss | 23 +- .../components/stepper/_stepper-theme.scss | 212 +++++- .../components/switch/_switch-theme.scss | 120 +++- .../styles/components/tabs/_tabs-theme.scss | 180 +++-- .../time-picker/_time-picker-theme.scss | 53 +- .../styles/components/toast/_toast-theme.scss | 19 +- .../components/tooltip/_tooltip-theme.scss | 9 +- .../styles/components/tree/_tree-theme.scss | 43 +- .../watermark/_watermark-theme.scss | 1 - .../core/styles/themes/generators/_base.scss | 204 ++++-- 61 files changed, 4656 insertions(+), 1081 deletions(-) create mode 100644 projects/igniteui-angular/src/lib/core/styles/components/button/_contained-button-theme.scss create mode 100644 projects/igniteui-angular/src/lib/core/styles/components/button/_fab-button-theme.scss create mode 100644 projects/igniteui-angular/src/lib/core/styles/components/button/_flat-button-theme.scss create mode 100644 projects/igniteui-angular/src/lib/core/styles/components/button/_outlined-button-theme.scss create mode 100644 projects/igniteui-angular/src/lib/core/styles/components/icon-button/_contained-icon-button-theme.scss create mode 100644 projects/igniteui-angular/src/lib/core/styles/components/icon-button/_flat-icon-button-theme.scss create mode 100644 projects/igniteui-angular/src/lib/core/styles/components/icon-button/_outlined-icon-button-theme.scss diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a5d8b720cf..6fe5277e2a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,17 @@ All notable changes for each version of this project will be documented in this file. +## 20.0.2 + +### New Features +- **Separating Button and Icon Button Themes** - The `button-theme` and `icon-button-theme` functions are still available, but for more targeted customization, you can now use the specific theme function for each button type. +- **Component Themes Enchancements** - Component themes have been improved to automatically calculate all necessary states (e.g., hover, focus, active) based on just a few key values. For example, customizing a contained button requires only a background color: +```scss + $custom-contained-button: contained-button-theme( + $background: #09f; + ); +``` + ## 20.0.0 ### General diff --git a/projects/igniteui-angular-elements/src/app/wrapper/wrapper.component.ts b/projects/igniteui-angular-elements/src/app/wrapper/wrapper.component.ts index e5557904ee6..bf6fbbc5c0e 100644 --- a/projects/igniteui-angular-elements/src/app/wrapper/wrapper.component.ts +++ b/projects/igniteui-angular-elements/src/app/wrapper/wrapper.component.ts @@ -16,7 +16,6 @@ export class TemplateWrapperComponent { public templateFunctions: TemplateFunction[] = []; public templateRendered = new Subject(); - private childParts: WeakMap = new WeakMap(); /** @@ -28,7 +27,7 @@ export class TemplateWrapperComponent { public templateRefs: QueryList>; constructor(private cdr: ChangeDetectorRef) { } - + protected litRender(container: HTMLElement, templateFunc: (arg: any) => TemplateResult, arg: any) { const part = render(templateFunc(arg), container); diff --git a/projects/igniteui-angular/src/lib/core/styles/components/action-strip/_action-strip-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/action-strip/_action-strip-theme.scss index 9a855fc8ae9..78d97b80462 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/action-strip/_action-strip-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/action-strip/_action-strip-theme.scss @@ -41,10 +41,9 @@ } $theme: digest-schema($action-strip-schema); - $meta: map.get($theme, '_meta'); @if not($icon-color) and $actions-background { - $icon-color: text-contrast($actions-background); + $icon-color: adaptive-contrast(var(--actions-background)); } @if not($actions-border-radius) { @@ -58,10 +57,6 @@ icon-color: $icon-color, delete-action: $delete-action, actions-border-radius: $actions-border-radius, - theme: map.get($schema, '_meta', 'theme'), - _meta: map.merge(if($meta, $meta, ()), ( - variant: map.get($schema, '_meta', 'theme') - )), )); } @@ -71,7 +66,7 @@ @mixin action-strip($theme) { @include css-vars($theme); - $variant: map.get($theme, '_meta', 'variant'); + $variant: map.get($theme, '_meta', 'theme'); $icon-button-size: map.get(( 'material': rem(36px), 'fluent': rem(32px), diff --git a/projects/igniteui-angular/src/lib/core/styles/components/avatar/_avatar-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/avatar/_avatar-theme.scss index 6c462663f50..06f9e037937 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/avatar/_avatar-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/avatar/_avatar-theme.scss @@ -41,10 +41,13 @@ } $theme: digest-schema($avatar-schema); - $meta: map.get($theme, '_meta'); @if not($color) and $background { - $color: text-contrast($background); + $color: adaptive-contrast(var(--background)); + } + + @if not($icon-color) and $background { + $icon-color: adaptive-contrast(var(--background)); } @return extend($theme, ( @@ -54,10 +57,6 @@ icon-color: $icon-color, border-radius: $border-radius, size: $size, - theme: map.get($schema, '_meta', 'theme'), - _meta: map.merge(if($meta, $meta, ()), ( - variant: map.get($schema, '_meta', 'theme') - )), )); } @@ -67,8 +66,8 @@ @mixin avatar($theme) { @include css-vars($theme); - $variant: map.get($theme, '_meta', 'variant'); - + $variant: map.get($theme, '_meta', 'theme'); + %igx-avatar-display { @include sizable(); diff --git a/projects/igniteui-angular/src/lib/core/styles/components/badge/_badge-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/badge/_badge-theme.scss index 97d3567c89f..305db2063f4 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/badge/_badge-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/badge/_badge-theme.scss @@ -48,14 +48,13 @@ } $theme: digest-schema($badge-schema); - $meta: map.get($theme, '_meta'); @if not($icon-color) and $background-color { - $icon-color: text-contrast($background-color); + $icon-color: adaptive-contrast(var(--background-color)); } @if not($text-color) and $background-color { - $text-color: text-contrast($background-color); + $text-color: adaptive-contrast(var(--background-color)); } @if not($shadow) { @@ -71,10 +70,6 @@ border-radius: $border-radius, background-color: $background-color, shadow: $shadow, - theme: map.get($schema, '_meta', 'theme'), - _meta: map.merge(if($meta, $meta, ()), ( - variant: map.get($schema, '_meta', 'theme'), - )), )); } @@ -84,7 +79,7 @@ @mixin badge($theme) { @include css-vars($theme); - $variant: map.get($theme, '_meta', 'variant'); + $variant: map.get($theme, '_meta', 'theme'); %igx-badge-display { --size: #{rem(22px)}; diff --git a/projects/igniteui-angular/src/lib/core/styles/components/banner/_banner-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/banner/_banner-theme.scss index 74a3166012a..dd52a4a12fc 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/banner/_banner-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/banner/_banner-theme.scss @@ -43,10 +43,13 @@ } $theme: digest-schema($banner-schema); - $meta: map.get($theme, '_meta'); @if not($banner-message-color) and $banner-background { - $banner-message-color: text-contrast($banner-background); + $banner-message-color: adaptive-contrast(var(--banner-background)); + } + + @if not($banner-illustration-color) and $banner-background { + $banner-illustration-color: adaptive-contrast(var(--banner-background)); } @return extend($theme, ( @@ -57,10 +60,6 @@ banner-border-color: $banner-border-color, banner-illustration-color: $banner-illustration-color, border-radius: $border-radius, - theme: map.get($schema, '_meta', 'theme'), - _meta: map.merge(if($meta, $meta, ()), ( - variant: map.get($schema, '_meta', 'theme') - )), )); } @@ -69,7 +68,7 @@ /// @param {Map} $theme - The theme used to style the component. @mixin banner($theme) { @include css-vars($theme); - $variant: map.get($theme, '_meta', 'variant'); + $variant: map.get($theme, '_meta', 'theme'); %igx-banner-host { igx-expansion-panel-body { diff --git a/projects/igniteui-angular/src/lib/core/styles/components/bottom-nav/_bottom-nav-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/bottom-nav/_bottom-nav-theme.scss index fdb0a893aea..87da896f8a7 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/bottom-nav/_bottom-nav-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/bottom-nav/_bottom-nav-theme.scss @@ -51,42 +51,36 @@ $theme: digest-schema($bottom-nav-schema); - $meta: map.get($theme, '_meta'); - - @if not($label-color) and $background { - @if meta.type-of($background) == 'color' { - $label-color: text-contrast($background); - } + @if not($label-color) and not($icon-color) and $background { + $label-color: adaptive-contrast(var(--background)); } @if not($icon-color) and $label-color { - @if meta.type-of($label-color) == 'color' { - $icon-color: $label-color; - } + $icon-color: $label-color; + } + + @if not($label-color) and $icon-color { + $label-color: $icon-color; + } + + @if not($icon-disabled-color) and not($label-disabled-color) and $label-color { + $label-disabled-color: adaptive-contrast(var(--background)); } @if not($icon-disabled-color) and $label-disabled-color { - @if meta.type-of($label-disabled-color) == 'color' { - $icon-disabled-color: $label-disabled-color; - } + $icon-disabled-color: $label-disabled-color; } @if not($label-disabled-color) and $icon-disabled-color { - @if meta.type-of($icon-disabled-color) == 'color' { - $label-disabled-color: $icon-disabled-color; - } + $label-disabled-color: $icon-disabled-color; } @if not($icon-selected-color) and $label-selected-color { - @if meta.type-of($background) == 'color' { - $icon-selected-color: $label-selected-color; - } + $icon-selected-color: $label-selected-color; } - @if not($icon-color) and $background { - @if meta.type-of($background) == 'color' { - $icon-color: text-contrast($background); - } + @if not($label-selected-color) and $icon-selected-color { + $label-selected-color: $icon-selected-color; } @if not($shadow) { @@ -105,11 +99,6 @@ label-disabled-color: $label-disabled-color, border-color: $border-color, shadow: $shadow, - theme: map.get($schema, '_meta', 'theme'), - _meta: map.merge(if($meta, $meta, ()), ( - variant: map.get($schema, '_meta', 'theme'), - theme-variant: map.get($schema, '_meta', 'variant') - )), )); } @@ -119,7 +108,7 @@ @mixin bottom-nav($theme) { @include css-vars($theme); - $variant: map.get($theme, '_meta', 'variant'); + $variant: map.get($theme, '_meta', 'theme'); $menu-height: rem(56px); $item-min-width: rem(80px); $item-max-width: rem(168px); diff --git a/projects/igniteui-angular/src/lib/core/styles/components/button-group/_button-group-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/button-group/_button-group-theme.scss index ff81ce04820..ccf7fb9d749 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/button-group/_button-group-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/button-group/_button-group-theme.scss @@ -120,44 +120,130 @@ } $theme: digest-schema($button-group-schema); - $meta: map.get($theme, '_meta'); $border: rem(1px) solid map.get($theme, 'item-selected-border-color'); + //background colors + @if not($item-hover-background) and $item-background { + $item-hover-background: hsl(from var(--item-background) h s calc(l * 0.9)); + } + + @if not($item-selected-background) and $item-background { + $item-selected-background: hsl(from var(--item-background) h s calc(l * 0.7)); + } + + @if not($item-selected-hover-background) and $item-selected-background { + $item-selected-hover-background: hsl(from var(--item-selected-background) h s calc(l * 1.1)); + } + + @if not($item-selected-focus-background) and $item-selected-background { + $item-selected-focus-background: var(--item-selected-background); + } + + @if not($item-selected-focus-hover-background) and $item-selected-hover-background { + $item-selected-focus-hover-background: var(--item-selected-hover-background); + } + + @if not($item-focused-background) and $item-background { + $item-focused-background: var(--item-hover-background); + } + + @if not($item-focused-hover-background) and $item-hover-background { + $item-focused-hover-background: hsl(from var(--item-focused-background) h s calc(l * 0.9)); + } + + @if not($disabled-background-color) and $item-background { + $disabled-background-color: var(--item-background); + } + + @if not($disabled-selected-background) and $item-selected-background { + $disabled-selected-background: rgba(gray, 0.3); + } + + //border colors + @if not($item-border-color) and $item-background { + $item-border-color: hsl(from var(--item-background) h s calc(l * 0.8)); + } + + @if not($item-hover-border-color) and $item-border-color { + $item-hover-border-color: var(--item-border-color); + } + + @if not($item-focused-border-color) and $item-border-color { + $item-focused-border-color: var(--item-border-color); + } + + @if not($item-selected-border-color) and $item-border-color { + $item-selected-border-color: var(--item-border-color); + } + + @if not($item-selected-hover-border-color) and $item-border-color { + $item-selected-hover-border-color: var(--item-border-color); + } + + @if not($item-disabled-border) and $item-border-color { + $item-disabled-border: var(--item-border-color); + } + + @if not($disabled-selected-border-color) and $item-border-color { + $disabled-selected-border-color: var(--item-border-color); + } + + //text and icon colors @if not($item-text-color) and $item-background { - @if meta.type-of($item-background) == 'color' { - $item-text-color: text-contrast($item-background); - } + $item-text-color: adaptive-contrast(var(--item-background)); } - @if not($item-hover-text-color) and $item-hover-background { - @if meta.type-of($item-hover-background) == 'color' { - $item-hover-text-color: text-contrast($item-hover-background); - } + @if not($item-icon-color) and $item-text-color { + $item-icon-color: var(--item-text-color); } - @if not($item-selected-background) and $item-background { - @if meta.type-of($item-background) == 'color' { - $item-selected-background: text-contrast($item-background); - } + @if not($item-hover-text-color) and $item-hover-background { + $item-hover-text-color: adaptive-contrast(var(--item-hover-background)); } - @if not($idle-shadow-color) and $selected-shadow-color { - @if meta.type-of($selected-shadow-color) == 'color' { - $idle-shadow-color: $selected-shadow-color; - } + @if not($item-hover-icon-color) and $item-hover-text-color { + $item-hover-icon-color: var(--item-hover-text-color); } - @if not($selected-shadow-color) and $idle-shadow-color { - @if meta.type-of($idle-shadow-color) == 'color' { - $selected-shadow-color: $idle-shadow-color; - } + @if not($item-focused-text-color) and $item-focused-background { + $item-focused-text-color: adaptive-contrast(var(--item-focused-background)); } @if not($item-selected-text-color) and $item-selected-background { - @if meta.type-of($item-selected-background) == 'color' { - $item-selected-text-color: text-contrast($item-selected-background); - } + $item-selected-text-color: adaptive-contrast(var(--item-selected-background)); + } + + @if not($item-selected-icon-color) and $item-selected-text-color { + $item-selected-icon-color: var(--item-selected-text-color); + } + + @if not($item-selected-hover-text-color) and $item-selected-hover-background { + $item-selected-hover-text-color: adaptive-contrast(var(--item-selected-hover-background)); + } + + @if not($item-selected-hover-icon-color) and $item-selected-hover-text-color { + $item-selected-hover-icon-color: var(--item-selected-hover-text-color); + } + + @if not($disabled-text-color) and $disabled-background-color { + $disabled-text-color: hsla(from adaptive-contrast(var(--disabled-background-color)) h s l / 0.4); + } + + @if not($disabled-selected-text-color) and $disabled-text-color { + $disabled-selected-text-color: var(--disabled-text-color); + } + + @if not($idle-shadow-color) and $item-background { + $idle-shadow-color: hsla(from var(--item-background) h s l / .5); + } + + @if not($idle-shadow-color) and $selected-shadow-color { + $idle-shadow-color: var(--selected-shadow-color); + } + + @if not($selected-shadow-color) and $idle-shadow-color { + $selected-shadow-color: var(--idle-shadow-color); } @if map.get($button-group-schema, 'elevation') > 0 { @@ -205,11 +291,7 @@ border: $border, shadow: $shadow, idle-shadow-color: $idle-shadow-color, - selected-shadow-color: $selected-shadow-color, - theme: map.get($schema, '_meta', 'theme'), - _meta: map.merge(if($meta, $meta, ()), ( - variant: map.get($schema, '_meta', 'theme') - )), + selected-shadow-color: $selected-shadow-color )); } @@ -223,7 +305,7 @@ $group-items-margin: rem(10px, 16px); $outline-btn-indent: rem(2px); - $variant: map.get($theme, '_meta', 'variant'); + $variant: map.get($theme, '_meta', 'theme'); $bootstrap-theme: $variant == 'bootstrap'; $indigo-theme: $variant == 'indigo'; $group-item-min-width: map.get(( @@ -445,6 +527,7 @@ @if $variant == 'bootstrap' { background: var-get($theme, 'item-background'); z-index: 1; + box-shadow: 0 0 0 rem(4px) var-get($theme, 'idle-shadow-color'); &:active { background: var-get($theme, 'item-hover-background'); @@ -691,6 +774,7 @@ color: var-get($theme, 'item-selected-text-color'); border-color: var-get($theme, 'item-selected-border-color'); background: var-get($theme, 'item-selected-background'); + box-shadow: 0 0 0 rem(4px) var-get($theme, 'selected-shadow-color'); igx-icon { color: var-get($theme, 'item-selected-icon-color'); diff --git a/projects/igniteui-angular/src/lib/core/styles/components/button/_button-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/button/_button-theme.scss index 93f0ba40041..e29b19afdf0 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/button/_button-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/button/_button-theme.scss @@ -1,9 +1,16 @@ @use 'sass:map'; @use 'sass:meta'; @use 'sass:color'; +@use 'sass:list'; +@use 'sass:string'; @use '../../base' as *; @use '../../themes/schemas' as *; +@forward './flat-button-theme'; +@forward './contained-button-theme'; +@forward './outlined-button-theme'; +@forward './fab-button-theme'; + //// /// @group themes /// @access public @@ -122,61 +129,39 @@ } @if not($foreground) and $background { - $foreground: text-contrast($background); + $foreground: adaptive-contrast(var(--background)); } - @if not($hover-background) and $background { - @if meta.type-of($background) == 'color' { - $hover-background: color.scale($background, $lightness: 5%); - } + @if not($icon-color) and $background { + $icon-color: adaptive-contrast(var(--background)); } @if not($hover-foreground) and $hover-background { - @if meta.type-of($hover-background) == 'color' { - $hover-foreground: text-contrast($hover-background); - } - } - - @if not($icon-color) and $background { - @if meta.type-of($background) == 'color' { - $icon-color: text-contrast($background); - } + $hover-foreground: adaptive-contrast(var(--hover-background)); } @if not($icon-color-hover) and $hover-foreground { - @if meta.type-of($hover-background) == 'color' { - $icon-color-hover: $hover-foreground; - } - } - - @if not($focus-background) and $background { - $focus-background: color.scale($background, $lightness: 5%); + $icon-color-hover: var(--hover-foreground); } @if not($focus-foreground) and $focus-background { - $focus-foreground: text-contrast($focus-background); - } - - @if not($focus-hover-background) and $background { - @if meta.type-of($background) == 'color' { - $focus-hover-background: color.scale($background, $lightness: 5%); - } + $focus-foreground: adaptive-contrast(var(--focus-background)); } @if not($focus-hover-foreground) and $focus-hover-background { - $focus-hover-foreground: text-contrast($focus-hover-background); + $focus-hover-foreground: adaptive-contrast(var(--focus-hover-background)); } @if not($focus-visible-background) and $focus-background { - $focus-visible-background: $focus-background; + $focus-visible-background: var(--focus-background); } - @if not($focus-visible-foreground) and $focus-foreground { - $focus-visible-foreground: $focus-foreground; + @if not($focus-visible-foreground) and $focus-visible-background { + $focus-visible-foreground: adaptive-contrast(var(--focus-visible-background)); } @if not($focus-visible-border-color) and $focus-border-color { - $focus-visible-border-color: $focus-border-color; + $focus-visible-border-color: var(--focus-border-color); } @if not($_resting-shadow) { @@ -242,7 +227,6 @@ disabled-icon-color: $disabled-icon-color, disabled-border-color: $disabled-border-color, size: $size, - theme: map.get($schema, '_meta', 'theme'), )) )); } @@ -256,28 +240,60 @@ /// @deprecated Use the `css-vars` mixin instead. /// @see {mixin} css-vars -/// @param {Map} $theme - The theme used to style the component. -@mixin button($theme) { +/// @param {Map} $flat [null] - The flat theme used to style the component. +/// @param {Map} $contained [null] - The contained theme used to style the component. +/// @param {Map} $outlined [null] - The outlined theme used to style the component. +/// @param {Map} $fab [null] - The fab theme used to style the component. +@mixin button($themes...) { $button-width: rem(88px); + $flat-theme: null; + $contained-theme: null; + $outlined-theme: null; + $fab-theme: null; + $variant: 'material'; + + $required: ('flat', 'contained', 'outlined', 'fab'); + $added: (); + $missing: (); + + @each $key, $theme in meta.keywords($themes) { + $type: map.get($theme, _meta, type); + + $added: list.append($added, $key); + + @if $type == 'flat' { + $flat-theme: $theme; + } @else if $type == 'contained' { + $contained-theme: $theme; + } @else if $type == 'outlined' { + $outlined-theme: $theme; + } @else if $type == 'fab' { + $fab-theme: $theme; + } - $variant: map.get($theme, variant); + $variant: map.get($theme, '_meta', 'theme'); + @include css-vars($theme); + } - $flat-theme: map.get(map.get($theme, 'themes'), 'flat'); - $outlined-theme: map.get(map.get($theme, 'themes'), 'outlined'); - $contained-theme: map.get(map.get($theme, 'themes'), 'contained'); - $fab-theme: map.get(map.get($theme, 'themes'), 'fab'); + @each $item in $required { + @if not(list.index($added, $item)) { + $missing: list.append($missing, '$#{$item}', $separator: comma); + } + } - @include css-vars($flat-theme); - @include css-vars($outlined-theme); - @include css-vars($contained-theme); - @include css-vars($fab-theme); + @if list.length($missing) != 0 { + @error meta.inspect(string.unquote("Missing theme properties:") #{$missing}); + } - $time: map.get(( - 'material': .1s, - 'fluent': .1s, - 'bootstrap': .15s, - 'indigo': .15s - ), $variant); + $time: map.get( + ( + 'material': 0.1s, + 'fluent': 0.1s, + 'bootstrap': 0.15s, + 'indigo': 0.15s, + ), + $variant + ); $button-transition: color $time ease-in-out, background-color $time ease-in-out, @@ -292,89 +308,101 @@ $button-padding-inline: ( comfortable: rem(16px, 16px), cosy: rem(12px, 16px), - compact: rem(8px, 16px) + compact: rem(8px, 16px), ); $button-padding-indigo-inline: ( comfortable: rem(24px, 16px), cosy: rem(16px, 16px), - compact: rem(10px, 16px) + compact: rem(10px, 16px), ); $button-padding-material-block: ( comfortable: rem(7px, 16px), cosy: rem(4px, 16px), - compact: rem(1px, 16px) + compact: rem(1px, 16px), ); $button-padding-fluent-block: ( comfortable: 0, cosy: 0, - compact: 0 + compact: 0, ); $button-padding-bootstrap-block: ( comfortable: rem(6px, 16px), cosy: rem(4px, 16px), - compact: rem(2px, 16px) + compact: rem(2px, 16px), ); $button-padding-indigo-block: ( comfortable: 0, cosy: 0, - compact: 0 + compact: 0, + ); + + $button-padding-inline: map.get( + ( + 'material': $button-padding-inline, + 'fluent': $button-padding-inline, + 'bootstrap': $button-padding-inline, + 'indigo': $button-padding-indigo-inline, + ), + $variant ); - $button-padding-inline: map.get(( - 'material': $button-padding-inline, - 'fluent': $button-padding-inline, - 'bootstrap': $button-padding-inline, - 'indigo': $button-padding-indigo-inline, - ), $variant); - - $button-padding-block: map.get(( - 'material': $button-padding-material-block, - 'fluent': $button-padding-fluent-block, - 'bootstrap': $button-padding-bootstrap-block, - 'indigo': $button-padding-indigo-block, - ), $variant); - - $outlined-button-padding-inline: map.get(( - 'material': $button-padding-inline, - 'fluent': $button-padding-inline, - 'bootstrap': $button-padding-inline, - 'indigo': $button-padding-indigo-inline, - ), $variant); - - $outlined-button-padding-block: map.get(( - 'material': $button-padding-material-block, - 'fluent': $button-padding-fluent-block, - 'bootstrap': $button-padding-bootstrap-block, - 'indigo': $button-padding-indigo-block - ), $variant); + $button-padding-block: map.get( + ( + 'material': $button-padding-material-block, + 'fluent': $button-padding-fluent-block, + 'bootstrap': $button-padding-bootstrap-block, + 'indigo': $button-padding-indigo-block, + ), + $variant + ); + + $outlined-button-padding-inline: map.get( + ( + 'material': $button-padding-inline, + 'fluent': $button-padding-inline, + 'bootstrap': $button-padding-inline, + 'indigo': $button-padding-indigo-inline, + ), + $variant + ); + + $outlined-button-padding-block: map.get( + ( + 'material': $button-padding-material-block, + 'fluent': $button-padding-fluent-block, + 'bootstrap': $button-padding-bootstrap-block, + 'indigo': $button-padding-indigo-block, + ), + $variant + ); $button-floating-padding-block: ( comfortable: rem(8px), cosy: rem(4px), - compact: 0 + compact: 0, ); $button-floating-padding-inline: ( comfortable: rem(14px), cosy: rem(10px), - compact: rem(6px) + compact: rem(6px), ); $button-floating-padding-indigo-inline: ( comfortable: rem(10px), cosy: rem(8px), - compact: rem(6px) + compact: rem(6px), ); $items-gap: ( comfortable: rem(12px), cosy: rem(8px), - compact: rem(4px) + compact: rem(4px), ); $items-gap-indigo-comfortable: rem(8px); @@ -382,73 +410,102 @@ $filtering-row-button-size: ( comfortable: rem(40px), cosy: rem(30px), - compact: rem(21px) + compact: rem(21px), ); - $icon-sizes: map.get(( - 'material': rem(18px), - 'fluent': rem(18px), - 'bootstrap': rem(18px), - 'indigo': rem(16px), - ), $variant); + $icon-sizes: map.get( + ( + 'material': rem(18px), + 'fluent': rem(18px), + 'bootstrap': rem(18px), + 'indigo': rem(16px), + ), + $variant + ); $icon-in-button-size: $icon-sizes; - $contained-shadow: map.get(( - 'material': var-get($contained-theme, 'resting-shadow'), - 'fluent': none, - 'bootstrap': none, - 'indigo': none - ), $variant); - - $contained-shadow--hover: map.get(( - 'material': var-get($contained-theme, 'hover-shadow'), - 'fluent': none, - 'bootstrap': none, - 'indigo': none - ), $variant); - - $contained-shadow--focus: map.get(( - 'material': var-get($contained-theme, 'focus-shadow'), - 'fluent': 0 0 0 rem(3px) var-get($contained-theme, 'shadow-color'), - 'bootstrap': 0 0 0 rem(4px) var-get($contained-theme, 'shadow-color'), - 'indigo': 0 0 0 rem(3px) var-get($contained-theme, 'shadow-color') - ), $variant); - - $contained-shadow--active: map.get(( - 'material': var-get($contained-theme, 'active-shadow'), - 'fluent': 0 0 0 rem(3px) var-get($contained-theme, 'shadow-color'), - 'bootstrap': 0 0 0 rem(4px) var-get($contained-theme, 'shadow-color'), - 'indigo': 0 0 0 rem(3px) var-get($contained-theme, 'shadow-color') - ), $variant); - - $fab-shadow: map.get(( - 'material': var-get($fab-theme, 'resting-shadow'), - 'fluent': none, - 'bootstrap': none, - 'indigo': none - ), $variant); - - $fab-shadow--hover: map.get(( - 'material': var-get($fab-theme, 'hover-shadow'), - 'fluent': none, - 'bootstrap': none, - 'indigo': none - ), $variant); - - $fab-shadow--focus: map.get(( - 'material': var-get($fab-theme, 'focus-shadow'), - 'fluent': 0 0 0 rem(3px) var-get($fab-theme, 'shadow-color'), - 'bootstrap': 0 0 0 rem(4px) var-get($fab-theme, 'shadow-color'), - 'indigo': 0 0 0 rem(3px) var-get($fab-theme, 'shadow-color') - ), $variant); - - $fab-shadow--active: map.get(( - 'material': var-get($fab-theme, 'active-shadow'), - 'fluent': 0 0 0 rem(3px) var-get($fab-theme, 'shadow-color'), - 'bootstrap': 0 0 0 rem(4px) var-get($fab-theme, 'shadow-color'), - 'indigo': 0 0 0 rem(3px) var-get($fab-theme, 'shadow-color') - ), $variant); + $contained-shadow: map.get( + ( + 'material': var-get($contained-theme, 'resting-shadow'), + 'fluent': none, + 'bootstrap': none, + 'indigo': none, + ), + $variant + ); + + $contained-shadow--hover: map.get( + ( + 'material': var-get($contained-theme, 'hover-shadow'), + 'fluent': none, + 'bootstrap': none, + 'indigo': none, + ), + $variant + ); + + $contained-shadow--focus: map.get( + ( + 'material': var-get($contained-theme, 'focus-shadow'), + 'fluent': 0 0 0 rem(3px) var-get($contained-theme, 'shadow-color'), + 'bootstrap': 0 0 0 rem(4px) + var-get($contained-theme, 'shadow-color'), + 'indigo': 0 0 0 rem(3px) var-get($contained-theme, 'shadow-color'), + ), + $variant + ); + + $contained-shadow--active: map.get( + ( + 'material': var-get($contained-theme, 'active-shadow'), + 'fluent': 0 0 0 rem(3px) var-get($contained-theme, 'shadow-color'), + 'bootstrap': 0 0 0 rem(4px) + var-get($contained-theme, 'shadow-color'), + 'indigo': 0 0 0 rem(3px) var-get($contained-theme, 'shadow-color'), + ), + $variant + ); + + $fab-shadow: map.get( + ( + 'material': var-get($fab-theme, 'resting-shadow'), + 'fluent': none, + 'bootstrap': none, + 'indigo': none, + ), + $variant + ); + + $fab-shadow--hover: map.get( + ( + 'material': var-get($fab-theme, 'hover-shadow'), + 'fluent': none, + 'bootstrap': none, + 'indigo': none, + ), + $variant + ); + + $fab-shadow--focus: map.get( + ( + 'material': var-get($fab-theme, 'focus-shadow'), + 'fluent': 0 0 0 rem(3px) var-get($fab-theme, 'shadow-color'), + 'bootstrap': 0 0 0 rem(4px) var-get($fab-theme, 'shadow-color'), + 'indigo': 0 0 0 rem(3px) var-get($fab-theme, 'shadow-color'), + ), + $variant + ); + + $fab-shadow--active: map.get( + ( + 'material': var-get($fab-theme, 'active-shadow'), + 'fluent': 0 0 0 rem(3px) var-get($fab-theme, 'shadow-color'), + 'bootstrap': 0 0 0 rem(4px) var-get($fab-theme, 'shadow-color'), + 'indigo': 0 0 0 rem(3px) var-get($fab-theme, 'shadow-color'), + ), + $variant + ); %fluent-border { &::after { @@ -514,10 +571,10 @@ igx-grid-filtering-row { @if $variant == 'bootstrap' { --filtering-row-button-size: #{sizable( - #{map.get($filtering-row-button-size, 'compact')}, - #{map.get($filtering-row-button-size, 'cosy')}, - #{map.get($filtering-row-button-size, 'comfortable')} - )}; + #{map.get($filtering-row-button-size, 'compact')}, + #{map.get($filtering-row-button-size, 'cosy')}, + #{map.get($filtering-row-button-size, 'comfortable')} + )}; %igx-button-display { min-height: var(--filtering-row-button-size); @@ -994,7 +1051,11 @@ /// Uses the 'button' category from the typographic scale. /// @group typography /// @param {String} $categories [(text: 'button')] - The category from the typographic scale used for type styles. -@mixin button-typography($categories: (text: 'button')) { +@mixin button-typography( + $categories: ( + text: 'button', + ) +) { $text: map.get($categories, 'text'); %igx-button-display { diff --git a/projects/igniteui-angular/src/lib/core/styles/components/button/_contained-button-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/button/_contained-button-theme.scss new file mode 100644 index 00000000000..53577249ca6 --- /dev/null +++ b/projects/igniteui-angular/src/lib/core/styles/components/button/_contained-button-theme.scss @@ -0,0 +1,302 @@ +@use 'sass:map'; +@use 'sass:meta'; +@use 'sass:color'; +@use 'sass:list'; +@use 'sass:string'; +@use '../../base' as *; +@use '../../themes/schemas' as *; + +//// +/// @group themes +/// @access public +/// @author Marin Popov +/// @author Simeon Simeonoff +//// + +/// If only background color is specified, text/icon color +/// will be assigned automatically to a contrasting color. +/// Does ___not___ apply for disabled state colors. +/// @param {Map} $schema [$light-material-schema] - The schema used as basis for styling the component. +/// @param {Color} $background [null] - The background color of the button. +/// @param {Color} $foreground [null] - The text color of the button. +/// @param {Color} $icon-color [null] - The icon color in the button. +/// @param {Color} $icon-color-hover [null] - The icon color in the button on hover. +/// @param {Color} $hover-background [null] - The hover background color of the button. +/// @param {Color} $hover-foreground [null] - The hover text color of the button. +/// @param {Color} $focus-background [null] - The focus background color of the button. +/// @param {Color} $focus-foreground [null] - The focus text color of the button. +/// @param {Color} $focus-hover-background [null] - The background color on focus hovered state of the button. +/// @param {Color} $focus-hover-foreground [null] - The text color on focus hovered state of the button. +/// @param {Color} $focus-visible-background [null] - The focus-visible background color of the button. +/// @param {Color} $focus-visible-foreground [null] - The focus-visible text color of the button. +/// @param {Color} $active-background [null] - The active background of the button. +/// @param {Color} $active-foreground [null] - The active text color of the button. +/// @param {List} $border-radius [null] - The border radius of the button. +/// @param {Color} $border-color [null] - The border color of the button. +/// @param {Color} $hover-border-color [null] - The hover border color of the button. +/// @param {Color} $focus-border-color [null] - The focus border color of the button. +/// @param {Color} $focus-visible-border-color [null] - The focus-visible border color of the button. +/// @param {Color} $active-border-color [null] - The active border color of the button. +/// @param {Color} $shadow-color [null] - The shadow color of the button. +/// @param {Color} $resting-shadow [null] - The shadow of the button in its idle state. +/// @param {Color} $hover-shadow [null] - The shadow of the button in its hover state. +/// @param {Color} $focus-shadow [null] - The shadow of the button in its focus state. +/// @param {Color} $active-shadow [null] - The shadow of the button in its focus state. +/// @param {Color} $disabled-background [null] - The disabled background color of the button. +/// @param {Color} $disabled-foreground [null] - The disabled text color of the button. +/// @param {Color} $disabled-icon-color [null] - The disabled icon color of the button. +/// @param {Color} $disabled-border-color [null] - The disabled border color of the button. +/// +/// @requires $light-material-schema +/// +/// @example scss Change the background and text colors in contained buttons +/// $my-button-theme: contained-button-theme( +/// $foreground: white, +/// $background: black +/// ); +/// // Pass the theme to the css-vars() mixin +/// @include css-vars($my-button-theme); +@function contained-button-theme( + $schema: $light-material-schema, + + $background: null, + $foreground: null, + + $hover-background: null, + $hover-foreground: null, + + $icon-color: $foreground, + $icon-color-hover: $hover-foreground, + + $focus-background: null, + $focus-foreground: null, + + $focus-hover-background: null, + $focus-hover-foreground: null, + + $focus-visible-background: null, + $focus-visible-foreground: null, + + $active-background: null, + $active-foreground: null, + + $border-radius: null, + $border-color: null, + $hover-border-color: null, + $focus-border-color: null, + $focus-visible-border-color: null, + $active-border-color: null, + + $shadow-color: null, + + $resting-shadow: null, + $hover-shadow: null, + $focus-shadow: null, + $active-shadow: null, + + $disabled-background: null, + $disabled-foreground: null, + $disabled-icon-color: $disabled-foreground, + $disabled-border-color: null, + $size: null +) { + $name: 'igx-contained-button'; + $button-schema: (); + + @if map.has-key($schema, 'button') { + $button-schema: map.get($schema, 'button'); + @if map.has-key($button-schema, 'contained') { + $button-schema: map.get($button-schema, 'contained'); + } @else { + $button-schema: $schema; + } + } + + $theme: digest-schema($button-schema); + $variant: map.get($schema, '_meta', 'theme'); + + @if not($hover-foreground) and $foreground { + $hover-foreground: var(--foreground); + } + + @if not($focus-foreground) and $foreground { + $focus-foreground: var(--foreground); + } + + @if not($focus-hover-foreground) and $foreground { + $focus-hover-foreground: var(--foreground); + } + + @if not($focus-visible-foreground) and $foreground { + $focus-visible-foreground: var(--foreground); + } + + @if not($active-foreground) and $foreground { + $active-foreground: var(--foreground); + } + + @if not($icon-color-hover) and $icon-color { + $icon-color-hover: var(--icon-color); + } + + @if not($foreground) and $background { + $foreground: adaptive-contrast(var(--background)); + } + + @if not($icon-color) and $background { + $icon-color: adaptive-contrast(var(--background)); + } + + @if $variant == 'indigo' { + @if not($hover-background) and $background { + $hover-background: hsl(from var(--background) h s calc(l * 1.08)); + } + } @else { + @if not($hover-background) and $background { + $hover-background: hsl(from var(--background) h s calc(l * 1.05)); + } + } + + @if $variant == 'indigo' { + @if not($focus-background) and $background { + $focus-background: var(--background); + } + } @else { + @if not($focus-background) and $background { + $focus-background: hsl(from var(--background) h s calc(l * 1.1)); + } + } + + @if not($hover-foreground) and $hover-background { + $hover-foreground: adaptive-contrast(var(--hover-background)); + } + + @if not($icon-color-hover) and $hover-background { + $icon-color-hover: adaptive-contrast(var(--hover-background)); + } + + @if not($focus-foreground) and $focus-background { + $focus-foreground: adaptive-contrast(var(--focus-background)); + } + + @if not($focus-hover-background) and $hover-background { + $focus-hover-background: var(--hover-background); + } + + @if not($focus-hover-foreground) and $focus-hover-background { + $focus-hover-foreground: adaptive-contrast(var(--focus-hover-background)); + } + + @if not($focus-visible-background) and $focus-background { + $focus-visible-background: var(--focus-background); + } + + @if not($focus-visible-foreground) and $focus-visible-background { + $focus-visible-foreground: adaptive-contrast(var(--focus-visible-background)); + } + + @if $variant == 'fluent' { + @if not($focus-visible-border-color) and $focus-visible-foreground { + $focus-visible-border-color: var(--focus-visible-foreground); + } + } + + @if $variant == 'fluent' or $variant == 'bootstrap' { + @if not($active-background) and $background { + $active-background: hsl(from var(--background) h s calc(l * 0.9)); + } + } @else if $variant == 'material' { + @if not($active-background) and $focus-background { + $active-background: var(--focus-background); + } + } @else { + @if not($active-background) and $hover-background { + $active-background: var(--hover-background); + } + } + + @if not($active-foreground) and $active-background { + $active-foreground: adaptive-contrast(var(--active-background)); + } + + @if $variant == 'bootstrap' or $variant == 'indigo' { + @if not($shadow-color) and $focus-visible-background { + $shadow-color: hsla( + from var(--focus-visible-background) h s l / 0.5 + ); + } + + @if not($disabled-background) and $background { + $disabled-background: hsla(from var(--background) h s l / 0.5); + } + + @if not($disabled-icon-color) and $disabled-foreground { + $disabled-icon-color: var(--disabled-foreground); + } + + @if not($disabled-foreground) and $disabled-background { + $disabled-foreground: hsla(from adaptive-contrast(var(--disabled-background)) h s l / 0.5); + } + + @if not($disabled-icon-color) and $disabled-background { + $disabled-icon-color: hsla(from adaptive-contrast(var(--disabled-background)) h s l / 0.5); + } + } + + @if not($resting-shadow) { + $resting-elevation: map.get($button-schema, 'resting-elevation'); + $resting-shadow: elevation($resting-elevation); + } + + @if not($hover-shadow) { + $hover-elevation: map.get($button-schema, 'hover-elevation'); + $hover-shadow: elevation($hover-elevation); + } + + @if not($focus-shadow) { + $focus-elevation: map.get($button-schema, 'focus-elevation'); + $focus-shadow: elevation($focus-elevation); + } + + @if not($active-shadow) { + $active-elevation: map.get($button-schema, 'active-elevation'); + $active-shadow: elevation($active-elevation); + } + + @return extend( + $theme, + ( + name: $name, + background: $background, + foreground: $foreground, + icon-color: $icon-color, + icon-color-hover: $icon-color-hover, + hover-background: $hover-background, + hover-foreground: $hover-foreground, + focus-background: $focus-background, + focus-foreground: $focus-foreground, + focus-hover-background: $focus-hover-background, + focus-hover-foreground: $focus-hover-foreground, + focus-visible-background: $focus-visible-background, + focus-visible-foreground: $focus-visible-foreground, + active-background: $active-background, + active-foreground: $active-foreground, + border-radius: $border-radius, + border-color: $border-color, + hover-border-color: $hover-border-color, + focus-border-color: $focus-border-color, + focus-visible-border-color: $focus-visible-border-color, + active-border-color: $active-border-color, + shadow-color: $shadow-color, + resting-shadow: $resting-shadow, + hover-shadow: $hover-shadow, + focus-shadow: $focus-shadow, + active-shadow: $active-shadow, + disabled-background: $disabled-background, + disabled-foreground: $disabled-foreground, + disabled-icon-color: $disabled-icon-color, + disabled-border-color: $disabled-border-color, + size: $size, + ) + ); +} diff --git a/projects/igniteui-angular/src/lib/core/styles/components/button/_fab-button-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/button/_fab-button-theme.scss new file mode 100644 index 00000000000..c42835c4037 --- /dev/null +++ b/projects/igniteui-angular/src/lib/core/styles/components/button/_fab-button-theme.scss @@ -0,0 +1,296 @@ +@use 'sass:map'; +@use 'sass:meta'; +@use 'sass:color'; +@use 'sass:list'; +@use 'sass:string'; +@use '../../base' as *; +@use '../../themes/schemas' as *; + +//// +/// @group themes +/// @access public +/// @author Marin Popov +/// @author Simeon Simeonoff +//// + +/// If only background color is specified, text/icon color +/// will be assigned automatically to a contrasting color. +/// Does ___not___ apply for disabled state colors. +/// @param {Map} $schema [$light-material-schema] - The schema used as basis for styling the component. +/// @param {Color} $background [null] - The background color of the button. +/// @param {Color} $foreground [null] - The text color of the button. +/// @param {Color} $icon-color [null] - The icon color in the button. +/// @param {Color} $icon-color-hover [null] - The icon color in the button on hover. +/// @param {Color} $hover-background [null] - The hover background color of the button. +/// @param {Color} $hover-foreground [null] - The hover text color of the button. +/// @param {Color} $focus-background [null] - The focus background color of the button. +/// @param {Color} $focus-foreground [null] - The focus text color of the button. +/// @param {Color} $focus-hover-background [null] - The background color on focus hovered state of the button. +/// @param {Color} $focus-hover-foreground [null] - The text color on focus hovered state of the button. +/// @param {Color} $focus-visible-background [null] - The focus-visible background color of the button. +/// @param {Color} $focus-visible-foreground [null] - The focus-visible text color of the button. +/// @param {Color} $active-background [null] - The active background of the button. +/// @param {Color} $active-foreground [null] - The active text color of the button. +/// @param {List} $border-radius [null] - The border radius of the button. +/// @param {Color} $border-color [null] - The border color of the button. +/// @param {Color} $hover-border-color [null] - The hover border color of the button. +/// @param {Color} $focus-border-color [null] - The focus border color of the button. +/// @param {Color} $focus-visible-border-color [null] - The focus-visible border color of the button. +/// @param {Color} $active-border-color [null] - The active border color of the button. +/// @param {Color} $shadow-color [null] - The shadow color of the button. +/// @param {Color} $resting-shadow [null] - The shadow of the button in its idle state. +/// @param {Color} $hover-shadow [null] - The shadow of the button in its hover state. +/// @param {Color} $focus-shadow [null] - The shadow of the button in its focus state. +/// @param {Color} $active-shadow [null] - The shadow of the button in its focus state. +/// @param {Color} $disabled-background [null] - The disabled background color of the button. +/// @param {Color} $disabled-foreground [null] - The disabled text color of the button. +/// @param {Color} $disabled-icon-color [null] - The disabled icon color of the button. +/// @param {Color} $disabled-border-color [null] - The disabled border color of the button. +/// +/// @requires $light-material-schema +/// +/// @example scss Change the background and text colors in fab buttons +/// $my-button-theme: fab-button-theme( +/// $foreground: white, +/// $background: black +/// ); +/// // Pass the theme to the css-vars() mixin +/// @include css-vars($my-button-theme); +@function fab-button-theme( + $schema: $light-material-schema, + + $background: null, + $foreground: null, + + $hover-background: null, + $hover-foreground: null, + + $icon-color: $foreground, + $icon-color-hover: $hover-foreground, + + $focus-background: null, + $focus-foreground: null, + + $focus-hover-background: null, + $focus-hover-foreground: null, + + $focus-visible-background: null, + $focus-visible-foreground: null, + + $active-background: null, + $active-foreground: null, + + $border-radius: null, + $border-color: null, + $hover-border-color: null, + $focus-border-color: null, + $focus-visible-border-color: null, + $active-border-color: null, + + $shadow-color: null, + + $resting-shadow: null, + $hover-shadow: null, + $focus-shadow: null, + $active-shadow: null, + + $disabled-background: null, + $disabled-foreground: null, + $disabled-icon-color: $disabled-foreground, + $disabled-border-color: null, + $size: null +) { + $name: 'igx-fab-button'; + $button-schema: (); + + @if map.has-key($schema, 'button') { + $button-schema: map.get($schema, 'button'); + @if map.has-key($button-schema, 'fab') { + $button-schema: map.get($button-schema, 'fab'); + } @else { + $button-schema: $schema; + } + } + + $theme: digest-schema($button-schema); + $variant: map.get($schema, '_meta', 'theme'); + + @if not($foreground) and $background { + $foreground: adaptive-contrast(var(--background)); + } + + @if not($icon-color) and $background { + $icon-color: adaptive-contrast(var(--background)); + } + + @if $variant == 'indigo' { + @if not($hover-background) and $background { + $hover-background: hsl(from var(--background) h s calc(l * 1.08)); + } + } @else { + @if not($hover-background) and $background { + $hover-background: hsl(from var(--background) h s calc(l * 1.05)); + } + } + + @if $variant == 'indigo' { + @if not($focus-background) and $background { + $focus-background: var(--background); + } + } @else { + @if not($focus-background) and $background { + $focus-background: hsl(from var(--background) h s calc(l * 1.1)); + } + } + + @if not($hover-foreground) and $hover-background { + $hover-foreground: if( + $foreground, + var(--foreground), + adaptive-contrast(var(--hover-background)) + ); + } + + @if not($icon-color-hover) and $hover-background { + $icon-color-hover: if( + $icon-color, + var(--icon-color), + adaptive-contrast(var(--hover-background)) + ); + } + + @if not($focus-foreground) and $focus-background { + $focus-foreground: if( + $foreground, + var(--foreground), + adaptive-contrast(var(--focus-background)) + ); + } + + @if not($focus-hover-background) and $hover-background { + $focus-hover-background: var(--hover-background); + } + + @if not($focus-hover-foreground) and $focus-hover-background { + $focus-hover-foreground: if( + $foreground, + var(--foreground), + adaptive-contrast(var(--focus-hover-background)) + ); + } + + @if not($focus-visible-background) and $focus-background { + $focus-visible-background: var(--focus-background); + } + + @if not($focus-visible-foreground) and $focus-visible-background { + $focus-visible-foreground: adaptive-contrast( + var(--focus-visible-background) + ); + } + + @if $variant == 'fluent' { + @if not($focus-visible-border-color) and $focus-visible-foreground { + $focus-visible-border-color: var(--focus-visible-foreground); + } + } + + @if $variant == 'fluent' or $variant == 'bootstrap' { + @if not($active-background) and $background { + $active-background: hsl(from var(--background) h s calc(l * 0.9)); + } + } @else if $variant == 'material' { + @if not($active-background) and $focus-background { + $active-background: var(--focus-background); + } + } @else { + @if not($active-background) and $hover-background { + $active-background: var(--hover-background); + } + } + + @if not($active-foreground) and $active-background { + $active-foreground: adaptive-contrast(var(--active-background)); + } + + @if $variant == 'bootstrap' or $variant == 'indigo' { + @if not($shadow-color) and $focus-visible-background { + $shadow-color: hsla( + from var(--focus-visible-background) h s l / 0.5 + ); + } + + @if not($disabled-background) and $background { + $disabled-background: hsla(from var(--background) h s l / 0.5); + } + + @if not($disabled-icon-color) and $disabled-foreground { + $disabled-icon-color: var(--disabled-foreground); + } + + @if not($disabled-foreground) and $disabled-background { + $disabled-foreground: hsla(from adaptive-contrast(var(--disabled-background)) h s l / 0.5); + } + + @if not($disabled-icon-color) and $disabled-background { + $disabled-icon-color: hsla(from adaptive-contrast(var(--disabled-background)) h s l / 0.5); + } + } + + @if not($resting-shadow) { + $resting-elevation: map.get($button-schema, 'resting-elevation'); + $resting-shadow: elevation($resting-elevation); + } + + @if not($hover-shadow) { + $hover-elevation: map.get($button-schema, 'hover-elevation'); + $hover-shadow: elevation($hover-elevation); + } + + @if not($focus-shadow) { + $focus-elevation: map.get($button-schema, 'focus-elevation'); + $focus-shadow: elevation($focus-elevation); + } + + @if not($active-shadow) { + $active-elevation: map.get($button-schema, 'active-elevation'); + $active-shadow: elevation($active-elevation); + } + + @return extend( + $theme, + ( + name: $name, + background: $background, + foreground: $foreground, + icon-color: $icon-color, + icon-color-hover: $icon-color-hover, + hover-background: $hover-background, + hover-foreground: $hover-foreground, + focus-background: $focus-background, + focus-foreground: $focus-foreground, + focus-hover-background: $focus-hover-background, + focus-hover-foreground: $focus-hover-foreground, + focus-visible-background: $focus-visible-background, + focus-visible-foreground: $focus-visible-foreground, + active-background: $active-background, + active-foreground: $active-foreground, + border-radius: $border-radius, + border-color: $border-color, + hover-border-color: $hover-border-color, + focus-border-color: $focus-border-color, + focus-visible-border-color: $focus-visible-border-color, + active-border-color: $active-border-color, + shadow-color: $shadow-color, + resting-shadow: $resting-shadow, + hover-shadow: $hover-shadow, + focus-shadow: $focus-shadow, + active-shadow: $active-shadow, + disabled-background: $disabled-background, + disabled-foreground: $disabled-foreground, + disabled-icon-color: $disabled-icon-color, + disabled-border-color: $disabled-border-color, + size: $size, + ) + ); +} diff --git a/projects/igniteui-angular/src/lib/core/styles/components/button/_flat-button-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/button/_flat-button-theme.scss new file mode 100644 index 00000000000..8a9a5c98779 --- /dev/null +++ b/projects/igniteui-angular/src/lib/core/styles/components/button/_flat-button-theme.scss @@ -0,0 +1,356 @@ +@use 'sass:map'; +@use 'sass:meta'; +@use 'sass:color'; +@use 'sass:list'; +@use 'sass:string'; +@use '../../base' as *; +@use '../../themes/schemas' as *; + +//// +/// @group themes +/// @access public +/// @author Marin Popov +/// @author Simeon Simeonoff +//// + +/// If only background color is specified, text/icon color +/// will be assigned automatically to a contrasting color. +/// Does ___not___ apply for disabled state colors. +/// @param {Map} $schema [$light-material-schema] - The schema used as basis for styling the component. +/// @param {Color} $background [null] - The background color of the button. +/// @param {Color} $foreground [null] - The text color of the button. +/// @param {Color} $icon-color [null] - The icon color in the button. +/// @param {Color} $icon-color-hover [null] - The icon color in the button on hover. +/// @param {Color} $hover-background [null] - The hover background color of the button. +/// @param {Color} $hover-foreground [null] - The hover text color of the button. +/// @param {Color} $focus-background [null] - The focus background color of the button. +/// @param {Color} $focus-foreground [null] - The focus text color of the button. +/// @param {Color} $focus-hover-background [null] - The background color on focus hovered state of the button. +/// @param {Color} $focus-hover-foreground [null] - The text color on focus hovered state of the button. +/// @param {Color} $focus-visible-background [null] - The focus-visible background color of the button. +/// @param {Color} $focus-visible-foreground [null] - The focus-visible text color of the button. +/// @param {Color} $active-background [null] - The active background of the button. +/// @param {Color} $active-foreground [null] - The active text color of the button. +/// @param {List} $border-radius [null] - The border radius of the button. +/// @param {Color} $border-color [null] - The border color of the button. +/// @param {Color} $hover-border-color [null] - The hover border color of the button. +/// @param {Color} $focus-border-color [null] - The focus border color of the button. +/// @param {Color} $focus-visible-border-color [null] - The focus-visible border color of the button. +/// @param {Color} $active-border-color [null] - The active border color of the button. +/// @param {Color} $shadow-color [null] - The shadow color of the button. +/// @param {Color} $resting-shadow [null] - The shadow of the button in its idle state. +/// @param {Color} $hover-shadow [null] - The shadow of the button in its hover state. +/// @param {Color} $focus-shadow [null] - The shadow of the button in its focus state. +/// @param {Color} $active-shadow [null] - The shadow of the button in its focus state. +/// @param {Color} $disabled-background [null] - The disabled background color of the button. +/// @param {Color} $disabled-foreground [null] - The disabled text color of the button. +/// @param {Color} $disabled-icon-color [null] - The disabled icon color of the button. +/// @param {Color} $disabled-border-color [null] - The disabled border color of the button. +/// +/// @requires $light-material-schema +/// +/// @example scss Change the text colors in flat buttons +/// $my-button-theme: flat-button-theme( +/// $foreground: black, +/// ); +/// // Pass the theme to the css-vars() mixin +/// @include css-vars($my-button-theme); +@function flat-button-theme( + $schema: $light-material-schema, + + $background: null, + $foreground: null, + + $hover-background: null, + $hover-foreground: null, + + $icon-color: $foreground, + $icon-color-hover: $hover-foreground, + + $focus-background: null, + $focus-foreground: null, + + $focus-hover-background: null, + $focus-hover-foreground: null, + + $focus-visible-background: null, + $focus-visible-foreground: null, + + $active-background: null, + $active-foreground: null, + + $border-radius: null, + $border-color: null, + $hover-border-color: null, + $focus-border-color: null, + $focus-visible-border-color: null, + $active-border-color: null, + + $shadow-color: null, + + $resting-shadow: null, + $hover-shadow: null, + $focus-shadow: null, + $active-shadow: null, + + $disabled-background: null, + $disabled-foreground: null, + $disabled-icon-color: $disabled-foreground, + $disabled-border-color: null, + $size: null +) { + $name: 'igx-flat-button'; + $button-schema: (); + + @if map.has-key($schema, 'button') { + $button-schema: map.get($schema, 'button'); + + @if map.has-key($button-schema, 'flat') { + $button-schema: map.get($button-schema, 'flat'); + } @else { + $button-schema: $schema; + } + } + + $theme: digest-schema($button-schema); + $variant: map.get($schema, '_meta', 'theme'); + + @if not($hover-foreground) and $hover-background { + $hover-foreground: adaptive-contrast(var(--hover-background)); + } + + @if not($icon-color-hover) and $hover-foreground { + $icon-color-hover: var(--hover-foreground); + } + + @if not($focus-foreground) and $focus-background { + $focus-foreground: adaptive-contrast(var(--focus-background)); + } + + @if not($focus-hover-foreground) and $focus-hover-background { + $focus-hover-foreground: adaptive-contrast(var(--focus-hover-background)); + } + + @if not($active-foreground) and $active-background { + $active-foreground: adaptive-contrast(var(--active-background)); + } + + @if not($focus-visible-background) and $focus-background { + $focus-visible-background: var(--focus-background); + } + + @if not($focus-visible-foreground) and $focus-visible-background { + $focus-visible-foreground: adaptive-contrast(var(--focus-visible-background)); + } + + @if not($focus-visible-border-color) and $focus-border-color { + $focus-visible-border-color: var(--focus-border-color); + } + + @if $variant == 'material' or $variant == 'fluent' { + @if not($hover-background) and $foreground { + $hover-background: hsla(from var(--foreground) h s l / 0.08); + } + + @if not($focus-background) and $foreground { + $focus-background: hsla(from var(--foreground) h s l / 0.32); + } + + @if not($focus-hover-background) and $foreground { + $focus-hover-background: hsla(from var(--foreground) h s l / 0.24); + } + + @if not($active-background) and $foreground { + $active-background: hsla(from var(--foreground) h s l / 0.16); + } + + @if not($hover-foreground) and $hover-background { + $hover-foreground: hsla(from var(--hover-background) h s l / 1); + } + + @if not($icon-color-hover) and $hover-foreground { + $icon-color-hover: var(--hover-foreground); + } + + @if not($focus-foreground) and $focus-background { + $focus-foreground: hsla(from var(--focus-background) h s l / 1); + } + + @if not($focus-hover-foreground) and $focus-hover-background { + $focus-hover-foreground: hsla( + from var(--focus-hover-background) h s l / 1 + ); + } + + @if not($active-foreground) and $active-background { + $active-foreground: hsla(from var(--active-background) h s l / 1); + } + + @if $variant == 'material' { + @if not($focus-visible-background) and $foreground { + $focus-visible-background: hsla( + from var(--foreground) h s l / 0.16 + ); + } + + @if not($focus-visible-foreground) and $focus-visible-background { + $focus-visible-foreground: hsla( + from var(--focus-visible-background) h s l / 1 + ); + } + } @else { + @if not($focus-visible-foreground) and $focus-foreground { + $focus-visible-foreground: var(--focus-foreground); + } + } + + @if $variant == 'fluent' { + @if not($focus-visible-border-color) and $focus-visible-foreground { + $focus-visible-border-color: var(--focus-visible-foreground); + } + } + } + + @if $variant == 'indigo' { + @if not($hover-background) and $foreground { + $hover-background: hsla(from var(--foreground) h s l / 0.08); + } + + @if not($focus-background) and $foreground { + $focus-background: hsla(from var(--foreground) h s l / 0.08); + } + + @if not($focus-hover-background) and $foreground { + $focus-hover-background: hsla(from var(--foreground) h s l / 0.08); + } + + @if not($active-background) and $foreground { + $active-background: hsla(from var(--foreground) h s l / 0.08); + } + } + + @if $variant == 'bootstrap' or $variant == 'indigo' { + @if not($hover-foreground) and $foreground { + $hover-foreground: hsl(from var(--foreground) h s calc(l * 0.9)); + } + + @if not($icon-color-hover) and $hover-foreground { + $icon-color-hover: var(--hover-foreground); + } + + @if $variant == 'bootstrap' { + @if not($focus-foreground) and $foreground { + $focus-foreground: hsl( + from var(--foreground) h s calc(l * 0.7) + ); + } + } @else { + @if not($focus-foreground) and $foreground { + $focus-foreground: hsl( + from var(--foreground) h s calc(l * 0.9) + ); + } + } + + @if not($focus-hover-foreground) and $foreground { + $focus-hover-foreground: hsl( + from var(--foreground) h s calc(l * 0.9) + ); + } + + @if not($focus-visible-foreground) and $foreground { + $focus-visible-foreground: var(--foreground); + } + + @if not($disabled-foreground) and $foreground { + $disabled-foreground: hsl(from (var(--foreground) h s l / 0.5)); + } + + @if not($disabled-icon-color) and $disabled-foreground { + $disabled-icon-color: var(--disabled-foreground); + } + + @if $variant == 'bootstrap' { + @if not($active-foreground) and $foreground { + $active-foreground: hsl( + from var(--foreground) h s calc(l * 0.7) + ); + } + + @if not($shadow-color) and $focus-visible-foreground { + $shadow-color: hsla( + from var(--focus-visible-foreground) h s l / 0.5 + ); + } + } @else { + @if not($active-foreground) and $foreground { + $active-foreground: hsl( + from var(--foreground) h s calc(l * 0.9) + ); + } + + @if not($shadow-color) and $focus-visible-foreground { + $shadow-color: hsla( + from var(--focus-visible-foreground) h s l / 0.2 + ); + } + } + } + + @if not($resting-shadow) { + $resting-elevation: map.get($button-schema, 'resting-elevation'); + $resting-shadow: elevation($resting-elevation); + } + + @if not($hover-shadow) { + $hover-elevation: map.get($button-schema, 'hover-elevation'); + $hover-shadow: elevation($hover-elevation); + } + + @if not($focus-shadow) { + $focus-elevation: map.get($button-schema, 'focus-elevation'); + $focus-shadow: elevation($focus-elevation); + } + + @if not($active-shadow) { + $active-elevation: map.get($button-schema, 'active-elevation'); + $active-shadow: elevation($active-elevation); + } + + @return extend( + $theme, + ( + name: $name, + background: $background, + foreground: $foreground, + icon-color: $icon-color, + icon-color-hover: $icon-color-hover, + hover-background: $hover-background, + hover-foreground: $hover-foreground, + focus-background: $focus-background, + focus-foreground: $focus-foreground, + focus-hover-background: $focus-hover-background, + focus-hover-foreground: $focus-hover-foreground, + focus-visible-background: $focus-visible-background, + focus-visible-foreground: $focus-visible-foreground, + active-background: $active-background, + active-foreground: $active-foreground, + border-radius: $border-radius, + border-color: $border-color, + hover-border-color: $hover-border-color, + focus-border-color: $focus-border-color, + focus-visible-border-color: $focus-visible-border-color, + active-border-color: $active-border-color, + shadow-color: $shadow-color, + resting-shadow: $resting-shadow, + hover-shadow: $hover-shadow, + focus-shadow: $focus-shadow, + active-shadow: $active-shadow, + disabled-background: $disabled-background, + disabled-foreground: $disabled-foreground, + disabled-icon-color: $disabled-icon-color, + disabled-border-color: $disabled-border-color, + size: $size, + ) + ); +} diff --git a/projects/igniteui-angular/src/lib/core/styles/components/button/_outlined-button-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/button/_outlined-button-theme.scss new file mode 100644 index 00000000000..895b516e89f --- /dev/null +++ b/projects/igniteui-angular/src/lib/core/styles/components/button/_outlined-button-theme.scss @@ -0,0 +1,419 @@ +@use 'sass:map'; +@use 'sass:meta'; +@use 'sass:color'; +@use 'sass:list'; +@use 'sass:string'; +@use '../../base' as *; +@use '../../themes/schemas' as *; + +//// +/// @group themes +/// @access public +/// @author Marin Popov +/// @author Simeon Simeonoff +//// + +/// If only background color is specified, text/icon color +/// will be assigned automatically to a contrasting color. +/// Does ___not___ apply for disabled state colors. +/// @param {Map} $schema [$light-material-schema] - The schema used as basis for styling the component. +/// @param {Color} $background [null] - The background color of the button. +/// @param {Color} $foreground [null] - The text color of the button. +/// @param {Color} $icon-color [null] - The icon color in the button. +/// @param {Color} $icon-color-hover [null] - The icon color in the button on hover. +/// @param {Color} $hover-background [null] - The hover background color of the button. +/// @param {Color} $hover-foreground [null] - The hover text color of the button. +/// @param {Color} $focus-background [null] - The focus background color of the button. +/// @param {Color} $focus-foreground [null] - The focus text color of the button. +/// @param {Color} $focus-hover-background [null] - The background color on focus hovered state of the button. +/// @param {Color} $focus-hover-foreground [null] - The text color on focus hovered state of the button. +/// @param {Color} $focus-visible-background [null] - The focus-visible background color of the button. +/// @param {Color} $focus-visible-foreground [null] - The focus-visible text color of the button. +/// @param {Color} $active-background [null] - The active background of the button. +/// @param {Color} $active-foreground [null] - The active text color of the button. +/// @param {List} $border-radius [null] - The border radius of the button. +/// @param {Color} $border-color [null] - The border color of the button. +/// @param {Color} $hover-border-color [null] - The hover border color of the button. +/// @param {Color} $focus-border-color [null] - The focus border color of the button. +/// @param {Color} $focus-visible-border-color [null] - The focus-visible border color of the button. +/// @param {Color} $active-border-color [null] - The active border color of the button. +/// @param {Color} $shadow-color [null] - The shadow color of the button. +/// @param {Color} $resting-shadow [null] - The shadow of the button in its idle state. +/// @param {Color} $hover-shadow [null] - The shadow of the button in its hover state. +/// @param {Color} $focus-shadow [null] - The shadow of the button in its focus state. +/// @param {Color} $active-shadow [null] - The shadow of the button in its focus state. +/// @param {Color} $disabled-background [null] - The disabled background color of the button. +/// @param {Color} $disabled-foreground [null] - The disabled text color of the button. +/// @param {Color} $disabled-icon-color [null] - The disabled icon color of the button. +/// @param {Color} $disabled-border-color [null] - The disabled border color of the button. +/// +/// @requires $light-material-schema +/// +/// @example scss Change the text colors in outlined buttons +/// $my-button-theme: outlined-button-theme( +/// $foreground: black, +/// ); +/// // Pass the theme to the css-vars() mixin +/// @include css-vars($my-button-theme); +@function outlined-button-theme( + $schema: $light-material-schema, + + $background: null, + $foreground: null, + + $hover-background: null, + $hover-foreground: null, + + $icon-color: $foreground, + $icon-color-hover: $hover-foreground, + + $focus-background: null, + $focus-foreground: null, + + $focus-hover-background: null, + $focus-hover-foreground: null, + + $focus-visible-background: null, + $focus-visible-foreground: null, + + $active-background: null, + $active-foreground: null, + + $border-radius: null, + $border-color: null, + $hover-border-color: null, + $focus-border-color: null, + $focus-visible-border-color: null, + $active-border-color: null, + + $shadow-color: null, + + $resting-shadow: null, + $hover-shadow: null, + $focus-shadow: null, + $active-shadow: null, + + $disabled-background: null, + $disabled-foreground: null, + $disabled-icon-color: $disabled-foreground, + $disabled-border-color: null, + $size: null +) { + $name: 'igx-outlined-button'; + $button-schema: (); + + @if map.has-key($schema, 'button') { + $button-schema: map.get($schema, 'button'); + @if map.has-key($button-schema, 'outlined') { + $button-schema: map.get($button-schema, 'outlined'); + } @else { + $button-schema: $schema; + } + } + + $theme: digest-schema($button-schema); + $variant: map.get($schema, '_meta', 'theme'); + + @if not($hover-foreground) and $hover-background { + $hover-foreground: adaptive-contrast(var(--hover-background)); + } + + @if not($icon-color-hover) and $hover-foreground { + $icon-color-hover: var(--hover-foreground); + } + + @if not($focus-foreground) and $focus-background { + $focus-foreground: adaptive-contrast(var(--focus-background)); + } + + @if not($focus-hover-foreground) and $focus-hover-background { + $focus-hover-foreground: adaptive-contrast(var(--focus-hover-background)); + } + + @if not($active-foreground) and $active-background { + $active-foreground: adaptive-contrast(var(--active-background)); + } + + @if not($focus-visible-background) and $focus-background { + $focus-visible-background: var(--focus-background); + } + + @if not($focus-visible-foreground) and $focus-visible-background { + $focus-visible-foreground: adaptive-contrast(var(--focus-visible-background)); + } + + @if not($focus-visible-border-color) and $focus-border-color { + $focus-visible-border-color: var(--focus-border-color); + } + + @if $variant == 'material' or $variant == 'fluent' { + @if not($hover-background) and $foreground { + $hover-background: hsla(from var(--foreground) h s l / 0.08); + } + + @if not($focus-background) and $foreground { + $focus-background: hsla(from var(--foreground) h s l / 0.32); + } + + @if not($focus-hover-background) and $foreground { + $focus-hover-background: hsla(from var(--foreground) h s l / 0.24); + } + + @if not($active-background) and $foreground { + $active-background: hsla(from var(--foreground) h s l / 0.16); + } + + @if not($hover-foreground) and $hover-background { + $hover-foreground: hsla(from var(--hover-background) h s l / 1); + } + + @if not($focus-foreground) and $focus-background { + $focus-foreground: hsla(from var(--focus-background) h s l / 1); + } + + @if not($focus-hover-foreground) and $focus-hover-background { + $focus-hover-foreground: hsla( + from var(--focus-hover-background) h s l / 1 + ); + } + + @if not($active-foreground) and $active-background { + $active-foreground: hsla(from var(--active-background) h s l / 1); + } + + @if $variant == 'material' { + @if not($focus-visible-background) and $foreground { + $focus-visible-background: hsla( + from var(--foreground) h s l / 0.16 + ); + } + + @if not($focus-visible-foreground) and $focus-visible-background { + $focus-visible-foreground: hsla( + from var(--focus-visible-background) h s l / 1 + ); + } + } @else { + @if not($focus-visible-foreground) and $focus-foreground { + $focus-visible-foreground: var(--focus-foreground); + } + } + + @if $variant == 'fluent' { + @if not($focus-visible-border-color) and $focus-visible-foreground { + $focus-visible-border-color: var(--focus-visible-foreground); + } + } + } + + @if $variant == 'indigo' { + @if not($hover-background) and $foreground { + $hover-background: hsla(from var(--foreground) h s l / 0.08); + } + + @if not($focus-background) and $foreground { + $focus-background: hsla(from var(--foreground) h s l / 0.08); + } + + @if not($focus-hover-background) and $foreground { + $focus-hover-background: hsla(from var(--foreground) h s l / 0.08); + } + + @if not($active-background) and $foreground { + $active-background: hsla(from var(--foreground) h s l / 0.08); + } + + @if not($hover-foreground) and $foreground { + $hover-foreground: hsl(from var(--foreground) h s calc(l * 0.9)); + } + + @if not($focus-foreground) and $foreground { + $focus-foreground: hsl(from var(--foreground) h s calc(l * 0.9)); + } + + @if not($focus-hover-foreground) and $foreground { + $focus-hover-foreground: hsl( + from var(--foreground) h s calc(l * 0.9) + ); + } + + @if not($focus-visible-foreground) and $foreground { + $focus-visible-foreground: var(--foreground); + } + + @if not($active-foreground) and $foreground { + $active-foreground: hsl(from var(--foreground) h s calc(l * 0.9)); + } + + @if not($shadow-color) and $focus-visible-foreground { + $shadow-color: hsla( + from var(--focus-visible-foreground) h s l / 0.2 + ); + } + } + + @if $variant == 'bootstrap' { + @if not($hover-background) and $foreground { + $hover-background: var(--foreground); + } + + @if not($hover-foreground) and $hover-background { + $hover-foreground: adaptive-contrast(var(--hover-background)); + } + + @if not($focus-background) and $foreground { + $focus-background: hsl(from var(--foreground) h s calc(l * 0.8)); + } + + @if not($focus-foreground) and $focus-background { + $focus-foreground: adaptive-contrast(var(--focus-background)); + } + + @if not($focus-hover-background) and $hover-background { + $focus-hover-background: hsl( + from var(--hover-background) h s calc(l * 0.9) + ); + } + + @if not($focus-hover-foreground) and $focus-hover-background { + $focus-hover-foreground: adaptive-contrast( + var(--focus-hover-background) + ); + } + + @if not($focus-visible-background) and $hover-background { + $focus-visible-background: var(--hover-background); + } + + @if not($focus-visible-foreground) and $focus-visible-background { + $focus-visible-foreground: adaptive-contrast( + var(--focus-visible-background) + ); + } + + @if not($active-background) and $foreground { + $active-background: hsl(from var(--foreground) h s calc(l * 0.8)); + } + + @if not($active-foreground) and $active-background { + $active-foreground: adaptive-contrast(var(--active-background)); + } + + @if not($disabled-foreground) and $foreground { + $disabled-foreground: hsl(from (var(--foreground) h s l / 0.5)); + } + + @if not($disabled-icon-color) and $disabled-foreground { + $disabled-icon-color: var(--disabled-foreground); + } + + @if not($disabled-border-color) and $disabled-foreground { + $disabled-border-color: var(--disabled-foreground); + } + + @if not($hover-border-color) and $hover-background { + $hover-border-color: var(--hover-background); + } + + @if not($focus-border-color) and $focus-background { + $focus-border-color: var(--focus-background); + } + + @if not($focus-visible-border-color) and $focus-visible-background { + $focus-visible-border-color: var(--focus-visible-background); + } + + @if not($active-border-color) and $active-background { + $active-border-color: var(--active-background); + } + + @if not($shadow-color) and $focus-visible-background { + $shadow-color: hsla( + from var(--focus-visible-background) h s l / 0.5 + ); + } + } + + @if not($icon-color-hover) and $hover-foreground { + $icon-color-hover: var(--hover-foreground); + } + + @if variant != 'bootstrap' { + @if not($border-color) and $foreground { + $border-color: var(--foreground); + } + + @if not($hover-border-color) and $hover-foreground { + $hover-border-color: var(--hover-foreground); + } + + @if not($focus-border-color) and $focus-foreground { + $focus-border-color: var(--focus-foreground); + } + + @if not($focus-visible-border-color) and $focus-visible-foreground { + $focus-visible-border-color: var(--focus-visible-foreground); + } + + @if not($active-border-color) and $active-foreground { + $active-border-color: var(--active-foreground); + } + } + + @if not($resting-shadow) { + $resting-elevation: map.get($button-schema, 'resting-elevation'); + $resting-shadow: elevation($resting-elevation); + } + + @if not($hover-shadow) { + $hover-elevation: map.get($button-schema, 'hover-elevation'); + $hover-shadow: elevation($hover-elevation); + } + + @if not($focus-shadow) { + $focus-elevation: map.get($button-schema, 'focus-elevation'); + $focus-shadow: elevation($focus-elevation); + } + + @if not($active-shadow) { + $active-elevation: map.get($button-schema, 'active-elevation'); + $active-shadow: elevation($active-elevation); + } + + @return extend( + $theme, + ( + name: $name, + background: $background, + foreground: $foreground, + icon-color: $icon-color, + icon-color-hover: $icon-color-hover, + hover-background: $hover-background, + hover-foreground: $hover-foreground, + focus-background: $focus-background, + focus-foreground: $focus-foreground, + focus-hover-background: $focus-hover-background, + focus-hover-foreground: $focus-hover-foreground, + focus-visible-background: $focus-visible-background, + focus-visible-foreground: $focus-visible-foreground, + active-background: $active-background, + active-foreground: $active-foreground, + border-radius: $border-radius, + border-color: $border-color, + hover-border-color: $hover-border-color, + focus-border-color: $focus-border-color, + focus-visible-border-color: $focus-visible-border-color, + active-border-color: $active-border-color, + shadow-color: $shadow-color, + resting-shadow: $resting-shadow, + hover-shadow: $hover-shadow, + focus-shadow: $focus-shadow, + active-shadow: $active-shadow, + disabled-background: $disabled-background, + disabled-foreground: $disabled-foreground, + disabled-icon-color: $disabled-icon-color, + disabled-border-color: $disabled-border-color, + size: $size, + ) + ); +} diff --git a/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss index cf254985f27..0e0ba2c8ca2 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss @@ -328,195 +328,589 @@ } $theme: digest-schema($calendar-schema); - $meta: map.get($theme, '_meta'); $variant: map.get($schema, '_meta', 'theme'); + //base start + @if not($header-foreground) and $header-background { + $header-foreground: adaptive-contrast(var(--header-background)); + } + + @if not($content-foreground) and $content-background { + $content-foreground: adaptive-contrast(var(--content-background)); + } + + @if not($weekend-color) and $content-foreground { + $weekend-color: var(--content-foreground); + } + + @if not($inactive-color) and $content-background { + $inactive-color: hsla(from adaptive-contrast(var(--content-background)) h s l / .5); + } + + @if not($weekday-color) and $inactive-color { + $weekday-color: var(--inactive-color); + } + + @if not($week-number-background) and $content-background { + $week-number-background: hsla(from var(--content-background) h s calc(l * 0.8)); + } + + @if not($week-number-foreground) and $week-number-background { + $week-number-foreground: hsla(from adaptive-contrast(var(--week-number-background)) h s l / 0.5); + } + //base end + + //picker start @if $variant == 'bootstrap' { @if not($picker-background) and $header-background { - @if meta.type-of($header-background) == 'color' { - $picker-background: $header-background; - } + $picker-background: var(--header-background); + } + + @if not($picker-hover-foreground) and $picker-background { + $picker-hover-foreground: hsla(from adaptive-contrast(var(--picker-background)) h s l / 0.8); + } + + @if not($weekday-color) and $header-background { + $weekday-color: hsla(from adaptive-contrast(var(--header-background)) h s l / 0.8); } } @else { @if not($picker-background) and $content-background { - @if meta.type-of($picker-background) == 'color' { - $picker-background: $content-background; - } + $picker-background: var(--content-background); } - @if not($weekday-color) and $content-background { - @if meta.type-of($content-background) == 'color' { - $weekday-color: text-contrast($content-background); - } + @if not($picker-hover-foreground) and $header-background { + $picker-hover-foreground: var(--header-background); } + } - @if not($navigation-color) and $content-background { - @if meta.type-of($content-background) == 'color' { - $navigation-color: text-contrast($content-background); - } + @if not($picker-foreground) and $picker-background { + $picker-foreground: adaptive-contrast(var(--picker-background)); + } + + @if not($picker-focus-foreground) and $picker-hover-foreground { + $picker-focus-foreground: var(--picker-hover-foreground); + } + + @if not($navigation-color) and $picker-background { + $navigation-color: adaptive-contrast(var(--picker-background)); + } + + @if not($navigation-hover-color) and $picker-hover-foreground { + $navigation-hover-color: var(--picker-hover-foreground); + } + + @if not($navigation-focus-color) and $navigation-hover-color { + $navigation-focus-color: var(--navigation-hover-color); + } + //picker end + + //date start + @if not($date-hover-background) and $content-background { + $date-hover-background: hsl(from var(--content-background) h s calc(l * 0.9)); + } + + @if not($date-hover-foreground) and $date-hover-background { + $date-hover-foreground: adaptive-contrast(var(--date-hover-background)); + } + + @if not($date-focus-background) and $date-hover-background { + $date-focus-background: var(--date-hover-background) + } + + @if not($date-focus-foreground) and $date-hover-foreground { + $date-focus-foreground: var(--date-hover-foreground); + } + + @if not($ym-hover-background) and $date-hover-background { + $ym-hover-background: var(--date-hover-background); + } + + @if not($ym-hover-foreground) and $ym-hover-background { + $ym-hover-foreground: adaptive-contrast(var(--ym-hover-background)); + } + //date end + + //date current start + @if $variant == 'indigo' { + @if not($date-current-background) and $header-background { + $date-current-background: hsla(from var(--header-background) h s l / 0.4); } - @if not($navigation-focus-color) and $navigation-hover-color { - @if meta.type-of($navigation-hover-color) == 'color' { - $navigation-focus-color: $navigation-hover-color; - } + @if not($date-current-border-color) and $date-current-background { + $date-current-border-color: hsla(from var(--date-current-background) h s l / 0.6); } - } - @if not($header-foreground) and $header-background { - @if meta.type-of($header-background) == 'color' { - $header-foreground: text-contrast($header-background); + @if not($date-current-hover-background) and $date-current-background { + $date-current-hover-background: hsl(from var(--date-current-background) h s calc(l * 0.9)); + } + + @if not($date-current-hover-border-color) and $date-current-border-color { + $date-current-hover-border-color: hsl(from var(--date-current-border-color) h s calc(l * 0.9)); + } + + @if not($date-current-focus-background) and $date-current-hover-background { + $date-current-focus-background: var(--date-current-hover-background); + } + + @if not($date-current-focus-border-color) and $date-current-hover-border-color { + $date-current-focus-border-color: var(--date-current-hover-border-color); + } + + @if not($date-current-foreground) and $date-current-background { + $date-current-foreground: adaptive-contrast(var(--date-current-background)); + } + + @if not($date-current-foreground) and $content-foreground { + $date-current-foreground: var(--content-foreground); + } + + @if not($date-current-hover-foreground) and $date-current-foreground { + $date-current-hover-foreground: var(--date-current-foreground); + } + + @if not($date-current-focus-foreground) and $date-current-foreground { + $date-current-focus-foreground: var(--date-current-foreground); } } - @if not($weekend-color) and $content-foreground { - @if meta.type-of($content-foreground) == 'color' { - $weekend-color: $content-foreground; + @if $variant == 'fluent' { + @if not($date-current-background) and $header-background { + $date-current-background: var(--header-background); } } - @if $variant != 'fluent' and $variant != 'bootstrap' { + @if $variant == 'material' or $variant == 'bootstrap' { @if not($date-current-background) and $content-background { - @if meta.type-of($content-background) == 'color' { - $date-current-background: $content-background; - } + $date-current-background: var(--content-background); + } + } + + @if $variant != 'indigo' { + @if not($date-current-foreground) and $date-current-background { + $date-current-foreground: adaptive-contrast(var(--date-current-background)); + } + + @if not($date-current-hover-background) and $date-hover-background { + $date-current-hover-background: var(--date-hover-background); } - @if not($date-current-foreground) and $content-background { - @if meta.type-of($content-background) == 'color' { - $date-current-foreground: text-contrast($content-background); + @if not($date-current-focus-background) and $date-focus-background { + $date-current-focus-background: var(--date-focus-background); + } + + @if $variant == 'fluent' { + @if not($date-current-hover-foreground) and $date-current-background { + $date-current-hover-foreground: adaptive-contrast(var(--date-current-background)); + } + + @if not($date-current-focus-foreground) and $date-current-background { + $date-current-focus-foreground: adaptive-contrast(var(--date-current-background)); } } - } - @if not($content-foreground) and $content-background { - @if meta.type-of($content-background) == 'color' { - $content-foreground: text-contrast($content-background); + @if not($date-current-hover-foreground) and $date-current-hover-background { + $date-current-hover-foreground: adaptive-contrast(var(--date-current-hover-background)); + } + + @if not($date-current-focus-foreground) and $date-current-hover-background { + $date-current-focus-foreground: adaptive-contrast(var(--date-current-hover-background)); } } - @if not($weekend-color) and $content-background { - @if meta.type-of($content-background) == 'color' { - $weekend-color: rgba($content-foreground, .5); + @if $variant == 'material' or $variant == 'bootstrap' { + @if not($date-current-border-color) and $date-current-foreground { + $date-current-border-color: var(--date-current-foreground); + } + + @if not($date-current-hover-border-color) and $date-current-hover-foreground { + $date-current-hover-border-color: var(--date-current-hover-foreground); + } + + @if not($date-current-focus-border-color) and $date-current-focus-foreground { + $date-current-focus-border-color: var(--date-current-focus-foreground); } } + //date current end + + //date selected start - @if not($picker-foreground) and $content-background { - @if meta.type-of($content-background) == 'color' { - $picker-foreground: text-contrast($content-background); + @if $variant == 'fluent' { + @if not($date-selected-background) and $date-hover-background { + $date-selected-background: var(--date-hover-background); + } + } @else { + @if not($date-selected-background) and $header-background { + $date-selected-background: var(--header-background); } } + @if not($date-selected-current-background) and $date-selected-background { + $date-selected-current-background: var(--date-selected-background); + } + + @if not($date-selected-hover-background) and $date-selected-background { + $date-selected-hover-background: hsl(from var(--date-selected-background) h s calc(l * 0.9)); + } + + @if not($date-selected-current-hover-background) and $date-selected-hover-background { + $date-selected-current-hover-background: var(--date-selected-hover-background); + } + + @if not($date-selected-focus-background) and $date-selected-hover-background { + $date-selected-focus-background: var(--date-selected-hover-background); + } + + @if not($date-selected-current-focus-background) and $date-selected-focus-background { + $date-selected-current-focus-background: var(--date-selected-focus-background); + } + @if not($date-selected-foreground) and $date-selected-background { - @if meta.type-of($date-selected-background) == 'color' { - $date-selected-foreground: text-contrast($date-selected-background); - } + $date-selected-foreground: adaptive-contrast(var(--date-selected-background)); } @if not($date-selected-hover-foreground) and $date-selected-background { - @if meta.type-of($date-selected-background) == 'color' { - $date-selected-hover-foreground: text-contrast($date-selected-background); - } + $date-selected-hover-foreground: adaptive-contrast(var(--date-selected-background)); } @if not($date-selected-focus-foreground) and $date-selected-background { - @if meta.type-of($date-selected-background) == 'color' { - $date-selected-focus-foreground: text-contrast($date-selected-background); - } + $date-selected-focus-foreground: adaptive-contrast(var(--date-selected-background)); } - @if not($date-selected-hover-foreground) and $date-selected-hover-background { - @if meta.type-of($date-selected-hover-background) == 'color' { - $date-selected-hover-foreground: text-contrast($date-selected-hover-background); + @if $variant == 'indigo' { + @if not($date-selected-current-border-color) and $date-selected-current-background { + $date-selected-current-border-color: hsl(from var(--date-selected-current-background) h calc(s * 0.9) calc(l * 1.5)); + } + } @else { + @if not($date-selected-current-border-color) and $content-foreground { + $date-selected-current-border-color: var(--content-foreground); } } - @if not($date-selected-focus-foreground) and $date-selected-focus-background { - @if meta.type-of($date-selected-focus-background) == 'color' { - $date-selected-focus-foreground: text-contrast($date-selected-focus-background); - } + @if not($date-selected-current-hover-background) and $date-selected-hover-background { + $date-selected-current-hover-background: var(--date-selected-hover-background); } - @if not($date-selected-current-foreground) and $date-selected-background { - @if meta.type-of($date-selected-background) == 'color' { - $date-selected-current-foreground: text-contrast($date-selected-background); - } + @if not($date-selected-current-hover-border-color) and $date-selected-current-border-color { + $date-selected-current-hover-border-color: var(--date-selected-current-border-color); } - @if not($date-selected-current-hover-foreground) and $date-selected-background { - @if meta.type-of($date-selected-background) == 'color' { - $date-selected-current-hover-foreground: text-contrast($date-selected-background); + @if $variant == 'fluent' { + @if not($date-selected-current-foreground) and $date-current-background { + $date-selected-current-foreground: adaptive-contrast(var(--date-current-background)); } - } - @if not($date-selected-current-focus-foreground) and $date-selected-background { - @if meta.type-of($date-selected-background) == 'color' { - $date-selected-current-focus-foreground: text-contrast($date-selected-background); + @if not($date-selected-current-hover-foreground) and $date-current-background { + $date-selected-current-hover-foreground: adaptive-contrast(var(--date-current-background)); } - } - @if not($date-selected-current-background) and $date-selected-background { - @if meta.type-of($date-selected-background) == 'color' { - $date-selected-current-background: $date-selected-background; + @if not($date-selected-current-focus-foreground) and $date-current-background { + $date-selected-current-focus-foreground: adaptive-contrast(var(--date-current-background)); + } + } @else { + @if not($date-selected-current-foreground) and $date-selected-background { + $date-selected-current-foreground: adaptive-contrast(var(--date-selected-background)); } - } - @if not($date-selected-current-hover-background) and $date-selected-background { - @if meta.type-of($date-selected-background) == 'color' { - $date-selected-current-hover-background: $date-selected-background; + @if not($date-selected-current-hover-foreground) and $date-selected-background { + $date-selected-current-hover-foreground: adaptive-contrast(var(--date-selected-background)); } - } - @if not($date-selected-current-focus-background) and $date-selected-background { - @if meta.type-of($date-selected-background) == 'color' { - $date-selected-current-focus-background: $date-selected-background; + @if not($date-selected-current-focus-foreground) and $date-selected-current-focus-background { + $date-selected-current-focus-foreground: adaptive-contrast(var(--date-selected-current-focus-background)); } } - @if not($date-selected-current-focus-background) and $date-selected-background { - @if meta.type-of($date-selected-background) == 'color' { - $date-selected-current-focus-background: $date-selected-background; - } + @if not($date-selected-current-focus-border-color) and $date-selected-current-hover-border-color { + $date-selected-current-focus-border-color: var(--date-selected-current-hover-border-color); } + //date selected end - @if not($date-selected-hover-background) and $date-selected-background { - @if meta.type-of($date-selected-background) == 'color' { - $date-selected-hover-background: $date-selected-background; + //date special start + @if $variant == 'fluent' or $variant == 'bootstrap' { + @if not($date-special-foreground) and $content-foreground { + $date-special-foreground: var(--content-foreground); } - } - @if not($date-selected-focus-background) and $date-selected-background { - @if meta.type-of($date-selected-background) == 'color' { - $date-selected-focus-background: $date-selected-background; + @if not($date-special-border-color) and $header-background { + $date-special-border-color: var(--header-background); + } + + @if not($date-special-hover-border-color) and $date-special-border-color { + $date-special-hover-border-color: var(--date-special-border-color); + } + + @if not($date-special-focus-foreground) and $date-special-foreground { + $date-special-focus-foreground: var(--date-special-foreground); + } + } @else { + @if not($date-special-foreground) and $header-background { + $date-special-foreground: var(--header-background); + } + + @if not($date-special-border-color) and $date-special-foreground { + $date-special-border-color: var(--date-special-foreground); + } + + @if not($date-special-hover-foreground) and $date-special-foreground { + $date-special-hover-foreground: hsl(from var(--date-special-foreground) h s calc(l * 0.8)); + } + + @if not($date-special-hover-border-color) and $date-special-hover-foreground { + $date-special-hover-border-color: var(--date-special-hover-foreground); + } + + @if not($date-special-focus-foreground) and $date-special-hover-border-color { + $date-special-focus-foreground: var(--date-special-hover-border-color); } } - @if not($date-selected-current-hover-background) and $date-selected-hover-background { - @if meta.type-of($date-selected-hover-background) == 'color' { - $date-selected-current-hover-background: $date-selected-hover-background; + @if not($date-special-hover-foreground) and $date-special-foreground { + $date-special-hover-foreground: hsl(from var(--date-special-foreground) h s calc(l * 0.8)); + } + + @if not($date-special-hover-background) and $date-hover-background { + $date-special-hover-background: var(--date-hover-background); + } + + @if not($date-special-focus-background) and $date-focus-background { + $date-special-focus-background: var(--date-focus-background); + } + + @if not($date-special-range-focus-background) and $date-special-focus-background { + $date-special-range-focus-background: var(--date-special-focus-background); + } + + @if $variant != 'fluent' { + @if not($date-selected-special-border-color) and $date-selected-foreground { + $date-selected-special-border-color: var(--date-selected-foreground); + } + + @if not($date-selected-special-hover-border-color) and $date-selected-hover-foreground { + $date-selected-special-hover-border-color: var(--date-selected-hover-foreground); + } + + @if not($date-selected-special-focus-border-color) and $date-selected-focus-foreground { + $date-selected-special-focus-border-color: var(--date-selected-focus-foreground); + } + } @else { + @if not($date-selected-special-border-color) and $date-special-border-color { + $date-selected-special-border-color: var(--date-special-border-color); + } + + @if not($date-selected-special-hover-border-color) and $date-selected-special-border-color { + $date-selected-special-hover-border-color: var(--date-selected-special-border-color); + } + + @if not($date-selected-special-focus-border-color) and $date-selected-special-border-color { + $date-selected-special-focus-border-color: var(--date-selected-special-border-color); } } + //date special end - @if not($date-selected-current-focus-background) and $date-selected-focus-background { - @if meta.type-of($date-selected-focus-background) == 'color' { - $date-selected-current-focus-background: $date-selected-focus-background; + //calendar views start + @if $variant != 'fluent' { + @if not($ym-selected-background) and $header-background { + $ym-selected-background: var(--header-background); + } + + @if not($ym-selected-hover-background) and $ym-selected-background { + $ym-selected-hover-background: hsl(from var(--ym-selected-background) h s calc(l * 0.9)); + } + + @if not($ym-current-background) and $date-current-background { + $ym-current-background: var(--date-current-background); + } + + @if not($ym-current-hover-background) and $date-current-hover-background { + $ym-current-hover-background: var(--date-current-hover-background); + } + + @if not($ym-current-outline-color) and $date-current-border-color { + $ym-current-outline-color: var(--date-current-border-color); + } + + @if not($ym-current-outline-hover-color) and $ym-current-outline-color { + $ym-current-outline-hover-color: var(--ym-current-outline-color); + } + + @if not($ym-current-outline-focus-color) and $ym-current-outline-hover-color { + $ym-current-outline-focus-color: var(--ym-current-outline-hover-color); + } + + @if not($ym-selected-current-outline-color) and $ym-current-outline-color { + $ym-selected-current-outline-color: var(--ym-current-outline-color); + } + + @if not($ym-selected-current-outline-hover-color) and $ym-current-outline-hover-color { + $ym-selected-current-outline-hover-color: var(--ym-current-outline-hover-color); + } + + @if not($ym-selected-current-outline-focus-color) and $ym-current-outline-focus-color { + $ym-selected-current-outline-focus-color: var(--ym-current-outline-focus-color); + } + } @else { + @if not($ym-selected-background) and $header-background { + $ym-selected-background: hsla(from var(--header-background) h s l / 0.3); + } + + @if not($ym-current-background) and $date-selected-background { + $ym-current-background: var(--date-selected-background); + } + + @if not($ym-current-hover-background) and $ym-current-background { + $ym-current-hover-background: hsl(from var(--ym-current-background) h s calc(l * 0.9)); + } + + @if not($ym-selected-hover-background) and $ym-selected-background { + $ym-selected-hover-background: hsla(from var(--ym-selected-background) h s calc(l * 0.9) / 0.5); + } + + @if not($ym-selected-current-outline-color) and $ym-selected-current-foreground { + $ym-selected-current-outline-color: var(--ym-selected-current-foreground); + } + + @if not($ym-selected-foreground) and $content-foreground { + $ym-selected-foreground: var(--content-foreground); + } + + @if not($ym-selected-hover-foreground) and $ym-selected-foreground { + $ym-selected-hover-foreground: var(--content-foreground); } } - @if not($ym-hover-foreground) and $ym-hover-background { - @if meta.type-of($ym-hover-background) == 'color' { - $ym-hover-foreground: text-contrast($ym-hover-background); + @if not($ym-selected-current-background) and $ym-selected-background { + $ym-selected-current-background: var(--ym-selected-background); + } + + @if not($ym-selected-current-hover-background) and $ym-selected-hover-background { + $ym-selected-current-hover-background: var(--ym-selected-hover-background); + } + + @if not($ym-current-foreground) and $ym-current-background { + $ym-current-foreground: adaptive-contrast(var(--ym-current-background)); + } + + @if not($ym-current-hover-foreground) and $ym-current-hover-background { + $ym-current-hover-foreground: adaptive-contrast(var(--ym-current-hover-background)); + } + + @if not($ym-selected-current-foreground) and $ym-selected-current-background { + $ym-selected-current-foreground: adaptive-contrast(var(--ym-selected-current-background)); + } + + @if not($ym-selected-current-hover-foreground) and $ym-selected-current-hover-background { + $ym-selected-current-hover-foreground: adaptive-contrast(var(--ym-selected-current-hover-background)); + } + //calendar views end + + //date range start + @if not($date-selected-range-foreground) and $content-foreground { + $date-selected-range-foreground: var(--content-foreground); + } + + @if $variant == 'fluent' { + @if not($date-selected-range-background) and $date-selected-background { + $date-selected-range-background: var(--date-selected-background); + } + + @if not($date-selected-current-range-background) and $date-selected-range-background { + $date-selected-current-range-background: var(--date-selected-range-background); + } + + @if not($date-selected-range-hover-background) and $date-selected-hover-background { + $date-selected-range-hover-background: var(--date-selected-hover-background); + } + + @if not($date-selected-range-focus-background) and $date-selected-hover-background { + $date-selected-range-focus-background: var(--date-selected-hover-background); + } + + @if not($date-selected-current-range-hover-foreground) and $date-current-background { + $date-selected-current-range-hover-foreground: adaptive-contrast(var(--date-current-background)); + } + + @if not($date-selected-current-range-focus-background) and $date-current-background { + $date-selected-current-range-focus-background: adaptive-contrast(var(--date-current-background)); + } + } @else { + @if not($date-selected-range-background) and $date-selected-background { + $date-selected-range-background: hsla(from var(--date-selected-background) h s l / 0.24); + } + + @if not($date-range-preview-border-color) and $date-selected-background { + $date-range-preview-border-color: var(--date-selected-background); } + + @if not($date-selected-current-range-hover-foreground) and $date-selected-current-range-hover-background { + $date-selected-current-range-hover-foreground: adaptive-contrast(var(--date-selected-current-range-hover-background)); + } + + @if not($date-selected-current-range-hover-foreground) and $content-foreground { + $date-selected-current-range-hover-foreground: var(--content-foreground); + } + + @if not($date-selected-current-range-focus-background) and $date-selected-current-range-hover-background { + $date-selected-current-range-focus-background: var(--date-selected-current-range-hover-background); + } + } + + @if not($date-selected-range-hover-background) and $date-hover-background { + $date-selected-range-hover-background: var(--date-hover-background); + } + + @if not($date-selected-range-focus-background) and $date-selected-range-hover-background { + $date-selected-range-focus-background: var(--date-selected-range-hover-background); + } + + @if not($date-selected-range-hover-foreground) and $date-selected-range-hover-background { + $date-selected-range-hover-foreground: adaptive-contrast(hsla(from var(--date-selected-range-hover-background) h s l / 1)); + } + + @if not($date-selected-range-focus-foreground) and $date-selected-range-focus-background { + $date-selected-range-focus-foreground: adaptive-contrast(hsla(from var(--date-selected-range-focus-background) h s l / 1)); } - @if not($ym-current-hover-foreground) and $ym-hover-background { - @if meta.type-of($ym-hover-background) == 'color' { - $ym-current-hover-foreground: text-contrast($ym-hover-background); + @if $variant == 'indigo' { + @if not($date-selected-current-range-background) and $date-selected-background { + $date-selected-current-range-background: hsla(from var(--date-selected-background) h s calc(l * 0.9) / 0.12); + } + + @if not($date-selected-current-range-hover-background) and $date-selected-background { + $date-selected-current-range-hover-background: hsla(from var(--date-selected-background) h s calc(l * 0.9) / 0.24); + } + + @if not($date-selected-current-range-foreground) and $date-current-background { + $date-selected-current-range-foreground: adaptive-contrast(var(--date-current-background)); + } + } @else { + @if not($date-selected-current-range-foreground) and $date-current-background { + $date-selected-current-range-foreground: adaptive-contrast(var(--date-current-background)); + } + + @if not($date-selected-current-range-foreground) and $content-foreground { + $date-selected-current-range-foreground: var(--content-foreground); } } - @if not($week-number-foreground) and $week-number-background { - $week-number-foreground: text-contrast($week-number-background); + @if not($date-special-range-foreground) and $date-special-foreground { + $date-special-range-foreground: hsl(from var(--date-special-foreground) h s calc(l * 0.8)); + } + + @if not($date-special-range-border-color) and $date-special-range-foreground { + $date-special-range-border-color: var(--date-special-range-foreground); + } + + @if not($date-special-range-hover-background) and $date-selected-range-hover-background { + $date-special-range-hover-background: var(--date-selected-range-hover-background); + } + //date range end + + @if not($date-disabled-foreground) and $content-background { + $date-disabled-foreground: hsla(from adaptive-contrast(var(--content-background)) h s l / .3); + } + + @if not($date-disabled-range-foreground) and $date-selected-range-background { + $date-disabled-range-foreground: hsla(from adaptive-contrast(var(--content-background)) h s l / .3); } @return extend($theme, ( @@ -658,10 +1052,6 @@ actions-divider-color: $actions-divider-color, size: $size, inner-size: $inner-size, - theme: map.get($schema, '_meta', 'theme'), - _meta: map.merge(if($meta, $meta, ()), ( - variant: map.get($schema, '_meta', 'theme') - )), )); } @@ -671,7 +1061,7 @@ @mixin calendar($theme) { @include css-vars($theme); - $variant: map.get($theme, '_meta', 'variant'); + $variant: map.get($theme, '_meta', 'theme'); $bootstrap-theme: $variant == 'bootstrap'; $cal-picker-padding: map.get(( diff --git a/projects/igniteui-angular/src/lib/core/styles/components/card/_card-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/card/_card-theme.scss index 91b849dd895..4955db6dbee 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/card/_card-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/card/_card-theme.scss @@ -52,28 +52,21 @@ } $theme: digest-schema($card-schema); - $meta: map.get($theme, '_meta'); @if not($header-text-color) and $background { - $header-text-color: text-contrast($background); + $header-text-color: adaptive-contrast(var(--background)); } @if not($actions-text-color) and $background { - @if meta.type-of($background) == 'color' { - $actions-text-color: rgba(text-contrast($background), .5); - } + $actions-text-color: adaptive-contrast(var(--background)); } @if not($content-text-color) and $background { - @if meta.type-of($background) == 'color' { - $content-text-color: rgba(text-contrast($background), .7); - } + $content-text-color: hsl(from adaptive-contrast(var(--background)) h s calc(l * 0.85)); } @if not($subtitle-text-color) and $background { - @if meta.type-of($background) == 'color' { - $subtitle-text-color: rgba(text-contrast($background), .7); - } + $subtitle-text-color: hsl(from adaptive-contrast(var(--background)) h s calc(l * 0.85)); } @if not($resting-shadow) { @@ -97,10 +90,6 @@ actions-text-color: $actions-text-color, resting-shadow: $resting-shadow, hover-shadow: $hover-shadow, - theme: map.get($schema, '_meta', 'theme'), - _meta: map.merge(if($meta, $meta, ()), ( - variant: map.get($schema, '_meta', 'theme') - )), )); } @@ -110,7 +99,7 @@ /// @param {Map} $theme - The theme used to style the component. @mixin card($theme) { @include css-vars($theme); - $variant: map.get($theme, '_meta', 'variant'); + $variant: map.get($theme, '_meta', 'theme'); $not-material-theme: $variant != 'material'; $card-heading-padding: rem(16px, 16px); diff --git a/projects/igniteui-angular/src/lib/core/styles/components/carousel/_carousel-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/carousel/_carousel-theme.scss index d90e486d0b9..d4515cf9683 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/carousel/_carousel-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/carousel/_carousel-theme.scss @@ -21,9 +21,13 @@ /// @param {Color} $button-disabled-arrow-color [null] - The previous/next buttons disabled arrow color. /// @param {Color} $button-border-color [null] - The previous/next buttons idle border color. /// @param {Color} $button-hover-border-color [null] - The previous/next buttons hover border color. +/// @param {Color} $button-focus-border-color [null] - The navigation buttons border color on focus. /// @param {Color} $button-disabled-border-color [null] - The previous/next buttons disabled border color. +/// @param {Color} $indicator-background [null] - The indicators container background color. +/// @param {Color} $label-indicator-background [null] - The label indicator container background color. /// @param {Color} $indicator-dot-color [null] - The idle indicator dot color. /// @param {Color} $indicator-hover-dot-color [null] - The hover indicator dot color. +/// @param {Color} $indicator-focus-color [null] - The indicators border and dot color on focus. /// @param {Color} $indicator-border-color [null] - The idle indicator border color. /// @param {Color} $indicator-active-dot-color [null] - The active indicator dot color. /// @param {Color} $indicator-active-border-color [null] - The active indicator border color. @@ -54,13 +58,18 @@ $button-disabled-background: null, $button-arrow-color: null, $button-hover-arrow-color: null, + $button-focus-arrow-color: null, $button-disabled-arrow-color: null, $button-border-color: null, $button-hover-border-color: null, + $button-focus-border-color: null, $button-disabled-border-color: null, + $indicator-background: null, + $label-indicator-background: null, $indicator-dot-color: null, $indicator-hover-dot-color: null, + $indicator-focus-color: null, $indicator-border-color: null, $indicator-active-dot-color: null, $indicator-active-border-color: null, @@ -76,7 +85,25 @@ } $theme: digest-schema($carousel-schema); - $meta: map.get($theme, '_meta'); + $variant: map.get($theme, '_meta', 'theme'); + + @if $variant == 'indigo' { + @if not($button-hover-background) and $button-background { + $button-hover-background: hsl(from var(--button-background) h s calc(l * 0.9)); + } + + @if not($button-border-color) and $button-background { + $button-border-color: hsl(from var(--button-background) h s calc(l * 0.9)); + } + + @if not($button-hover-border-color) and $button-border-color { + $button-hover-border-color: hsl(from var(--button-border-color) h s calc(l * 0.9)); + } + + @if not($indicator-active-dot-color) and not($indicator-background) and $button-background { + $indicator-active-dot-color: var(--button-background); + } + } @if not($button-shadow) { $button-elevation: map.get($carousel-schema, 'button-elevation'); @@ -84,16 +111,80 @@ } @if not($button-arrow-color) and $button-background { - $button-arrow-color: text-contrast($button-background); + $button-arrow-color: hsla(from (adaptive-contrast(var(--button-background)) h s l / 0.85)); + } + + @if not($button-hover-background) and $button-background { + $button-hover-background: var(--button-background); } @if not($button-hover-arrow-color) and $button-hover-background { - $button-hover-arrow-color: text-contrast($button-hover-background); + $button-hover-arrow-color: adaptive-contrast(var(--button-hover-background)); + } + + @if not($button-focus-arrow-color) and $button-hover-arrow-color { + $button-focus-arrow-color: var(--button-hover-arrow-color); + } + + @if not($button-disabled-background) and $button-background { + $button-disabled-background: var(--button-background); } @if not($button-disabled-arrow-color) and $button-disabled-background { - @if meta.type-of($button-disabled-background) == 'color' { - $button-disabled-arrow-color: rgba(text-contrast($button-disabled-background), .3); + $button-disabled-arrow-color: hsla(from adaptive-contrast(var(--button-disabled-background)) h s l / .4); + } + + @if not($indicator-dot-color) and $indicator-background { + $indicator-dot-color: hsla(from adaptive-contrast(var(--indicator-background)) h s l / .8); + } + + @if not($indicator-hover-dot-color) and $indicator-dot-color { + $indicator-hover-dot-color: hsla(from var(--indicator-dot-color) h s l / 1); + } + + @if not($indicator-border-color) and $indicator-dot-color { + $indicator-border-color: var(--indicator-dot-color); + } + + @if not($indicator-active-dot-color) and $indicator-background { + $indicator-active-dot-color: hsl(from adaptive-contrast(var(--indicator-background)) h s calc(l * 0.9)); + } + + @if not($indicator-active-hover-dot-color) and $indicator-active-dot-color { + $indicator-active-hover-dot-color: hsl(from var(--indicator-active-dot-color) h s calc(l * 1.1)); + } + + @if not($indicator-active-border-color) and $indicator-active-dot-color { + $indicator-active-border-color: var(--indicator-active-dot-color); + } + + @if $variant == 'material' { + @if not($button-focus-border-color) and $button-focus-arrow-color { + $button-focus-border-color: var(--button-focus-arrow-color); + } + } + + @if $variant == 'fluent' or $variant == 'bootstrap' { + @if not($button-focus-border-color) and $button-background { + $button-focus-border-color: hsla(from adaptive-contrast(var(--button-background)) h s l / 0.5); + } + } + + @if $variant == 'indigo' { + @if not($button-focus-border-color) and $indicator-active-dot-color { + $button-focus-border-color: var(--indicator-active-dot-color); + } + + @if not($indicator-focus-color) and $indicator-active-hover-dot-color { + $indicator-focus-color: hsla(from var(--indicator-active-hover-dot-color) h s l / .5); + } + } @else { + @if not($indicator-focus-color) and not($indicator-background) and $button-background { + $indicator-focus-color: var(--button-background); + } + + @if not($indicator-focus-color) and $indicator-background { + $indicator-focus-color: adaptive-contrast(var(--indicator-background)); } } @@ -110,21 +201,22 @@ button-hover-background: $button-hover-background, button-arrow-color: $button-arrow-color, button-hover-arrow-color: $button-hover-arrow-color, + button-focus-arrow-color: $button-focus-arrow-color, button-disabled-arrow-color: $button-disabled-arrow-color, button-border-color: $button-border-color, button-hover-border-color: $button-hover-border-color, + button-focus-border-color: $button-focus-border-color, button-disabled-border-color: $button-disabled-border-color, + indicator-background: $indicator-background, + label-indicator-background: $label-indicator-background, indicator-dot-color: $indicator-dot-color, indicator-hover-dot-color: $indicator-hover-dot-color, + indicator-focus-color: $indicator-focus-color, indicator-border-color: $indicator-border-color, indicator-active-dot-color: $indicator-active-dot-color, indicator-active-border-color: $indicator-active-border-color, indicator-active-hover-dot-color: $indicator-active-hover-dot-color, - theme: map.get($schema, '_meta', 'theme'), - _meta: map.merge(if($meta, $meta, ()), ( - variant: map.get($schema, '_meta', 'theme') - )), )); } @@ -139,7 +231,7 @@ $indicator-border-style: rem(2px) solid; $btn-indent: rem(3px); - $variant: map.get($theme, '_meta', 'variant'); + $variant: map.get($theme, '_meta', 'theme'); $not-bootstrap-theme: $variant != 'bootstrap'; %igx-carousel-display { @@ -206,25 +298,17 @@ border: rem(2px) solid var-get($theme, 'button-focus-border-color'); igx-icon { - color: var-get($theme, 'button-focus-border-color'); + color: var-get($theme, 'button-focus-arrow-color'); } @if $variant == 'bootstrap' { box-shadow: 0 0 0 rem(4px) var-get($theme, 'button-focus-border-color'); border-color: var-get($theme, 'button-border-color'); - - igx-icon { - color: var-get($theme, 'button-arrow-color'); - } } @if $variant == 'fluent' { border: none; - igx-icon { - color: var-get($theme, 'indicator-focus-color'); - } - &::after { position: absolute; content: ''; @@ -239,10 +323,6 @@ @if $variant == 'indigo' { box-shadow: 0 0 0 rem(3px) var-get($theme, 'indicator-focus-color'); - - igx-icon { - color: var-get($theme, 'button-arrow-color'); - } } } diff --git a/projects/igniteui-angular/src/lib/core/styles/components/checkbox/_checkbox-component.scss b/projects/igniteui-angular/src/lib/core/styles/components/checkbox/_checkbox-component.scss index ea5e85bc339..5c0def5856a 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/checkbox/_checkbox-component.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/checkbox/_checkbox-component.scss @@ -163,7 +163,7 @@ @extend %igx-checkbox--focused-bootstrap !optional; &:hover { - @extend %igx-checkbox--focused-hovered !optional; + @extend %igx-checkbox--focused-hovered-bootstrap !optional; } } diff --git a/projects/igniteui-angular/src/lib/core/styles/components/checkbox/_checkbox-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/checkbox/_checkbox-theme.scss index 4f8f632a66e..48ed1cffa0e 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/checkbox/_checkbox-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/checkbox/_checkbox-theme.scss @@ -29,8 +29,11 @@ /// @param {List} $border-radius [null] - The border radius used for checkbox component. /// @param {List} $border-radius-ripple [null] - The border radius used for checkbox ripple. /// @param {Color} $focus-outline-color [null] - The focus outlined color. +/// @param {Color} $focus-outline-color-focused [null] - The focus outlined color for focused state. +/// @param {Color} $focus-border-color [null] - The focus border color. /// @param {Color} $error-color [null] - The border and fill colors in invalid state. /// @param {Color} $error-color-hover [null] - The border and fill colors in invalid state on hover. +/// @param {Color} $focus-outline-color-error [null] - The focus outline error color. /// Set to light when the surrounding area is dark. /// /// @requires $light-material-schema @@ -58,8 +61,11 @@ $disabled-color-label: null, $border-radius-ripple: null, $focus-outline-color: null, + $focus-outline-color-focused: null, + $focus-border-color: null, $error-color: null, $error-color-hover: null, + $focus-outline-color-error: null, ) { $name: 'igx-checkbox'; $checkbox-schema: (); @@ -71,7 +77,55 @@ } $theme: digest-schema($checkbox-schema); - $meta: map.get($theme, '_meta'); + $variant: map.get($theme, '_meta', 'theme'); + + @if not($empty-color-hover) and $empty-color { + $empty-color-hover: hsl(from var(--empty-color) h s calc(l * 0.9)); + } + + @if not($fill-color-hover) and $fill-color { + $fill-color-hover: hsl(from var(--fill-color) h s calc(l * 0.9)); + } + + @if not($tick-color) and $fill-color { + $tick-color: adaptive-contrast(var(--fill-color)); + } + + @if not($label-color-hover) and $label-color { + $label-color-hover: hsl(from var(--label-color) h s calc(l * 0.9)); + } + + @if not($focus-border-color) and $fill-color { + $focus-border-color: var(--fill-color); + } + + @if not($disabled-indeterminate-color) and $fill-color { + $disabled-indeterminate-color: hsla(from var(--fill-color) h s l / 0.5); + } + + @if not($error-color-hover) and $error-color { + $error-color-hover: hsl(from var(--error-color) h s calc(l * 0.9)); + } + + @if not($focus-outline-color-error) and $error-color { + $focus-outline-color-error: hsla(from var(--error-color) h s l / .5); + } + + @if $variant == 'bootstrap' { + @if not($focus-outline-color) and $fill-color { + $focus-outline-color: hsla(from var(--fill-color) h s l / .5); + } + } + + @if $variant == 'indigo' { + @if not($focus-outline-color) and $empty-color { + $focus-outline-color: hsla(from var(--empty-color) h s l / .5); + } + + @if not($focus-outline-color-focused) and $fill-color { + $focus-outline-color-focused: hsla(from var(--fill-color) h s l / .5); + } + } @return extend($theme, ( name: $name, @@ -91,13 +145,11 @@ border-radius: $border-radius, border-radius-ripple: $border-radius-ripple, focus-outline-color: $focus-outline-color, + focus-outline-color-focused: $focus-outline-color-focused, + focus-border-color: $focus-border-color, error-color: $error-color, error-color-hover: $error-color-hover, - theme: map.get($schema, '_meta', 'theme'), - _meta: map.merge(if($meta, $meta, ()), ( - variant: map.get($schema, '_meta', 'theme'), - theme-variant: map.get($schema, '_meta', 'variant') - )), + focus-outline-color-error: $focus-outline-color-error )); } @@ -106,8 +158,8 @@ /// @param {Map} $theme - The theme used to style the component. @mixin checkbox($theme) { @include css-vars($theme); - $theme-variant: map.get($theme, '_meta', 'theme-variant'); - $variant: map.get($theme, '_meta', 'variant'); + $theme-variant: map.get($theme, '_meta', 'variant'); + $variant: map.get($theme, '_meta', 'theme'); $material-theme: $variant == 'material'; $bootstrap-theme: $variant == 'bootstrap'; @@ -591,14 +643,14 @@ %igx-checkbox--focused-bootstrap { %cbx-composite { border-radius: var-get($theme, 'border-radius'); - border-color: color($color: 'primary', $variant: 200); + border-color: var-get($theme, 'focus-border-color'); box-shadow: 0 0 0 rem(4px) var-get($theme, 'focus-outline-color'); } } - %igx-checkbox--focused-hovered { + %igx-checkbox--focused-hovered-bootstrap { %cbx-composite { - border-color: color($color: 'primary', $variant: 300); + border-color: hsl(from var-get($theme, 'focus-border-color') h calc(s * 1.12) calc(l * 0.82)); } } diff --git a/projects/igniteui-angular/src/lib/core/styles/components/chip/_chip-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/chip/_chip-theme.scss index 45b929e1bda..4b5371c8cc6 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/chip/_chip-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/chip/_chip-theme.scss @@ -106,94 +106,116 @@ } $theme: digest-schema($chip-schema); - $meta: map.get($theme, '_meta'); + $variant: map.get($theme, '_meta', 'theme'); @if not($text-color) and $background { - $text-color: text-contrast($background); + $text-color: adaptive-contrast(var(--background)); } - @if not($hover-background) and $background { - $luminance: luminance($background); + @if not($border-color) and $background { + $border-color: var(--background); + } - @if meta.type-of($luminance) == 'color' and $luminance + .05 < .5 { - $hover-background: color.scale($background, $lightness: 14%); - } @else { - $hover-background: color.scale($background, $lightness: -4%); - } + @if not($hover-background) and $background { + $hover-background: hsl(from var(--background) h s calc(l * 0.9)); } @if not($hover-text-color) and $hover-background { - $hover-text-color: text-contrast(to-opaque($hover-background)); + $hover-text-color: adaptive-contrast(var(--hover-background)); } @if not($focus-background) and $background { - $luminance: luminance($background); + $focus-background: hsl(from var(--background) h s calc(l * 0.8)); + } - @if meta.type-of($luminance) == 'color' and $luminance + .05 < .5 { - $focus-background: color.scale($background, $lightness: 22%); - } @else { - $focus-background: color.scale($background, $lightness: -8%); + @if $variant == 'fluent' { + @if not($focus-background) and $selected-background { + $focus-background: var(--selected-background); } } @if not($focus-text-color) and $focus-background { - $focus-text-color: text-contrast(to-opaque($focus-background)); + $focus-text-color: adaptive-contrast(var(--focus-background)); } - @if not($selected-background) and $background { - $luminance: luminance($background); - - @if meta.type-of($luminance) == 'color' and $luminance + .05 < .5 { - $selected-background: color.scale($background, $lightness: 22%); - } @else { - $selected-background: color.scale($background, $lightness: -8%); + @if $variant != 'indigo' and $variant != 'fluent' { + @if not($selected-background) and $background { + $selected-background: var(--background); + } + } @else { + @if not($selected-background) and $background { + $selected-background: hsl(from var(--background) h s calc(l * 1.1)); } } @if not($selected-text-color) and $selected-background { - $selected-text-color: text-contrast(to-opaque($selected-background)); + $selected-text-color: adaptive-contrast(var(--selected-background)); } - @if not($hover-selected-background) and $hover-background { - $hover-selected-background: $hover-background; + @if not($hover-selected-background) and $selected-background { + $hover-selected-background: hsl(from var(--selected-background) h s calc(l * 0.9)); } @if not($hover-selected-text-color) and $hover-selected-background { - $hover-selected-text-color: text-contrast(to-opaque($hover-selected-background)); + $hover-selected-text-color: adaptive-contrast(var(--hover-selected-background)); } - @if not($focus-selected-background) and $selected-background { - $luminance: luminance($selected-background); - - @if meta.type-of($luminance) == 'color' and $luminance + .05 < .5 { - $focus-selected-background: color.scale($background, $lightness: 32%); - } @else { - $focus-selected-background: color.scale($background, $lightness: -16%); + @if $variant != 'indigo' { + @if not($focus-selected-background) and $selected-background { + $focus-selected-background: hsl(from var(--selected-background) h s calc(l * 0.8)); + } + } @else { + @if not($focus-selected-background) and $selected-background { + $focus-selected-background: var(--selected-background); } } @if not($focus-selected-text-color) and $focus-selected-background { - $focus-selected-text-color: text-contrast(to-opaque($focus-selected-background)); + $focus-selected-text-color: adaptive-contrast(var(--focus-selected-background)); } @if not($hover-border-color) and $border-color { - $hover-border-color: $border-color; + $hover-border-color: var(--border-color); } @if not($focus-border-color) and $border-color { - $focus-border-color: $border-color; + $focus-border-color: var(--border-color); } @if not($selected-border-color) and $border-color { - $selected-border-color: $border-color; + $selected-border-color: var(--border-color); } @if not($hover-selected-border-color) and $border-color { - $hover-selected-border-color: $border-color; + $hover-selected-border-color: var(--border-color); } @if not($focus-selected-border-color) and $border-color { - $focus-selected-border-color: $border-color; + $focus-selected-border-color: var(--border-color); + } + + @if $variant == 'indigo' { + @if not($selected-border-color) and $selected-background { + $selected-border-color: var(--selected-background); + } + + @if not($hover-selected-border-color) and $hover-selected-background { + $hover-selected-border-color: var(--hover-selected-background); + } + + @if not($focus-selected-border-color) and $focus-selected-background { + $focus-selected-border-color: var(--focus-selected-background); + } + } + + @if $variant == 'bootstrap' or $variant == 'indigo' { + @if not($focus-outline-color) and $focus-background { + $focus-outline-color: hsla(from var(--focus-background) h s l / 0.4); + } + + @if not($focus-selected-outline-color) and $focus-selected-background { + $focus-selected-outline-color: hsla(from var(--focus-selected-background) h s l / 0.4); + } } @if not($ghost-shadow) { @@ -240,11 +262,6 @@ remove-icon-color-focus: $remove-icon-color-focus, focus-selected-outline-color: $focus-selected-outline-color, focus-outline-color: $focus-outline-color, - theme: map.get($schema, '_meta', 'theme'), - _meta: map.merge(if($meta, $meta, ()), ( - variant: map.get($schema, '_meta', 'theme'), - theme-variant: map.get($schema, '_meta', 'variant') - )), size: $size, )); } @@ -256,8 +273,8 @@ @include css-vars($theme); $chip-max-width: 32ch; - $variant: map.get($theme, '_meta', 'variant'); - $theme-variant: map.get($theme, '_meta', 'theme-variant'); + $variant: map.get($theme, '_meta', 'theme'); + $theme-variant: map.get($theme, '_meta', 'variant'); $chip-padding: ( comfortable: rem(if($variant != 'indigo', 12px, 7px)), diff --git a/projects/igniteui-angular/src/lib/core/styles/components/column-actions/_column-actions-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/column-actions/_column-actions-theme.scss index 47c6c705edf..10bc31b20f6 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/column-actions/_column-actions-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/column-actions/_column-actions-theme.scss @@ -37,20 +37,15 @@ } $theme: digest-schema($column-actions-schema); - $meta: map.get($theme, '_meta'); @if not($title-color) and $background-color { - $title-color: text-contrast($background-color); + $title-color: adaptive-contrast(var(--background-color)); } @return extend($theme, ( name: $name, title-color: $title-color, background-color: $background-color, - theme: map.get($schema, '_meta', 'theme'), - _meta: map.merge(if($meta, $meta, ()), ( - variant: map.get($schema, '_meta', 'theme'), - )), )); } @@ -59,7 +54,7 @@ /// @param {Map} $theme - The theme used to style the component. @mixin column-actions($theme) { @include css-vars($theme); - $variant: map.get($theme, '_meta', 'variant'); + $variant: map.get($theme, '_meta', 'theme'); %column-actions-display { display: flex; diff --git a/projects/igniteui-angular/src/lib/core/styles/components/combo/_combo-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/combo/_combo-theme.scss index 58e551cb3c5..b04cb960e80 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/combo/_combo-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/combo/_combo-theme.scss @@ -60,7 +60,49 @@ } $theme: digest-schema($combo-schema); - $meta: map.get($theme, '_meta'); + $variant: map.get($theme, '_meta', 'theme'); + + @if not($empty-list-placeholder-color) and $empty-list-background { + $empty-list-placeholder-color: adaptive-contrast(var(--empty-list-background)); + } + + @if not($toggle-button-foreground) and $toggle-button-background { + $toggle-button-foreground: adaptive-contrast(var(--toggle-button-background)); + } + + @if $variant == 'material' { + @if not($toggle-button-background-focus) and $toggle-button-background { + $toggle-button-background-focus: hsl(from var(--toggle-button-background) h s calc(l * 0.9)); + } + } @else { + @if not($toggle-button-background-focus) and $toggle-button-background { + $toggle-button-background-focus: var(--toggle-button-background); + } + } + + @if not($toggle-button-foreground-focus) and $toggle-button-background-focus { + $toggle-button-foreground-focus: adaptive-contrast(var(--toggle-button-background-focus)); + } + + @if not($toggle-button-background-focus--border) and $toggle-button-background { + $toggle-button-background-focus--border: var(--toggle-button-background); + } + + @if not($toggle-button-foreground-filled) and $toggle-button-background { + $toggle-button-foreground-filled: adaptive-contrast(var(--toggle-button-background)); + } + + @if not($toggle-button-background-disabled) and $toggle-button-background { + $toggle-button-background-disabled: hsla(from var(--toggle-button-background) h s l / 0.3); + } + + @if not($toggle-button-foreground-disabled) and $toggle-button-background { + $toggle-button-foreground-disabled: hsla(from adaptive-contrast(var(--toggle-button-background)) h s l / 0.7); + } + + @if not($clear-button-foreground-focus) and $clear-button-background-focus { + $clear-button-foreground-focus: adaptive-contrast(var(--clear-button-background-focus)); + } @return extend($theme, ( name: $name, @@ -80,10 +122,6 @@ clear-button-background-focus: $clear-button-background-focus, clear-button-foreground: $clear-button-foreground, clear-button-foreground-focus: $clear-button-foreground-focus, - theme: map.get($schema, '_meta', 'theme'), - _meta: map.merge(if($meta, $meta, ()), ( - variant: map.get($schema, '_meta', 'theme') - )), )); } @@ -93,7 +131,7 @@ @mixin combo($theme) { @include css-vars($theme); - $variant: map.get($theme, '_meta', 'variant'); + $variant: map.get($theme, '_meta', 'theme'); $search-input-inline-padding: map.get(( 'material': pad-inline(rem(4px), rem(8px), rem(16px)), diff --git a/projects/igniteui-angular/src/lib/core/styles/components/dialog/_dialog-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/dialog/_dialog-theme.scss index 09abd1eca12..88580758382 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/dialog/_dialog-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/dialog/_dialog-theme.scss @@ -46,16 +46,17 @@ } $theme: digest-schema($dialog-schema); - $meta: map.get($theme, '_meta'); @if not($title-color) and $background{ - $title-color: text-contrast($background); + $title-color: adaptive-contrast(var(--background)); } @if not($message-color) and $background{ - @if meta.type-of($background) == 'color' { - $message-color: rgba(text-contrast($background), .8); - } + $message-color: hsla(from adaptive-contrast(var(--background)) h s l / .8); + } + + @if not($border-color) and $background{ + $border-color: hsla(from adaptive-contrast(var(--background)) h s l / .3); } @if not($shadow) { @@ -71,11 +72,7 @@ title-color: $title-color, message-color: $message-color, shadow: $shadow, - border-color: $border-color, - theme: map.get($schema, '_meta', 'theme'), - _meta: map.merge(if($meta, $meta, ()), ( - variant: map.get($schema, '_meta', 'theme') - )), + border-color: $border-color )); } @@ -85,8 +82,8 @@ @mixin dialog($theme) { @include css-vars($theme); - $variant: map.get($theme, '_meta', 'variant'); - $bootstrap-theme: map.get($theme, '_meta', 'variant') == 'bootstrap'; + $variant: map.get($theme, '_meta', 'theme'); + $bootstrap-theme: map.get($theme, '_meta', 'theme') == 'bootstrap'; $dialog-min-width: map.get(( 'material': rem(280px), diff --git a/projects/igniteui-angular/src/lib/core/styles/components/divider/_divider-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/divider/_divider-theme.scss index 2326d4151e5..8cf8dbfb696 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/divider/_divider-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/divider/_divider-theme.scss @@ -32,16 +32,11 @@ } $theme: digest-schema($divider-schema); - $meta: map.get($theme, '_meta'); @return extend($theme, ( name: $name, color: $color, inset: $inset, - theme: map.get($schema, '_meta', 'theme'), - _meta: map.merge(if($meta, $meta, ()), ( - variant: map.get($schema, '_meta', 'theme'), - )), )); } @@ -51,7 +46,7 @@ @mixin divider($theme) { @include css-vars($theme); - $variant: map.get($theme, '_meta', 'variant'); + $variant: map.get($theme, '_meta', 'theme'); %igx-divider-display { position: relative; diff --git a/projects/igniteui-angular/src/lib/core/styles/components/drop-down/_drop-down-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/drop-down/_drop-down-theme.scss index 19b442dfdbe..269339629f1 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/drop-down/_drop-down-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/drop-down/_drop-down-theme.scss @@ -91,68 +91,88 @@ } $theme: digest-schema($drop-down-schema); - $meta: map.get($theme, '_meta'); + $variant: map.get($theme, '_meta', 'theme'); @if not($item-text-color) and $background-color { - $item-text-color: text-contrast($background-color); + $item-text-color: adaptive-contrast(var(--background-color)); + } + + @if not($item-icon-color) and $item-text-color { + $item-icon-color: hsla(from var(--item-text-color) h s l / 0.8); } @if not($hover-item-background) and $background-color { - $hover-item-text-color: text-contrast($background-color); + $hover-item-background: hsla(from adaptive-contrast(var(--background-color)) h s l / .12); + } - @if meta.type-of($background-color) == 'color' { - $hover-item-background: rgba(text-contrast($background-color), .12); - } + @if not($hover-item-text-color) and $item-text-color { + $hover-item-text-color: var(--item-text-color); } - @if not($hover-item-text-color) and $background-color { - $hover-item-text-color: text-contrast($background-color); + @if not($hover-item-icon-color) and $hover-item-text-color { + $hover-item-icon-color: hsla(from var(--hover-item-text-color) h s l / 0.8); } @if not($focused-item-background) and $background-color { - $focused-item-text-color: text-contrast($background-color); - - @if meta.type-of($background-color) == 'color' { - $focused-item-background: rgba(text-contrast($background-color), .12); - } + $focused-item-background: hsl(from var(--background-color) h s calc(l * 0.8)); } @if not($focused-item-text-color) and $focused-item-background { - $focused-item-text-color: text-contrast($focused-item-background); + $focused-item-text-color: adaptive-contrast(var(--focused-item-background)); + } + + @if not($selected-item-background) and $background-color { + $selected-item-background: hsl(from var(--background-color) h s calc(l * 1.2)); } @if not($selected-item-text-color) and $selected-item-background { - $selected-item-text-color: text-contrast($selected-item-background); + $selected-item-text-color: adaptive-contrast(var(--selected-item-background)); + } + + @if not($selected-item-icon-color) and $selected-item-text-color { + $selected-item-icon-color: hsla(from var(--selected-item-text-color) h s l / 0.8); + } + + @if not($selected-hover-item-background) and $selected-item-background { + $selected-hover-item-background: hsl(from var(--selected-item-background) h s calc(l * 0.7)); } @if not($selected-hover-item-text-color) and $selected-hover-item-background { - $selected-hover-item-text-color: text-contrast($selected-hover-item-background); + $selected-hover-item-text-color: adaptive-contrast(var(--selected-hover-item-background)); + } + + @if not($selected-hover-item-icon-color) and $selected-hover-item-text-color { + $selected-hover-item-icon-color: hsla(from var(--selected-hover-item-text-color) h s l / 0.8); + } + + @if not($selected-focus-item-background) and $selected-item-background { + $selected-focus-item-background: hsl(from var(--selected-item-background) h s calc(l * 0.7)); } @if not($selected-focus-item-text-color) and $selected-focus-item-background { - $selected-focus-item-text-color: text-contrast($selected-focus-item-background); + $selected-focus-item-text-color: adaptive-contrast(var(--selected-focus-item-background)); } @if not($selected-focus-item-text-color) and $selected-focus-item-background { - $selected-focus-item-text-color: text-contrast($selected-focus-item-background); + $selected-focus-item-text-color: adaptive-contrast(var(--selected-focus-item-background)); } - @if not($disabled-item-text-color) and $background-color { - @if meta.type-of($background-color) == 'color' { - $disabled-item-text-color: rgba(text-contrast($background-color), .36); + @if $variant == 'indigo' { + @if not($focused-item-border-color) and $selected-item-background { + $focused-item-border-color: var(--selected-item-background); } } + @if not($disabled-item-text-color) and $background-color { + $disabled-item-text-color: hsla(from adaptive-contrast(var(--background-color)) h s l / .36); + } + @if not($disabled-item-text-color) and $disabled-item-background { - @if meta.type-of($disabled-item-background) == 'color' { - $disabled-item-text-color: rgba(text-contrast($disabled-item-background), .36); - } + $disabled-item-text-color: hsla(from adaptive-contrast(var(--disabled-item-background)) h s l / .36); } @if not($header-text-color) and $background-color { - @if meta.type-of($background-color) == 'color' { - $header-text-color: rgba(text-contrast($background-color), .7); - } + $header-text-color: hsla(from adaptive-contrast(var(--background-color)) h s l / .7); } @if not($shadow) { @@ -189,10 +209,6 @@ border-color: $border-color, border-width: $border-width, size: $size, - theme: map.get($schema, '_meta', 'theme'), - _meta: map.merge(if($meta, $meta, ()), ( - variant: map.get($schema, '_meta', 'theme') - )), )); } @@ -201,7 +217,7 @@ /// @param {Map} $theme - The theme used to style the component. @mixin drop-down($theme) { @include css-vars($theme); - $variant: map.get($theme, '_meta', 'variant'); + $variant: map.get($theme, '_meta', 'theme'); %igx-drop-down { position: absolute; diff --git a/projects/igniteui-angular/src/lib/core/styles/components/expansion-panel/_expansion-panel-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/expansion-panel/_expansion-panel-theme.scss index 20e144dcca6..2798fbfd668 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/expansion-panel/_expansion-panel-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/expansion-panel/_expansion-panel-theme.scss @@ -53,24 +53,33 @@ } $theme: digest-schema($expansion-panel-schema); - $meta: map.get($theme, '_meta'); @if not($header-title-color) and $header-background { - $header-title-color: text-contrast($header-background); + $header-title-color: adaptive-contrast(var(--header-background)); + } + + @if not($header-icon-color) and $header-background { + $header-icon-color: adaptive-contrast(var(--header-background)); } @if not($header-description-color) and $header-background { - @if meta.type-of($header-background) == 'color' { - $header-description-color: rgba(text-contrast($header-background), .8); - } + $header-description-color: hsla(from adaptive-contrast(var(--header-background)) h s l / .8); } - @if not($header-icon-color) and $header-background { - $header-icon-color: text-contrast($header-background); + @if not($header-focus-background) and $header-background { + $header-focus-background: hsl(from var(--header-background) h s calc(l * 1.1)); } @if not($body-color) and $body-background { - $body-color: text-contrast($body-background); + $body-color: adaptive-contrast(var(--body-background)); + } + + @if not($disabled-text-color) and $header-background { + $disabled-text-color: hsla(from adaptive-contrast(var(--header-background)) h s l / .5); + } + + @if not($disabled-description-color) and $header-background { + $disabled-description-color: hsla(from adaptive-contrast(var(--header-background)) h s l / .5); } @return extend($theme, ( @@ -86,10 +95,6 @@ disabled-text-color: $disabled-text-color, disabled-description-color: $disabled-description-color, expanded-margin: $expanded-margin, - theme: map.get($schema, '_meta', 'theme'), - _meta: map.merge(if($meta, $meta, ()), ( - variant: map.get($schema, '_meta', 'theme') - )), )); } @@ -98,7 +103,7 @@ /// @param {Map} $theme - The theme used to style the component. @mixin expansion-panel($theme) { @include css-vars($theme); - $variant: map.get($theme, '_meta', 'variant'); + $variant: map.get($theme, '_meta', 'theme'); $panel-padding: rem(16px) rem(24px); $panel-padding-header-indigo: rem(10px) rem(16px); diff --git a/projects/igniteui-angular/src/lib/core/styles/components/grid-summary/_grid-summary-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/grid-summary/_grid-summary-theme.scss index 3fe579c34d5..f82f8e2559e 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/grid-summary/_grid-summary-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/grid-summary/_grid-summary-theme.scss @@ -50,22 +50,25 @@ } $theme: digest-schema($grid-summary-schema); - $meta: map.get($theme, '_meta'); + + @if not($label-color) and $background-color { + $label-color: adaptive-contrast(var(--background-color)); + } + + @if not($label-hover-color) and $label-color { + $label-hover-color: var(--label-color); + } @if not($result-color) and $background-color { - $result-color: text-contrast($background-color); + $result-color: adaptive-contrast(var(--background-color)); } @if not($border-color) and $background-color { - @if type-of($background-color) == 'color' { - $border-color: rgba(text-contrast($background-color), .26); - } + $border-color: hsla(from adaptive-contrast(var(--background-color)) h s l / .26); } @if not($pinned-border-color) and $background-color { - @if type-of($background-color) == 'color' { - $pinned-border-color: rgba(text-contrast($background-color), .26); - } + $pinned-border-color: hsla(from adaptive-contrast(var(--background-color)) h s l / .26); } @return extend($theme, ( @@ -79,10 +82,6 @@ pinned-border-style: $pinned-border-style, pinned-border-color: $pinned-border-color, label-hover-color: $label-hover-color, - theme: map.get($schema, '_meta', 'theme'), - _meta: map.merge(if($meta, $meta, ()), ( - variant: map.get($schema, '_meta', 'theme') - )), )); } @@ -92,7 +91,7 @@ @mixin grid-summary($theme) { @include css-vars($theme); - $variant: map.get($theme, '_meta', 'variant'); + $variant: map.get($theme, '_meta', 'theme'); $cell-pin: ( style: var-get($theme, 'pinned-border-width') var-get($theme, 'pinned-border-style'), diff --git a/projects/igniteui-angular/src/lib/core/styles/components/grid-toolbar/_grid-toolbar-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/grid-toolbar/_grid-toolbar-theme.scss index f45ce0a3238..da35e179b9f 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/grid-toolbar/_grid-toolbar-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/grid-toolbar/_grid-toolbar-theme.scss @@ -52,30 +52,29 @@ } $theme: digest-schema($grid-toolbar-schema); - $meta: map.get($theme, '_meta'); @if not($title-text-color) and $background-color { - $title-text-color: text-contrast($background-color); + $title-text-color: adaptive-contrast(var(--background-color)); } @if not($item-text-color) and $dropdown-background { - $item-text-color: text-contrast($dropdown-background); + $item-text-color: adaptive-contrast(var(--dropdown-background)); } @if not($item-hover-text-color) and $dropdown-background { - $item-hover-text-color: text-contrast($dropdown-background); + $item-hover-text-color: adaptive-contrast(var(--dropdown-background)); } @if not($item-focus-text-color) and $dropdown-background { - $item-focus-text-color: text-contrast($dropdown-background); + $item-focus-text-color: adaptive-contrast(var(--dropdown-background)); } @if not($item-hover-text-color) and $item-hover-background { - $item-hover-text-color: text-contrast($item-hover-background); + $item-hover-text-color: adaptive-contrast(var(--item-hover-background)); } @if not($item-focus-text-color) and $item-focus-background { - $item-focus-text-color: text-contrast($item-focus-background); + $item-focus-text-color: adaptive-contrast(var(--item-focus-background)); } @return extend($theme, ( @@ -89,10 +88,6 @@ item-hover-text-color: $item-hover-text-color, item-focus-background: $item-focus-background, item-focus-text-color: $item-focus-text-color, - theme: map.get($schema, '_meta', 'theme'), - _meta: map.merge(if($meta, $meta, ()), ( - variant: map.get($schema, '_meta', 'theme') - )), size: $size, border-color: $border-color )); @@ -104,7 +99,7 @@ @mixin grid-toolbar($theme) { @include css-vars($theme); - $variant: map.get($theme, '_meta', 'variant'); + $variant: map.get($theme, '_meta', 'theme'); $bootstrap-theme: $variant == 'bootstrap'; // Caption 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..145d5f0dae8 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 @@ -225,104 +225,113 @@ } $theme: digest-schema($grid-schema); - $meta: map.get($theme, '_meta'); - - @if not($cell-selected-within-text-color) and $cell-selected-within-background { - $cell-selected-within-text-color: text-contrast($cell-selected-within-background); - } @if not($ghost-header-icon-color) and $ghost-header-background { - @if meta.type-of($ghost-header-background) == 'color' { - $ghost-header-icon-color: rgba(text-contrast($ghost-header-background), .07); - } + $ghost-header-icon-color: hsla(from adaptive-contrast(var(--ghost-header-background)) h s l / .07); } @if not($ghost-header-text-color) and $ghost-header-background { - $ghost-header-text-color: text-contrast($ghost-header-background); + $ghost-header-text-color: adaptive-contrast(var(--ghost-header-background)); } - @if $header-background and meta.type-of($header-background) == 'color' { - $header-background: to-opaque($header-background, color($color: 'surface')); + @if not($header-text-color) and $header-background { + $header-text-color: adaptive-contrast(var(--header-background)); } - @if not($header-text-color) and $header-background { - $header-text-color: text-contrast($header-background); + @if not($header-selected-background) and $header-background { + $header-selected-background: hsl(from var(--header-background) h s calc(l * 0.9)); } @if not($header-selected-text-color) and $header-selected-background { - $header-selected-text-color: text-contrast($header-selected-background); + $header-selected-text-color: adaptive-contrast(var(--header-selected-background)); } @if not($header-border-color) and $header-background { - @if meta.type-of($header-background) == 'color' { - $header-border-color: rgba(text-contrast($header-background), .24); - } + $header-border-color: hsla(from adaptive-contrast(var(--header-background)) h s l / .24); } @if not($content-text-color) and $content-background { - $content-text-color: text-contrast($content-background); + $content-text-color: adaptive-contrast(var(--content-background)); } @if not($row-odd-background) and $content-background { - $row-odd-background: $content-background; - } - - @if $row-odd-background and meta.type-of($row-odd-background) == 'color' and color.alpha($row-odd-background) != 1 { - $cbg: if($content-background, $content-background, map.get($theme, 'content-background')); - - $row-odd-background: to-opaque($row-odd-background, $cbg); + $row-odd-background: hsl(from var(--content-background) h calc(s - 10) l); } @if not($row-odd-text-color) and $row-odd-background { - $row-odd-text-color: text-contrast($row-odd-background); + $row-odd-text-color: adaptive-contrast(var(--row-odd-background)); } @if not($row-even-background) and $content-background { - $row-even-background: $content-background; - } - - @if $row-even-background and meta.type-of($row-even-background) == 'color' and color.alpha($row-even-background) != 1 { - $cbg: if($content-background, $content-background, map.get($theme, 'content-background')); - - $row-even-background: to-opaque($row-even-background, $cbg); + $row-even-background: hsl(from var(--content-background) h calc(s + 10) l); } @if not($row-even-text-color) and $row-even-background { - $row-even-text-color: text-contrast($row-even-background); + $row-even-text-color: adaptive-contrast(var(--row-even-background)); } @if not($row-hover-background) and $content-background { - @if meta.type-of($content-background) == 'color' { - $row-hover-background: to-opaque(rgba(text-contrast($content-background), .08), $content-background) - } + $row-hover-background: hsl(from var(--content-background) h s calc(l * 0.85)); } @if not($row-hover-text-color) and $row-hover-background { - $row-hover-text-color: text-contrast($row-hover-background); + $row-hover-text-color: adaptive-contrast(var(--row-hover-background)); + } + + @if not($cell-selected-background) and $content-background { + $cell-selected-background: hsl(from var(--content-background) h s calc(l * 0.9)); } @if not($cell-selected-text-color) and $cell-selected-background { - $cell-selected-text-color: text-contrast($cell-selected-background); + $cell-selected-text-color: adaptive-contrast(var(--cell-selected-background)); + } + + @if not($row-selected-background) and $content-background { + $row-selected-background: hsl(from var(--content-background) h s calc(l * 0.9)); } @if not($row-selected-text-color) and $row-selected-background { - $row-selected-text-color: text-contrast($row-selected-background); + $row-selected-text-color: adaptive-contrast(var(--row-selected-background)); + } + + @if not($row-selected-hover-background) and $row-selected-background { + $row-selected-hover-background: hsl(from var(--row-selected-background) h s calc(l * 0.85)); } @if not($row-selected-hover-text-color) and $row-selected-hover-background { - $row-selected-hover-text-color: text-contrast($row-selected-hover-background); + $row-selected-hover-text-color: adaptive-contrast(var(--row-selected-hover-background)); } @if not($row-border-color) and $content-background { - @if meta.type-of($content-background) == 'color' { - $row-border-color: rgba(text-contrast($content-background), .08) - } + $row-border-color: hsla(from adaptive-contrast(var(--content-background)) h s l / .08); + } + + @if not($cell-selected-within-background) and $row-selected-background { + $cell-selected-within-background: hsl(from var(--row-selected-background) h s calc(l * 0.85)); + } + + @if not($cell-selected-within-text-color) and $cell-selected-within-background { + $cell-selected-within-text-color: adaptive-contrast(var(--cell-selected-within-background)); + } + + @if not($cell-editing-background) and $content-background { + $cell-editing-background: var(--content-background); + } + + @if not($cell-editing-foreground) and $cell-editing-background { + $cell-editing-foreground: adaptive-contrast(var(--cell-editing-background)); + } + + @if not($cell-editing-focus-foreground) and $cell-editing-background { + $cell-editing-focus-foreground: adaptive-contrast(var(--cell-editing-background)); + } + + @if not($cell-active-border-color) and $content-background { + $cell-active-border-color: hsla(from adaptive-contrast(var(--content-background)) h s l / .5); } @if not($pinned-border-color) and $content-background { - @if meta.type-of($content-background) == 'color' { - $pinned-border-color: rgba(text-contrast($content-background), .08) - } + $pinned-border-color: hsla(from adaptive-contrast(var(--content-background)) h s l / .08); } @if not($group-row-background) and $header-background { @@ -330,61 +339,75 @@ } @if not($expand-icon-color) and $group-row-background { - $expand-icon-color: text-contrast($group-row-background) + $expand-icon-color: adaptive-contrast(var(--group-row-background)) + } + + @if not($group-row-selected-background) and $group-row-background { + $group-row-selected-background: hsl(from var(--group-row-background) h s calc(l * 0.8)); } @if not($group-label-text) and $group-row-selected-background { - $group-label-text: text-contrast($group-row-selected-background) + $group-label-text: adaptive-contrast(var(--group-row-selected-background)) } @if not($expand-icon-color) and $group-row-selected-background { - $expand-icon-color: text-contrast($group-row-selected-background) + $expand-icon-color: adaptive-contrast(var(--group-row-selected-background)) + } + + @if not($expand-icon-hover-color) and $expand-icon-color { + $expand-icon-hover-color: var(--expand-icon-color); } @if not($group-count-background) and $group-row-selected-background { - $group-count-background: text-contrast($group-row-selected-background); + $group-count-background: adaptive-contrast(var(--group-row-selected-background)); } @if not($expand-all-icon-color) and $header-background { - @if meta.type-of($header-background) == 'color' { - $expand-all-icon-color: rgba(text-contrast($header-background), .87); - } + $expand-all-icon-color: hsla(from adaptive-contrast(var(--header-background)) h s l / .87); } @if not($expand-all-icon-hover-color) and $header-background { - $expand-all-icon-hover-color: text-contrast($header-background); + $expand-all-icon-hover-color: adaptive-contrast(var(--header-background)); + } + + @if not($sorted-header-icon-color) and $header-background { + $sorted-header-icon-color: hsla(from adaptive-contrast(var(--header-background)) h s l / 0.8); + } + + @if not($sortable-header-icon-hover-color) and $sorted-header-icon-color { + $sortable-header-icon-hover-color: hsla(from var(--sorted-header-icon-color) h s l / 1); + } + + @if not($edit-mode-color) and $content-background { + $edit-mode-color: hsla(from adaptive-contrast(var(--content-background)) h s l / 0.5); } @if not($group-label-text) and $group-row-background { - $group-label-text: text-contrast($group-row-background) + $group-label-text: adaptive-contrast(var(--group-row-background)) } @if not($group-count-background) and $group-row-background { - $group-count-background: text-contrast($group-row-background); + $group-count-background: adaptive-contrast(var(--group-row-background)); } @if not($group-count-text-color) and $group-count-background { - $group-count-text-color: text-contrast($group-count-background); + $group-count-text-color: adaptive-contrast(var(--group-count-background)); } @if not($grouparea-background) and $header-background { - $grouparea-background: $header-background + $grouparea-background: var(--header-background); } @if not($grouparea-color) and $grouparea-background { - @if meta.type-of($grouparea-background) == 'color' { - $grouparea-color: rgba(text-contrast($grouparea-background), .8) - } + $grouparea-color: hsla(from adaptive-contrast(var(--grouparea-background)) h s l / .8); } @if not($grouparea-color) and $header-background { - @if meta.type-of($header-background) == 'color' { - $grouparea-color: rgba(text-contrast($header-background), .8) - } + $grouparea-color: hsla(from adaptive-contrast(var(--header-background)) h s l / .8); } @if not($drop-area-background) and $grouparea-background { - $drop-area-background: text-contrast($grouparea-background); + $drop-area-background: adaptive-contrast(var(--grouparea-background)); } @if not($drop-area-on-drop-background) and $drop-area-background { @@ -392,49 +415,53 @@ } @if not($drop-area-text-color) and $drop-area-background { - $drop-area-text-color: text-contrast($drop-area-background) + $drop-area-text-color: adaptive-contrast(var(--drop-area-background)); } @if not($drop-area-icon-color) and $drop-area-background { - $drop-area-icon-color: text-contrast($drop-area-background) + $drop-area-icon-color: adaptive-contrast(var(--drop-area-background)); } @if not($filtering-header-background) and $header-background { - @if meta.type-of($header-background) == 'color' { - @if luminance($header-background) < .5 { - $filtering-header-background: to-opaque(color.scale($header-background, $lightness: 5%)); - } @else { - $filtering-header-background: to-opaque(color.scale($header-background, $lightness: -5%)); - } - } + $filtering-header-background: color-mix(in hsl, var(--header-background), #fff 5%); } @if not($filtering-header-text-color) and $filtering-header-background { - $filtering-header-text-color: text-contrast($filtering-header-background); + $filtering-header-text-color: adaptive-contrast(var(--filtering-header-background)); } @if not($filtering-row-background) and $header-background { - @if meta.type-of($header-background) == 'color' { - @if luminance($header-background) < .5 { - $filtering-row-background: to-opaque(color.scale($header-background, $lightness: 5%)); - } @else { - $filtering-row-background: to-opaque(color.scale($header-background, $lightness: -5%)); - } - } + $filtering-row-background: color-mix(in hsl, var(--header-background), #fff 5%); } @if not($filtering-row-text-color) and $filtering-row-background { - $filtering-row-text-color: text-contrast(to-opaque($filtering-row-background)); + $filtering-row-text-color: adaptive-contrast(var(--filtering-row-background)); + } + + @if not($excel-filtering-header-foreground) and $filtering-row-background { + $excel-filtering-header-foreground: adaptive-contrast(var(--filtering-row-background)); + } + + @if not($excel-filtering-subheader-foreground) and $filtering-row-background { + $excel-filtering-subheader-foreground: adaptive-contrast(var(--filtering-row-background)); + } + + @if not($excel-filtering-actions-foreground) and $filtering-row-background { + $excel-filtering-actions-foreground: hsla(from adaptive-contrast(var(--filtering-row-background)) h s l / 0.8); + } + + @if not($excel-filtering-actions-disabled-foreground) and $filtering-row-background { + $excel-filtering-actions-disabled-foreground: hsla(from adaptive-contrast(var(--filtering-row-background)) h s l / 0.5); } @if not($grid-shadow) { $grid-elevation: map.get($grid-schema, 'grid-elevation'); - $grid-shadow: elevation($grid-elevation); + $grid-shadow: elevation(var(--grid-elevation)); } @if not($drag-shadow) { $drag-elevation: map.get($grid-schema, 'drag-elevation'); - $drag-shadow: elevation($drag-elevation); + $drag-shadow: elevation(var(--drag-elevation)); } @if not($drop-area-border-radius) { @@ -553,12 +580,6 @@ cell-selected-within-background: $cell-selected-within-background, cell-selected-within-text-color: $cell-selected-within-text-color, - - theme: map.get($schema, '_meta', 'theme'), - _meta: map.merge(if($meta, $meta, ()), ( - variant: map.get($schema, '_meta', 'theme'), - theme-variant: map.get($schema, '_meta', 'variant') - )), )); } @@ -580,8 +601,8 @@ @include scale-in-ver-center(); - $variant: map.get($theme, '_meta', 'variant'); - $theme-variant: map.get($theme, '_meta', 'theme-variant'); + $variant: map.get($theme, '_meta', 'theme'); + $theme-variant: map.get($theme, '_meta', 'variant'); $bootstrap-theme: $variant == 'bootstrap'; $not-bootstrap-theme: $variant != 'bootstrap'; diff --git a/projects/igniteui-angular/src/lib/core/styles/components/grid/_pivot-data-selector-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/grid/_pivot-data-selector-theme.scss index 2723371e9a9..29747c382f8 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/grid/_pivot-data-selector-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/grid/_pivot-data-selector-theme.scss @@ -25,14 +25,9 @@ } $theme: digest-schema($pivot-data-selector-schema); - $meta: map.get($theme, '_meta'); @return extend($theme, ( name: $name, - theme: map.get($schema, '_meta', 'theme'), - _meta: map.merge(if($meta, $meta, ()), ( - variant: map.get($schema, '_meta', 'theme') - )), )); } @@ -41,7 +36,7 @@ /// @param {Map} $theme - The theme used to style the component. @mixin pivot-data-selector($theme) { @include css-vars($theme); - $variant: map.get($theme, '_meta', 'variant'); + $variant: map.get($theme, '_meta', 'theme'); $chip-height-material: ( comfortable: rem(22px), diff --git a/projects/igniteui-angular/src/lib/core/styles/components/highlight/highlight-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/highlight/highlight-theme.scss index 641077c20d6..7a575101755 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/highlight/highlight-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/highlight/highlight-theme.scss @@ -39,11 +39,11 @@ $theme: digest-schema($highlight-schema); @if not($resting-color) and $resting-background { - $resting-color: text-contrast($resting-background); + $resting-color: adaptive-contrast(var(--resting-background)); } @if not($active-color) and $active-background { - $active-color: text-contrast($active-background); + $active-color: adaptive-contrast(var(--active-background)); } @return extend($theme, ( @@ -53,7 +53,6 @@ resting-color: $resting-color, active-background: $active-background, active-color: $active-color, - theme: map.get($schema, '_meta', 'theme'), )); } diff --git a/projects/igniteui-angular/src/lib/core/styles/components/icon-button/_contained-icon-button-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/icon-button/_contained-icon-button-theme.scss new file mode 100644 index 00000000000..8c186676e21 --- /dev/null +++ b/projects/igniteui-angular/src/lib/core/styles/components/icon-button/_contained-icon-button-theme.scss @@ -0,0 +1,196 @@ +@use 'sass:map'; +@use '../../base' as *; +@use '../../themes/schemas' as *; + +@function contained-icon-button-theme( + $schema: $light-material-schema, + + $background: null, + $foreground: null, + $shadow-color: null, + + $hover-background: null, + $hover-foreground: null, + + $focus-background: null, + $focus-foreground: null, + + $focus-hover-background: null, + $focus-hover-foreground: null, + + $active-background: null, + $active-foreground: null, + + $border-radius: null, + $border-color: null, + $focus-border-color: null, + + $disabled-background: null, + $disabled-foreground: null, + $disabled-border-color: null, + + $size: null, +) { + $name: 'igx-contained-icon-button'; + $icon-button-schema: (); + + @if map.has-key($schema, 'icon-button') { + $icon-button-schema: map.get($schema, 'icon-button'); + @if map.has-key($icon-button-schema, 'contained') { + $icon-button-schema: map.get($icon-button-schema, 'contained'); + } @else { + $icon-button-schema: $schema; + } + } + + $theme: digest-schema($icon-button-schema); + $variant: map.get($schema, '_meta', 'theme'); + + @if not($hover-foreground) and $foreground { + $hover-foreground: var(--foreground); + } + + @if not($focus-foreground) and $foreground { + $focus-foreground: var(--foreground); + } + + @if not($focus-hover-foreground) and $foreground { + $focus-hover-foreground: var(--foreground); + } + + @if not($active-foreground) and $foreground { + $active-foreground: var(--foreground); + } + + @if $variant == 'indigo' { + @if not($foreground) and $background { + $foreground: hsla(from adaptive-contrast(var(--background)) h s l / 0.8); + } + + @if not($hover-background) and $background { + $hover-background: hsl(from var(--background) h s calc(l * 1.1)); + } + + @if not($focus-background) and $background { + $focus-background: var(--background); + } + + @if not($focus-foreground) and $foreground { + $focus-foreground: var(--foreground); + } + + @if not($focus-hover-background) and $focus-background { + $focus-hover-background: hsl(from var(--focus-background) h s calc(l * 1.1)); + } + + @if not($active-background) and $background { + $active-background: hsl(from var(--background) h s calc(l * 1.1)); + } + } @else { + @if not($foreground) and $background { + $foreground: adaptive-contrast(var(--background)); + } + + @if not($hover-background) and $background { + $hover-background: hsl(from var(--background) h s calc(l * 0.9)); + } + + @if not($focus-background) and $background { + @if $variant == 'fluent' or $variant == 'bootstrap' { + $focus-background: var(--background); + } @else { + $focus-background: hsl(from var(--background) h s calc(l * 0.8)); + } + } + + @if not($focus-foreground) and $focus-background { + $focus-foreground: adaptive-contrast(var(--focus-background)); + } + + @if not($focus-hover-background) and $focus-background { + $focus-hover-background: hsl(from var(--focus-background) h s calc(l * 0.9)); + } + + @if not($active-background) and $background { + $active-background: hsl(from var(--background) h s calc(l * 0.8)); + } + } + + @if not($hover-foreground) and $hover-background { + $hover-foreground: adaptive-contrast(var(--hover-background)); + } + + @if not($focus-hover-foreground) and $focus-hover-background { + $focus-hover-foreground: adaptive-contrast(var(--focus-hover-background)); + } + + @if not($active-foreground) and $active-background { + $active-foreground: adaptive-contrast(var(--active-background)); + } + + @if not($shadow-color) and $focus-background { + $shadow-color: hsla(from var(--focus-background) h s l / 0.5); + } + + @if $variant == 'fluent' { + @if not($focus-border-color) and $foreground { + $focus-border-color: var(--foreground); + } + } @else { + @if not($focus-border-color) and $border-color { + $focus-border-color: hsl(from var(--border-color) h s calc(l * 0.8)); + } + } + + @if $variant == 'indigo' { + @if not($disabled-background) and $background { + $disabled-background: hsla(from var(--background) h s l / 0.4); + } + + @if not($disabled-foreground) and $foreground { + $disabled-foreground: hsla(from var(--foreground) h s l / 0.5); + } + + @if not($focus-border-color) and $focus-background { + $focus-border-color: hsla(from var(--focus-background) h s l / 0.3); + } + } @else if $variant == 'bootstrap' { + @if not($disabled-background) and $background { + $disabled-background: hsla(from var(--background) h s l / 0.2); + } + + @if not($disabled-foreground) and $disabled-background { + $disabled-foreground: hsla(from var(--disabled-background) h s l / 0.7); + } + } + + @return extend( + $theme, + ( + name: $name, + background: $background, + foreground: $foreground, + shadow-color: $shadow-color, + + hover-background: $hover-background, + hover-foreground: $hover-foreground, + + focus-background: $focus-background, + focus-foreground: $focus-foreground, + + focus-hover-background: $focus-hover-background, + focus-hover-foreground: $focus-hover-foreground, + + active-background: $active-background, + active-foreground: $active-foreground, + + border-radius: $border-radius, + border-color: $border-color, + focus-border-color: $focus-border-color, + + disabled-background: $disabled-background, + disabled-foreground: $disabled-foreground, + disabled-border-color: $disabled-border-color, + size: $size, + )); +} diff --git a/projects/igniteui-angular/src/lib/core/styles/components/icon-button/_flat-icon-button-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/icon-button/_flat-icon-button-theme.scss new file mode 100644 index 00000000000..c5d35da4741 --- /dev/null +++ b/projects/igniteui-angular/src/lib/core/styles/components/icon-button/_flat-icon-button-theme.scss @@ -0,0 +1,188 @@ +@use 'sass:map'; +@use '../../base' as *; +@use '../../themes/schemas' as *; + +@function flat-icon-button-theme( + $schema: $light-material-schema, + + $background: null, + $foreground: null, + $shadow-color: null, + + $hover-background: null, + $hover-foreground: null, + + $focus-background: null, + $focus-foreground: null, + + $focus-hover-background: null, + $focus-hover-foreground: null, + + $active-background: null, + $active-foreground: null, + + $border-radius: null, + $border-color: null, + $focus-border-color: null, + + $disabled-background: null, + $disabled-foreground: null, + $disabled-border-color: null, + + $size: null, +) { + $name: 'igx-flat-icon-button'; + $icon-button-schema: (); + + @if map.has-key($schema, 'icon-button') { + $icon-button-schema: map.get($schema, 'icon-button'); + @if map.has-key($icon-button-schema, 'flat') { + $icon-button-schema: map.get($icon-button-schema, 'flat'); + } @else { + $icon-button-schema: $schema; + } + } + + $theme: digest-schema($icon-button-schema); + $variant: map.get($schema, '_meta', 'theme'); + + @if not($hover-foreground) and $hover-background { + $hover-foreground: adaptive-contrast(var(--hover-background)); + } + + @if not($focus-foreground) and $focus-background { + $focus-foreground: adaptive-contrast(var(--focus-background)); + } + + @if not($focus-hover-foreground) and $focus-hover-background { + $focus-hover-foreground: adaptive-contrast(var(--focus-hover-background)); + } + + @if not($active-foreground) and $active-background { + $active-foreground: adaptive-contrast(var(--active-background)); + } + + @if $variant == 'material' or $variant == 'fluent' { + @if not($hover-foreground) and $foreground { + $hover-foreground: var(--foreground); + } + + @if not($focus-foreground) and $foreground { + $focus-foreground: var(--foreground); + } + + @if not($focus-hover-foreground) and $foreground { + $focus-hover-foreground: var(--foreground); + } + + @if not($active-foreground) and $foreground { + $active-foreground: var(--foreground); + } + + @if not($hover-background) and $foreground { + $hover-background: hsla(from var(--foreground) h s l / 0.08); + } + + @if $variant == 'material' { + @if not($focus-background) and $foreground { + $focus-background: hsla(from var(--foreground) h s l / 0.16); + } + + @if not($focus-hover-background) and $foreground { + $focus-hover-background: hsla(from var(--foreground) h s l / 0.24); + } + } @else { + @if not($focus-hover-background) and $hover-background { + $focus-hover-background: var(--hover-background); + } + } + + @if not($active-background) and $foreground { + $active-background: hsla(from var(--foreground) h s l / 0.24); + } + } + + @if $variant == 'indigo' { + @if not($hover-background) and $foreground { + $hover-background: hsla(from var(--foreground) h s l / 0.15); + } + + @if not($focus-background) and $foreground { + $focus-background: hsla(from var(--foreground) h s l / 0.15); + } + + @if not($focus-hover-background) and $foreground { + $focus-hover-background: hsla(from var(--foreground) h s l / 0.15); + } + + @if not($active-background) and $foreground { + $active-background: hsla(from var(--foreground) h s l / 0.15); + } + } + + @if $variant == 'bootstrap'or $variant == 'indigo' { + @if not($hover-foreground) and $foreground { + $hover-foreground: hsl(from var(--foreground) h s calc(l * 0.9)); + } + + @if not($focus-foreground) and $foreground { + $focus-foreground: var(--foreground); + } + + @if not($focus-hover-foreground) and $hover-foreground { + $focus-hover-foreground: var(--hover-foreground); + } + + @if not($disabled-foreground) and $foreground { + $disabled-foreground: hsla(from var(--foreground) h s l / 0.5); + } + + @if $variant == 'bootstrap' { + @if not($active-foreground) and $foreground { + $active-foreground: hsl(from var(--foreground) h s calc(l * 0.7)); + } + + @if not($shadow-color) and $foreground { + $shadow-color: hsla(from var(--foreground) h s l / 0.5); + } + } @else { + @if not($active-foreground) and $hover-foreground { + $active-foreground: var(--hover-foreground); + } + + @if not($focus-border-color) and $foreground { + $focus-border-color: hsla(from var(--foreground) h s l / 0.3); + } + } + } + + @return extend( + $theme, + ( + name: $name, + background: $background, + foreground: $foreground, + shadow-color: $shadow-color, + + hover-background: $hover-background, + hover-foreground: $hover-foreground, + + focus-background: $focus-background, + focus-foreground: $focus-foreground, + + focus-hover-background: $focus-hover-background, + focus-hover-foreground: $focus-hover-foreground, + + active-background: $active-background, + active-foreground: $active-foreground, + + border-radius: $border-radius, + border-color: $border-color, + focus-border-color: $focus-border-color, + + disabled-background: $disabled-background, + disabled-foreground: $disabled-foreground, + disabled-border-color: $disabled-border-color, + size: $size, + )); +} diff --git a/projects/igniteui-angular/src/lib/core/styles/components/icon-button/_icon-button-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/icon-button/_icon-button-theme.scss index ad2ea91c001..f8f788b2214 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/icon-button/_icon-button-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/icon-button/_icon-button-theme.scss @@ -1,9 +1,14 @@ @use 'sass:map'; @use 'sass:meta'; +@use 'sass:list'; @use 'sass:color'; @use '../../base' as *; @use '../../themes/schemas' as *; +@forward './flat-icon-button-theme'; +@forward './contained-icon-button-theme'; +@forward './outlined-icon-button-theme'; + //// /// @group themes /// @access public @@ -57,37 +62,19 @@ } @if not($foreground) and $background { - $foreground: text-contrast($background); - } - - @if not($hover-background) and $background { - @if meta.type-of($background) == 'color' { - $hover-background: color.scale($background, $lightness: 5%); - } + $foreground: adaptive-contrast(var(--background)); } @if not($hover-foreground) and $hover-background { - @if meta.type-of($hover-background) == 'color' { - $hover-foreground: text-contrast($hover-background); - } - } - - @if not($focus-background) and $background { - $focus-background: color.scale($background, $lightness: 5%); + $hover-foreground: adaptive-contrast(var(--hover-background)); } @if not($focus-foreground) and $focus-background { - $focus-foreground: text-contrast($focus-background); - } - - @if not($focus-hover-background) and $background { - @if meta.type-of($background) == 'color' { - $focus-hover-background: color.scale($background, $lightness: 5%); - } + $focus-foreground: adaptive-contrast(var(--focus-background)); } @if not($focus-hover-foreground) and $focus-hover-background { - $focus-hover-foreground: text-contrast($focus-hover-background); + $focus-hover-foreground: adaptive-contrast(var(--focus-hover-background)); } $themes: map.merge($themes, ( @@ -117,7 +104,6 @@ disabled-foreground: $disabled-foreground, disabled-border-color: $disabled-border-color, size: $size, - theme: map.get($schema, '_meta', 'theme'), )) )); } @@ -132,15 +118,42 @@ /// @deprecated Use the `css-vars` mixin instead. /// @see {mixin} css-vars /// @param {Map} $theme - The theme used to style the component. -@mixin icon-button($theme) { - $variant: map.get($theme, variant); - $flat-theme: map.get(map.get($theme, 'themes'), 'flat'); - $outlined-theme: map.get(map.get($theme, 'themes'), 'outlined'); - $contained-theme: map.get(map.get($theme, 'themes'), 'contained'); - - @include css-vars($flat-theme); - @include css-vars($outlined-theme); - @include css-vars($contained-theme); +@mixin icon-button($themes...) { + $flat-theme: null; + $contained-theme: null; + $outlined-theme: null; + $variant: 'material'; + + $required: ('flat', 'contained', 'outlined'); + $added: (); + $missing: (); + + @each $key, $theme in meta.keywords($themes) { + $type: map.get($theme, _meta, type); + + $added: list.append($added, $key); + + @if $type == 'flat' { + $flat-theme: $theme; + } @else if $type == 'contained' { + $contained-theme: $theme; + } @else if $type == 'outlined' { + $outlined-theme: $theme; + } + + $variant: map.get($theme, '_meta', 'theme'); + @include css-vars($theme); + } + + @each $item in $required { + @if not(list.index($added, $item)) { + $missing: list.append($missing, '$#{$item}', $separator: comma); + } + } + + @if list.length($missing) != 0 { + @error meta.inspect(string.unquote("Missing theme properties:") #{$missing}); + } $icon-sizes: map.get(( 'material': rem(18px), diff --git a/projects/igniteui-angular/src/lib/core/styles/components/icon-button/_outlined-icon-button-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/icon-button/_outlined-icon-button-theme.scss new file mode 100644 index 00000000000..9ecc8857f99 --- /dev/null +++ b/projects/igniteui-angular/src/lib/core/styles/components/icon-button/_outlined-icon-button-theme.scss @@ -0,0 +1,232 @@ +@use 'sass:map'; +@use '../../base' as *; +@use '../../themes/schemas' as *; + +@function outlined-icon-button-theme( + $schema: $light-material-schema, + + $background: null, + $foreground: null, + $shadow-color: null, + + $hover-background: null, + $hover-foreground: null, + + $focus-background: null, + $focus-foreground: null, + + $focus-hover-background: null, + $focus-hover-foreground: null, + + $active-background: null, + $active-foreground: null, + + $border-radius: null, + $border-color: null, + $focus-border-color: null, + + $disabled-background: null, + $disabled-foreground: null, + $disabled-border-color: null, + + $size: null, +) { + $name: 'igx-outlined-icon-button'; + $icon-button-schema: (); + + @if map.has-key($schema, 'icon-button') { + $icon-button-schema: map.get($schema, 'icon-button'); + @if map.has-key($icon-button-schema, 'outlined') { + $icon-button-schema: map.get($icon-button-schema, 'outlined'); + } @else { + $icon-button-schema: $schema; + } + } + + $theme: digest-schema($icon-button-schema); + $variant: map.get($schema, '_meta', 'theme'); + + @if not($hover-foreground) and $hover-background { + $hover-foreground: adaptive-contrast(var(--hover-background)); + } + + @if not($focus-foreground) and $focus-background { + $focus-foreground: adaptive-contrast(var(--focus-background)); + } + + @if not($focus-hover-foreground) and $focus-hover-background { + $focus-hover-foreground: adaptive-contrast(var(--focus-hover-background)); + } + + @if not($active-foreground) and $active-background { + $active-foreground: adaptive-contrast(var(--active-background)); + } + + @if $variant == 'material' or $variant == 'fluent' { + @if not($hover-foreground) and $foreground { + $hover-foreground: var(--foreground); + } + + @if not($focus-foreground) and $foreground { + $focus-foreground: var(--foreground); + } + + @if not($focus-hover-foreground) and $foreground { + $focus-hover-foreground: var(--foreground); + } + + @if not($active-foreground) and $foreground { + $active-foreground: var(--foreground); + } + + @if not($hover-background) and $foreground { + $hover-background: hsla(from var(--foreground) h s l / 0.08); + } + + @if not($active-background) and $foreground { + $active-background: hsla(from var(--foreground) h s l / 0.24); + } + + @if $variant == 'material' { + @if not($focus-background) and $foreground { + $focus-background: hsla(from var(--foreground) h s l / 0.16); + } + + @if not($focus-hover-background) and $foreground { + $focus-hover-background: hsla(from var(--foreground) h s l / 0.24); + } + + @if not($border-color) and $foreground { + $border-color: hsla(from var(--foreground) h s l / 0.4); + } + } @else { + @if not($focus-hover-background) and $hover-background { + $focus-hover-background: var(--hover-background); + } + + @if not($focus-border-color) and $foreground { + $focus-border-color: var(--foreground); + } + + @if not($border-color) and $foreground { + $border-color: hsla(from var(--foreground) h s l / 0.7); + } + } + } + + @if $variant == 'indigo' { + @if not($border-color) and $foreground { + $border-color: hsla(from var(--foreground) h s l / 0.8); + } + + @if not($hover-foreground) and $foreground { + $hover-foreground: hsl(from var(--foreground) h s calc(l * 0.9)); + } + + @if not($hover-background) and $foreground { + $hover-background: hsla(from var(--foreground) h s l / 0.1); + } + + @if not($focus-foreground) and $foreground { + $focus-foreground: var(--foreground); + } + + @if not($focus-border-color) and $foreground { + $focus-border-color: hsla(from var(--foreground) h s l / 0.2); + } + + @if not($focus-hover-foreground) and $hover-foreground { + $focus-hover-foreground: var(--hover-foreground); + } + + @if not($active-foreground) and $hover-foreground { + $active-foreground: var(--hover-foreground); + } + } + + @if $variant == 'bootstrap' { + @if not($border-color) and $foreground { + $border-color: var(--foreground); + } + + @if not($hover-background) and $foreground { + $hover-background: var(--foreground); + } + + @if not($hover-foreground) and $hover-background { + $hover-foreground: adaptive-contrast(var(--hover-background)); + } + + @if not($focus-background) and $foreground { + $focus-background: var(--foreground); + } + + @if not($focus-foreground) and $focus-background { + $focus-foreground: adaptive-contrast(var(--focus-background)); + } + + @if not($focus-hover-background) and $focus-background { + $focus-hover-background: hsl(from var(--focus-background) h s calc(l * 0.9)); + } + + @if not($focus-hover-foreground) and $focus-hover-background { + $focus-hover-foreground: adaptive-contrast(var(--focus-hover-background)); + } + + @if not($active-background) and $foreground { + $active-background: hsl(from var(--foreground) h s calc(l * 0.8)); + } + + @if not($active-foreground) and $active-background { + $active-foreground: adaptive-contrast(var(--active-background)); + } + + @if not($focus-border-color) and $active-background { + $focus-border-color: var(--active-background); + } + + @if not($shadow-color) and $focus-background { + $shadow-color: hsla(from var(--focus-background) h s l / 0.5); + } + } + + @if $variant == 'bootstrap' or $variant == 'indigo' { + @if not($disabled-foreground) and $foreground { + $disabled-foreground: hsla(from var(--foreground) h s l / 0.5); + } + + @if not($disabled-border-color) and $border-color { + $disabled-border-color: hsla(from var(--border-color) h s l / 0.2); + } + } + + @return extend( + $theme, + ( + name: $name, + background: $background, + foreground: $foreground, + shadow-color: $shadow-color, + + hover-background: $hover-background, + hover-foreground: $hover-foreground, + + focus-background: $focus-background, + focus-foreground: $focus-foreground, + + focus-hover-background: $focus-hover-background, + focus-hover-foreground: $focus-hover-foreground, + + active-background: $active-background, + active-foreground: $active-foreground, + + border-radius: $border-radius, + border-color: $border-color, + focus-border-color: $focus-border-color, + + disabled-background: $disabled-background, + disabled-foreground: $disabled-foreground, + disabled-border-color: $disabled-border-color, + size: $size, + )); +} diff --git a/projects/igniteui-angular/src/lib/core/styles/components/icon/_icon-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/icon/_icon-theme.scss index e2b5249ac41..a70edbc4dd4 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/icon/_icon-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/icon/_icon-theme.scss @@ -41,7 +41,6 @@ color: $color, size: $size, disabled-color: $disabled-color, - theme: map.get($schema, '_meta', 'theme'), )); } diff --git a/projects/igniteui-angular/src/lib/core/styles/components/input/_input-group-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/input/_input-group-theme.scss index 7c301ffee81..a716c1b2434 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/input/_input-group-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/input/_input-group-theme.scss @@ -139,24 +139,247 @@ } $theme: digest-schema($input-group-schema); + $variant: map.get($theme, '_meta', 'theme'); + $search-resting-elevation: map.get($input-group-schema, 'search-resting-elevation'); $search-hover-elevation: map.get($input-group-schema, 'search-hover-elevation'); $search-disabled-elevation: map.get($input-group-schema, 'search-disabled-elevation'); - @if not($placeholder-color) and $box-background { - $placeholder-color: text-contrast($box-background); + @if $variant == 'material' { + @if not($box-background-hover) and $box-background { + $box-background-hover: var(--box-background); + } + + @if not($box-background-focus) and $box-background { + $box-background-focus: hsl(from var(--box-background) h s calc(l * 0.9)); + } + + @if not($placeholder-color) and $box-background { + $placeholder-color: hsla(from adaptive-contrast(var(--box-background)) h s l / 0.9); + } + + @if not($hover-placeholder-color) and $box-background-hover { + $hover-placeholder-color: hsla(from adaptive-contrast(var(--box-background-hover)) h s l / 0.9); + } + + @if not($idle-text-color) and $box-background { + $idle-text-color: adaptive-contrast(var(--box-background)); + } + + @if not($filled-text-color) and $box-background { + $filled-text-color: adaptive-contrast(var(--box-background)); + } + + @if not($filled-text-hover-color) and $box-background { + $filled-text-hover-color: adaptive-contrast(var(--box-background)); + } + + @if not($focused-text-color) and $box-background-focus { + $focused-text-color: adaptive-contrast(var(--box-background-focus)); + } + + @if not($idle-secondary-color) and $box-background { + $idle-secondary-color: hsla(from adaptive-contrast(var(--box-background)) h s l / 0.9); + } + + @if not($input-prefix-color) and $box-background { + $input-prefix-color: hsla(from adaptive-contrast(var(--box-background)) h s l / 0.9); + } + + @if not($input-prefix-color--filled) and $box-background { + $input-prefix-color--filled: adaptive-contrast(var(--box-background)); + } + + @if not($input-prefix-color--focused) and $box-background-focus { + $input-prefix-color--focused: adaptive-contrast(var(--box-background-focus)); + } + + @if not($input-suffix-color) and $box-background { + $input-suffix-color: hsla(from adaptive-contrast(var(--box-background)) h s l / 0.9); + } + + @if not($input-suffix-color--filled) and $box-background { + $input-suffix-color--filled: adaptive-contrast(var(--box-background)); + } + + @if not($input-suffix-color--focused) and $box-background-focus { + $input-suffix-color--focused: adaptive-contrast(var(--box-background-focus)); + } + + @if $box-background != transparent { + @if not($box-disabled-background) and $box-background { + $box-disabled-background: hsla(from var(--box-background) h s l / 0.4); + } + + @if not($disabled-placeholder-color) and $box-disabled-background { + $disabled-placeholder-color: adaptive-contrast(var(--box-disabled-background)); + } + + @if not($disabled-text-color) and $box-disabled-background { + $disabled-text-color: adaptive-contrast(var(--box-disabled-background)); + } + } @else { + @if not($box-disabled-background) and $box-background { + $box-disabled-background: var(--box-background); + } + + @if not($disabled-placeholder-color) and $placeholder-color { + $disabled-placeholder-color: hsla(from var(--placeholder-color) h s l / 0.7); + } + + @if not($disabled-text-color) and $idle-text-color { + $disabled-text-color: hsla(from var(--idle-text-color) h s l / 0.7); + } + } + } + + @if $variant == 'fluent' or $variant == 'bootstrap' { + @if not($input-prefix-background) and $input-suffix-background { + $input-prefix-background: var(--input-suffix-background); + } + + @if not($input-suffix-background) and $input-prefix-background { + $input-suffix-background: var(--input-prefix-background); + } } - @if not($placeholder-color) and $box-background-hover { - $placeholder-color: text-contrast($box-background-hover); + @if $variant == 'material' or $variant == 'indigo' { + //bottom line color + @if not($hover-bottom-line-color) and $idle-bottom-line-color { + $hover-bottom-line-color: hsl(from var(--idle-bottom-line-color) h s calc(l * 0.8)); + } + + @if not($focused-bottom-line-color) and $hover-bottom-line-color { + $focused-bottom-line-color: var(--hover-bottom-line-color); + } + + @if $variant == 'material' { + @if not($focused-secondary-color) and $focused-bottom-line-color { + $focused-secondary-color: var(--focused-bottom-line-color); + } + + @if not($border-color) and $idle-bottom-line-color { + $border-color: var(--idle-bottom-line-color); + } + } + } + + //border-color + @if $variant == 'bootstrap' { + @if not($focused-border-color) and $border-color { + $focused-border-color: hsl(from var(--border-color) h s calc(l * 0.8)); + } + + @if not($focused-secondary-color) and $focused-border-color { + $focused-secondary-color: hsla(from var(--focused-border-color) h s l / 0.4); + } + } @else { + @if not($hover-border-color) and $border-color { + $hover-border-color: hsl(from var(--border-color) h s calc(l * 0.8)); + } + + @if not($focused-border-color) and $hover-border-color { + $focused-border-color: var(--hover-border-color); + } + + @if $variant != 'indigo' { + @if not($focused-secondary-color) and $focused-border-color { + $focused-secondary-color: var(--focused-border-color); + } + } } - @if not($placeholder-color) and $box-background-focus { - $placeholder-color: text-contrast($box-background-focus); + @if $variant == 'material' { + @if not($focused-bottom-line-color) and $focused-border-color { + $focused-bottom-line-color: var(--focused-border-color); + } } + //search input @if not($placeholder-color) and $search-background { - $placeholder-color: text-contrast($search-background); + $placeholder-color: hsla(from adaptive-contrast(var(--search-background)) h s l / 0.9); + } + + @if not($hover-placeholder-color) and $placeholder-color { + $hover-placeholder-color: var(--placeholder-color); + } + + @if $variant == 'indigo' { + @if not($box-background-hover) and $search-background { + $box-background-hover: var(--search-background); + } + } @else { + @if not($idle-secondary-color) and $placeholder-color { + $idle-secondary-color: var(--placeholder-color); + } + } + + @if not($idle-text-color) and $search-background { + $idle-text-color: adaptive-contrast(var(--search-background)); + } + + @if not($filled-text-color) and $search-background { + $filled-text-color: adaptive-contrast(var(--search-background)); + } + + @if not($filled-text-hover-color) and $search-background { + $filled-text-hover-color: adaptive-contrast(var(--search-background)); + } + + @if not($focused-text-color) and $search-background { + $focused-text-color: adaptive-contrast(var(--search-background)); + } + + @if not($input-prefix-color) and $search-background { + $input-prefix-color: hsla(from adaptive-contrast(var(--search-background)) h s l / 0.9); + } + + @if not($input-suffix-color) and $search-background { + $input-suffix-color: hsla(from adaptive-contrast(var(--search-background)) h s l / 0.9); + } + + @if $variant != 'indigo' { + @if not($input-prefix-color--filled) and $search-background { + $input-prefix-color--filled: adaptive-contrast(var(--search-background)); + } + + @if not($input-prefix-color--focused) and $search-background { + $input-prefix-color--focused: adaptive-contrast(var(--search-background)); + } + + @if not($input-suffix-color--filled) and $search-background { + $input-suffix-color--filled: adaptive-contrast(var(--search-background)); + } + + @if not($input-suffix-color--focused) and $search-background { + $input-suffix-color--focused: adaptive-contrast(var(--search-background)); + } + } + + @if $search-background != transparent { + @if not($search-disabled-background) and $search-background { + $search-disabled-background: hsla(from var(--search-background) h s l / 0.4); + } + + @if not($disabled-placeholder-color) and $search-disabled-background { + $disabled-placeholder-color: adaptive-contrast(var(--search-disabled-background)); + } + + @if not($disabled-text-color) and $search-disabled-background { + $disabled-text-color: adaptive-contrast(var(--search-disabled-background)); + } + } @else { + @if not($search-disabled-background) and $search-background { + $search-disabled-background: var(--search-background); + } + + @if not($disabled-placeholder-color) and $placeholder-color { + $disabled-placeholder-color: hsla(from var(--placeholder-color) h s l / 0.7); + } + + @if not($disabled-text-color) and $idle-text-color { + $disabled-text-color: hsla(from var(--idle-text-color) h s l / 0.7); + } } @if not($search-resting-shadow) { @@ -170,37 +393,70 @@ @if not($search-disabled-shadow) { $search-disabled-shadow: elevation($search-disabled-elevation); } + //end search input + + @if not($input-prefix-color) and $input-suffix-color { + $input-prefix-color: var(--input-suffix-color); + } + + @if not($input-suffix-color) and $input-prefix-color { + $input-suffix-color: var(--input-prefix-color); + } @if not($input-prefix-background--filled) and $input-prefix-background { - $input-prefix-background--filled: $input-prefix-background; + $input-prefix-background--filled: var(--input-prefix-background); } @if not($input-prefix-background--focused) and $input-prefix-background { - $input-prefix-background--focused: $input-prefix-background; + $input-prefix-background--focused: var(--input-prefix-background); } @if not($input-prefix-color) and $input-prefix-background { - $input-prefix-color: text-contrast($input-prefix-background); + $input-prefix-color: adaptive-contrast(var(--input-prefix-background)); + } + + @if not($input-prefix-color--filled) and $input-prefix-color { + $input-prefix-color--filled: var(--input-prefix-color); + } + + @if not($input-prefix-color--focused) and $input-prefix-color--filled { + $input-prefix-color--focused: var(--input-prefix-color--filled); } @if not($input-prefix-color--filled) and $input-prefix-background--filled { - $input-prefix-color--filled: text-contrast($input-prefix-background--filled); + $input-prefix-color--filled: adaptive-contrast(var(--input-prefix-background--filled)); } @if not($input-prefix-color--focused) and $input-prefix-background--focused { - $input-prefix-color--focused: text-contrast($input-prefix-background--focused); + $input-prefix-color--focused: adaptive-contrast(var(--input-prefix-background--focused)); + } + + @if not($input-suffix-background--filled) and $input-suffix-background { + $input-suffix-background--filled: var(--input-suffix-background); + } + + @if not($input-suffix-background--focused) and $input-suffix-background { + $input-suffix-background--focused: var(--input-suffix-background); } @if not($input-suffix-color) and $input-suffix-background { - $input-suffix-color: text-contrast($input-suffix-background); + $input-suffix-color: adaptive-contrast(var(--input-suffix-background)); + } + + @if not($input-suffix-color--filled) and $input-suffix-color { + $input-suffix-color--filled: var(--input-suffix-color); + } + + @if not($input-suffix-color--focused) and $input-suffix-color--filled { + $input-suffix-color--focused: var(--input-suffix-color--filled); } @if not($input-suffix-color--filled) and $input-suffix-background--filled { - $input-suffix-color--filled: text-contrast($input-suffix-background--filled); + $input-suffix-color--filled: adaptive-contrast(var(--input-suffix-background--filled)); } @if not($input-suffix-color--focused) and $input-suffix-background--focused { - $input-suffix-color--focused: text-contrast($input-suffix-background--focused); + $input-suffix-color--focused: adaptive-contrast(var(--input-suffix-background--focused)); } @if not($box-border-radius) { @@ -268,8 +524,6 @@ input-suffix-background--filled: $input-suffix-background--filled, input-suffix-color--focused: $input-suffix-color--focused, input-suffix-background--focused: $input-suffix-background--focused, - theme: map.get($schema, '_meta', 'theme'), - variant: map.get($schema, '_meta', 'theme'), size: $size, )); } @@ -282,7 +536,7 @@ // when dynamically switching between the input `type` attribute. @include css-vars($theme); - $variant: map.get($theme, 'variant'); + $variant: map.get($theme, '_meta', 'theme'); $transition-timing: .25s $out-cubic; $material-theme: $variant == 'material'; $indigo-theme: $variant == 'indigo'; diff --git a/projects/igniteui-angular/src/lib/core/styles/components/label/_label-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/label/_label-theme.scss index ddd9e5dede5..e43cdf6fba2 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/label/_label-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/label/_label-theme.scss @@ -33,9 +33,7 @@ name: $name, selector: $selector, color: $color, - disabled-color: $disabled-color, - theme: map.get($schema, '_meta', 'theme'), - variant: map.get($schema, '_meta', 'theme'), + disabled-color: $disabled-color )); } @@ -46,7 +44,7 @@ // The --variant CSS produced by css-vars is needed also // when dynamically switching between the input `type` attribute. @include css-vars($theme); - $variant: map.get($theme, 'variant'); + $variant: map.get($theme, '_meta', 'theme'); %label-base { @include ellipsis(); diff --git a/projects/igniteui-angular/src/lib/core/styles/components/list/_list-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/list/_list-theme.scss index ee2f3119d64..e74b152efc6 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/list/_list-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/list/_list-theme.scss @@ -94,160 +94,140 @@ } $theme: digest-schema($list-schema); - $meta: map.get($theme, '_meta'); + $variant: map.get($theme, '_meta', 'theme'); @if not($header-background) and $background { - $header-background: $background; + $header-background: var(--background); } @if not($header-background) and $item-background { - $header-background: $item-background; + $header-background: var(--item-background); } @if not($item-background) and $background { - $item-background: $background; + $item-background: var(--background); } @if not($background) and $item-background { - $background: $item-background; + $background: var(--item-background); } @if not($item-background-hover) and $item-background { - @if meta.type-of($item-background) == 'color' { - @if luminance($item-background) < .5 { - $item-background-hover: color.scale($item-background, $lightness: 8%); - } @else { - $item-background-hover: color.scale($item-background, $lightness: -8%); - } - } + $item-background-hover: hsl(from var(--item-background) h s calc(l * 0.9)); } - @if not($item-background-active) and $item-background { - @if meta.type-of($item-background) == 'color' { - @if luminance($item-background) < .5 { - $item-background-active: color.scale($item-background, $lightness: 8%); - } @else { - $item-background-active: color.scale($item-background, $lightness: -8%); - } - } + @if not($item-background-active) and $item-background-hover { + $item-background-active: var(--item-background-hover); } - @if not($item-background-selected) and $item-background { - @if meta.type-of($item-background) == 'color' { - @if luminance($item-background) < .5 { - $item-background-selected: color.scale($item-background, $lightness: 8%); - } @else { - $item-background-selected: color.scale($item-background, $lightness: -8%); - } - } + @if not($item-background-selected) and $item-background-active { + $item-background-selected: var(--item-background-active); } @if not($header-text-color) and $header-background { - $header-text-color: text-contrast($header-background); + $header-text-color: adaptive-contrast(var(--header-background)); } @if not($item-text-color) and $item-background { - $item-text-color: text-contrast($item-background); + $item-text-color: adaptive-contrast(var(--item-background)); } @if not($item-title-color) and $item-background { - $item-title-color: text-contrast($item-background); + $item-title-color: adaptive-contrast(var(--item-background)); } @if not($item-action-color) and $item-background { - $item-action-color: text-contrast($item-background); + $item-action-color: adaptive-contrast(var(--item-background)); } @if not($item-thumbnail-color) and $item-background { - $item-thumbnail-color: text-contrast($item-background); + $item-thumbnail-color: adaptive-contrast(var(--item-background)); } @if not($item-subtitle-color) and $item-background { - @if meta.type-of($item-background) == 'color' { - $item-subtitle-color: rgba(text-contrast($item-background), .74); - } + $item-subtitle-color: hsla(from adaptive-contrast(var(--item-background)) h s l / .74); } @if not($item-subtitle-color) and $item-text-color { - $item-subtitle-color: $item-text-color; + $item-subtitle-color: var(--item-text-color); } @if not($item-text-color-hover) and $item-background-hover { - $item-text-color-hover: text-contrast($item-background-hover); + $item-text-color-hover: adaptive-contrast(var(--item-background-hover)); } @if not($item-title-color-hover) and $item-background-hover { - $item-title-color-hover: text-contrast($item-background-hover); + $item-title-color-hover: adaptive-contrast(var(--item-background-hover)); } @if not($item-action-color-hover) and $item-background-hover { - $item-action-color-hover: text-contrast($item-background-hover); + $item-action-color-hover: adaptive-contrast(var(--item-background-hover)); } @if not($item-thumbnail-color-hover) and $item-background-hover { - $item-thumbnail-color-hover: text-contrast($item-background-hover); + $item-thumbnail-color-hover: adaptive-contrast(var(--item-background-hover)); } @if not($item-subtitle-color-hover) and $item-background-hover { - @if meta.type-of($item-background-hover) == 'color' { - $item-subtitle-color-hover: rgba(text-contrast($item-background-hover), .74); - } + $item-subtitle-color-hover: hsla(from adaptive-contrast(var(--item-background-hover)) h s l / .74); } @if not($item-subtitle-color-hover) and $item-text-color-hover { - $item-subtitle-color-hover: $item-text-color-hover; + $item-subtitle-color-hover: var(--item-text-color-hover); } @if not($item-text-color-active) and $item-background-active { - $item-text-color-active: text-contrast($item-background-active); + $item-text-color-active: adaptive-contrast(var(--item-background-active)); } @if not($item-text-color-selected) and $item-background-selected { - $item-text-color-selected: text-contrast($item-background-selected); + $item-text-color-selected: adaptive-contrast(var(--item-background-selected)); } @if not($item-title-color-active) and $item-background-active { - $item-title-color-active: text-contrast($item-background-active); + $item-title-color-active: adaptive-contrast(var(--item-background-active)); } @if not($item-title-color-selected) and $item-background-selected { - $item-title-color-selected: text-contrast($item-background-selected); + $item-title-color-selected: adaptive-contrast(var(--item-background-selected)); } @if not($item-action-color-active) and $item-background-active { - $item-action-color-active: text-contrast($item-background-active); + $item-action-color-active: adaptive-contrast(var(--item-background-active)); } @if not($item-action-color-selected) and $item-background-selected { - $item-action-color-selected: text-contrast($item-background-selected); + $item-action-color-selected: adaptive-contrast(var(--item-background-selected)); } @if not($item-thumbnail-color-active) and $item-background-active { - $item-thumbnail-color-active: text-contrast($item-background-active); + $item-thumbnail-color-active: adaptive-contrast(var(--item-background-active)); } @if not($item-thumbnail-color-selected) and $item-background-selected { - $item-thumbnail-color-selected: text-contrast($item-background-selected); + $item-thumbnail-color-selected: adaptive-contrast(var(--item-background-selected)); } @if not($item-subtitle-color-active) and $item-background-active { - @if meta.type-of($item-background-active) == 'color' { - $item-subtitle-color-active: rgba(text-contrast($item-background-active), .74); - } + $item-subtitle-color-active: hsla(from adaptive-contrast(var(--item-background-active)) h s l / .74); } @if not($item-subtitle-color-selected) and $item-background-selected { - @if meta.type-of($item-background-selected) == 'color' { - $item-subtitle-color-selected: rgba(text-contrast($item-background-selected), .74); - } + $item-subtitle-color-selected: hsla(from adaptive-contrast(var(--item-background-selected)) h s l / .74); } @if not($item-subtitle-color-active) and $item-text-color-active { - $item-subtitle-color-active: $item-text-color-active; + $item-subtitle-color-active: var(--item-text-color-active); } @if not($item-subtitle-color-selected) and $item-text-color-selected { - $item-subtitle-color-selected: $item-text-color-selected; + $item-subtitle-color-selected: var(--item-text-color-selected); + } + + @if $variant == 'fluent' or $variant == 'bootstrap'{ + @if not($border-color) and $item-background { + $border-color: hsla(from adaptive-contrast(var(--item-background)) h s l / .15); + } } @return extend($theme, ( @@ -283,10 +263,6 @@ item-thumbnail-color-selected: $item-thumbnail-color-selected, border-color: $border-color, border-width: $border-width, - theme: map.get($schema, '_meta', 'theme'), - _meta: map.merge(if($meta, $meta, ()), ( - variant: map.get($schema, '_meta', 'theme') - )), )); } @@ -296,7 +272,7 @@ @mixin list($theme) { @include css-vars($theme); - $variant: map.get($theme, '_meta', 'variant'); + $variant: map.get($theme, '_meta', 'theme'); $bootstrap-theme: $variant == 'bootstrap'; $theme-padding-block-l: map.get(( diff --git a/projects/igniteui-angular/src/lib/core/styles/components/navbar/_navbar-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/navbar/_navbar-theme.scss index 0b2cb70cb10..adef165709e 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/navbar/_navbar-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/navbar/_navbar-theme.scss @@ -43,18 +43,32 @@ } $theme: digest-schema($navbar-schema); - $meta: map.get($theme, '_meta'); + $variant: map.get($theme, '_meta', 'theme'); @if not($text-color) and $background { - $text-color: text-contrast($background); + $text-color: adaptive-contrast(var(--background)); + } + + @if not($hover-icon-color) and $idle-icon-color { + $hover-icon-color: hsl(from (var(--idle-icon-color)) h s calc(l * 1.1)); } @if not($idle-icon-color) and $background { - $idle-icon-color: text-contrast($background); + $idle-icon-color: adaptive-contrast(var(--background)); } - @if not($hover-icon-color) and $background { - $hover-icon-color: text-contrast($background); + @if $variant == 'indigo' { + @if not($border-color) and $background { + $border-color: hsla(from adaptive-contrast(var(--background)) h s l / 0.3); + } + + @if not($hover-icon-color) and $background { + $hover-icon-color: hsla(from adaptive-contrast(var(--background)) h s l / 0.7); + } + } @else { + @if not($hover-icon-color) and $background { + $hover-icon-color: adaptive-contrast(var(--background)); + } } @if not($shadow) { @@ -74,10 +88,6 @@ idle-icon-color: $idle-icon-color, hover-icon-color: $hover-icon-color, shadow: $shadow, - theme: map.get($schema, '_meta', 'theme'), - _meta: map.merge(if($meta, $meta, ()), ( - variant: map.get($schema, '_meta', 'theme') - )), )); } @@ -86,7 +96,7 @@ /// @param {Map} $theme - The theme used to style the component. @mixin navbar($theme) { @include css-vars($theme); - $variant: map.get($theme, '_meta', 'variant'); + $variant: map.get($theme, '_meta', 'theme'); $navbar-padding: rem(16px); $navbar-title-fz: rem(18px, 16px); @@ -194,19 +204,19 @@ igx-icon, igc-icon { --component-size: 3; + cursor: pointer; + user-select: none; + transition: color .15s $out-quad; } - > igx-icon, - > igc-icon { - transition: color .15s $out-quad; + >igx-icon, + >igc-icon { color: var-get($theme, 'idle-icon-color'); &:hover { color: var-get($theme, 'hover-icon-color'); } - - user-select: none; } @if $variant == 'indigo' { diff --git a/projects/igniteui-angular/src/lib/core/styles/components/navdrawer/_navdrawer-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/navdrawer/_navdrawer-theme.scss index 69f4ef7e25d..e9a91d6658f 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/navdrawer/_navdrawer-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/navdrawer/_navdrawer-theme.scss @@ -73,42 +73,48 @@ } $theme: digest-schema($navdrawer-schema); - $meta: map.get($theme, '_meta'); @if not($item-header-text-color) and $background { - $item-header-text-color: text-contrast($background); + $item-header-text-color: adaptive-contrast(var(--background)); } @if not($item-text-color) and $background { - $item-text-color: text-contrast($background); + $item-text-color: adaptive-contrast(var(--background)); } @if not($item-icon-color) and $background { - $item-icon-color: text-contrast($background); + $item-icon-color: adaptive-contrast(var(--background)); + } + + @if not($item-hover-background) and $background { + $item-hover-background: hsla(from adaptive-contrast(var(--background)) h s l / .08); + } + + @if not($item-hover-text-color) and $background { + $item-hover-text-color: adaptive-contrast(var(--background)); + } + + @if not($item-hover-icon-color) and $background { + $item-hover-icon-color: adaptive-contrast(var(--background)); } @if not($item-active-background) and $background { - @if meta.type-of($background) == 'color' { - $item-active-background: rgba(text-contrast($background), .24); - } + $item-active-background: hsla(from adaptive-contrast(var(--background)) h s l / .24); } @if not($item-active-text-color) and $item-active-background { - $item-active-text-color: text-contrast($item-active-background); + $item-active-text-color: adaptive-contrast(var(--item-active-background)); } @if not($item-active-icon-color) and $item-active-background { - $item-active-icon-color: text-contrast($item-active-background); + $item-active-icon-color: adaptive-contrast(var(--item-active-background)); } - @if not($item-hover-background) and $background { - @if meta.type-of($background) == 'color' { - $item-hover-background: rgba(text-contrast($background), .08); - } + @if not($item-disabled-text-color) and $background { + $item-disabled-text-color: hsla(from adaptive-contrast(var(--background)) h s l / .38); } - - @if not($item-hover-text-color) and $background { - $item-hover-text-color: text-contrast($background); + @if not($item-disabled-icon-color) and $background { + $item-disabled-icon-color: hsla(from adaptive-contrast(var(--background)) h s l / .38); } @if not($shadow) { @@ -133,11 +139,7 @@ item-hover-icon-color: $item-hover-icon-color, item-disabled-text-color:$item-disabled-text-color, item-disabled-icon-color: $item-disabled-icon-color, - shadow: $shadow, - theme: map.get($schema, '_meta', 'theme'), - _meta: map.merge(if($meta, $meta, ()), ( - variant: map.get($schema, '_meta', 'theme') - )), + shadow: $shadow )); } @@ -147,7 +149,7 @@ @mixin navdrawer($theme) { @include css-vars($theme); - $variant: map.get($theme, '_meta', 'variant'); + $variant: map.get($theme, '_meta', 'theme'); $drawer-icon-size: rem(24px); $aside-padding: map.get(( diff --git a/projects/igniteui-angular/src/lib/core/styles/components/overlay/_overlay-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/overlay/_overlay-theme.scss index 68c4d19e3ae..45034ddb62c 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/overlay/_overlay-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/overlay/_overlay-theme.scss @@ -37,7 +37,6 @@ name: $name, selector: $selector, background-color: $background-color, - theme: map.get($schema, '_meta', 'theme'), )); } diff --git a/projects/igniteui-angular/src/lib/core/styles/components/paginator/_paginator-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/paginator/_paginator-theme.scss index 1e4883f8678..14130e74bbc 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/paginator/_paginator-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/paginator/_paginator-theme.scss @@ -38,10 +38,9 @@ } $theme: digest-schema($grid-paginator-schema); - $meta: map.get($theme, '_meta'); @if not($text-color) and $background-color { - $text-color: text-contrast($background-color); + $text-color: adaptive-contrast($background-color); } @return extend($theme, ( @@ -49,10 +48,6 @@ text-color: $text-color, background-color: $background-color, border-color: $border-color, - theme: map.get($schema, '_meta', 'theme'), - _meta: map.merge(if($meta, $meta, ()), ( - variant: map.get($schema, '_meta', 'theme') - )), )); } @@ -62,7 +57,7 @@ @mixin paginator($theme) { @include css-vars($theme); - $variant: map.get($theme, '_meta', 'variant'); + $variant: map.get($theme, '_meta', 'theme'); $paginator-padding-inline: ( comfortable: rem(24px), diff --git a/projects/igniteui-angular/src/lib/core/styles/components/progress/circular/_circular-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/progress/circular/_circular-theme.scss index 8c0512966e6..d2486da8ee3 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/progress/circular/_circular-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/progress/circular/_circular-theme.scss @@ -46,7 +46,6 @@ } $theme: digest-schema($circular-bar-schema); - $meta: map.get($theme, '_meta'); $fill-color-default-start: map.get($theme, 'fill-color-default'); $fill-color-default-end: map.get($theme, 'fill-color-default'); @@ -73,10 +72,6 @@ fill-color-success: $fill-color-success, text-color: $text-color, diameter: $diameter, - theme: map.get($schema, '_meta', 'theme'), - _meta: map.merge(if($meta, $meta, ()), ( - variant: map.get($schema, '_meta', 'theme') - )), )); } @@ -94,7 +89,7 @@ $diameter: calc(var(--circular-size) + var(--stroke-thickness)); $radius: calc(var(--circular-size) / 2 - var(--stroke-thickness) * .5); $circumference: calc(#{$radius} * 2 * 3.1416); - $variant: map.get($theme, '_meta', 'variant'); + $variant: map.get($theme, '_meta', 'theme'); %display-circular { --circular-size: calc(#{var-get($theme, 'diameter')} - var(--stroke-thickness)); @@ -136,7 +131,7 @@ %outer { stroke: var-get($theme, 'fill-color-default'); - + @if $variant != 'bootstrap' { animation: igx-initial-dashoffset var(--_transition-duration) linear; } @else { @@ -313,7 +308,7 @@ %text--hidden { visibility: hidden; } - + %gradient-start { stop-color: var-get($theme, 'fill-color-default-end'); } diff --git a/projects/igniteui-angular/src/lib/core/styles/components/progress/linear/_linear-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/progress/linear/_linear-theme.scss index c4d3cfa10ec..fb381552206 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/progress/linear/_linear-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/progress/linear/_linear-theme.scss @@ -52,7 +52,6 @@ $linear-bar-schema: if(map.has-key($schema, 'linear-bar'), map.get($schema, 'linear-bar'), $schema); $theme: digest-schema($linear-bar-schema); - $meta: map.get($theme, '_meta'); @if not($track-border-radius) { $track-border-radius: map.get($theme, 'track-border-radius'); @@ -71,10 +70,6 @@ track-border-radius: $track-border-radius, track-height: $track-height, strip-size: $strip-size, - theme: map.get($schema, '_meta', 'theme'), - _meta: map.merge(if($meta, $meta, ()), ( - variant: map.get($schema, '_meta', 'theme') - )), )); } @@ -127,7 +122,7 @@ $easing-curves: ( @mixin progress-linear($theme) { @include css-vars($theme); - $variant: map.get($theme, '_meta', 'variant'); + $variant: map.get($theme, '_meta', 'theme'); %display-linear { position: relative; diff --git a/projects/igniteui-angular/src/lib/core/styles/components/query-builder/_query-builder-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/query-builder/_query-builder-theme.scss index e1d2cafd988..63c4d7aa15b 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/query-builder/_query-builder-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/query-builder/_query-builder-theme.scss @@ -52,14 +52,36 @@ } $theme: digest-schema($query-builder-schema); - $meta: map.get($theme, '_meta'); + $variant: map.get($theme, '_meta', 'theme'); - @if not($header-foreground) and $header-background { - $header-foreground: text-contrast($header-background); + @if not($label-foreground) and $background { + $label-foreground: hsla(from adaptive-contrast(var(--background)) h s l / 0.6); } @if not($header-background) and $background { - $header-background: $background; + $header-background: var(--background); + } + + @if not($header-foreground) and $header-background { + $header-foreground: adaptive-contrast(var(--header-background)); + } + + @if not($subquery-header-background) and $header-background { + $subquery-header-background: hsl(from var(--header-background) h s calc(l * 0.9)); + } + + @if not($subquery-border-color) and $subquery-header-background { + $subquery-border-color: hsl(from var(--subquery-header-background) h s calc(l * 0.9)); + } + + @if not($separator-color) and $subquery-border-color { + $separator-color: hsl(from var(--subquery-border-color) h s calc(l * 0.9)); + } + + @if $variant == 'bootstrap' { + @if not($header-border) and $subquery-border-color { + $header-border: var(--subquery-border-color); + } } @return extend($theme, ( @@ -77,11 +99,6 @@ separator-color: $separator-color, border-radius: $border-radius, label-foreground: $label-foreground, - theme: map.get($schema, '_meta', 'theme'), - _meta: map.merge(if($meta, $meta, ()), ( - variant: map.get($schema, '_meta', 'theme'), - theme-variant: map.get($schema, '_meta', 'variant') - )), )); } @@ -98,8 +115,8 @@ @mixin query-builder($theme) { @include css-vars($theme); - $variant: map.get($theme, '_meta', 'variant'); - $theme-variant: map.get($theme, '_meta', 'theme-variant'); + $variant: map.get($theme, '_meta', 'theme'); + $theme-variant: map.get($theme, '_meta', 'variant'); $bootstrap-theme: $variant == 'bootstrap'; $not-bootstrap-theme: not($bootstrap-theme); diff --git a/projects/igniteui-angular/src/lib/core/styles/components/radio/_radio-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/radio/_radio-theme.scss index 20db6a0ea35..522fbb0de5f 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/radio/_radio-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/radio/_radio-theme.scss @@ -24,6 +24,7 @@ /// @param {Color} $hover-color [null] - The border and dot colors on hover. /// @param {Color} $fill-color-hover [null] - The checked dot color on hover. /// @param {Color} $fill-hover-border-color [null] - The checked border color on hover. +/// @param {Color} $focus-border-color [null] - The focus border color. /// @param {Color} $focus-outline-color [null] - The focus outlined color. /// @param {Color} $focus-outline-color-filled [null] - The focus outline color when radio is filled. /// @param {Color} $error-color [null] - The label, border and dot color in invalid state. @@ -46,6 +47,7 @@ $empty-fill-color: null, $fill-color: null, $fill-hover-border-color: null, + $focus-border-color: null, $focus-outline-color: null, $focus-outline-color-filled: null, $disabled-color: null, @@ -67,7 +69,53 @@ } $theme: digest-schema($radio-schema); - $meta: map.get($theme, '_meta'); + $variant: map.get($theme, '_meta', 'theme'); + + @if not($hover-color) and $empty-color { + $hover-color: hsl(from var(--empty-color) h s calc(l * 0.9)); + } + + @if not($fill-color-hover) and $fill-color { + $fill-color-hover: hsl(from var(--fill-color) h s calc(l * 0.9)); + } + + @if $variant != 'bootstrap' { + @if not($fill-hover-border-color) and $fill-color-hover { + $fill-hover-border-color: var(--fill-color-hover); + } + } + + @if not($label-color-hover) and $label-color { + $label-color-hover: hsl(from var(--label-color) h s calc(l * 0.9)); + } + + @if not($error-color-hover) and $error-color { + $error-color-hover: hsl(from var(--error-color) h s calc(l * 0.9)); + } + + @if not($focus-outline-color-error) and $error-color { + $focus-outline-color-error: hsla(from var(--error-color) h s l / .5); + } + + @if $variant == 'bootstrap' { + @if not($focus-border-color) and $fill-color { + $focus-border-color: var(--fill-color); + } + + @if not($focus-outline-color) and $fill-color { + $focus-outline-color: hsla(from var(--fill-color) h s l / .5); + } + } + + @if $variant == 'indigo' { + @if not($focus-outline-color) and $empty-color { + $focus-outline-color: hsla(from var(--empty-color) h s l / .5); + } + + @if not($focus-outline-color-filled) and $fill-color { + $focus-outline-color-filled: hsla(from var(--fill-color) h s l / .5); + } + } @return extend($theme, ( name: $name, @@ -82,16 +130,12 @@ disabled-fill-color: $disabled-fill-color, hover-color: $hover-color, fill-color-hover: $fill-color-hover, + focus-border-color: $focus-border-color, focus-outline-color: $focus-outline-color, focus-outline-color-filled: $focus-outline-color-filled, error-color: $error-color, error-color-hover: $error-color-hover, focus-outline-color-error: $focus-outline-color-error, - theme: map.get($schema, '_meta', 'theme'), - _meta: map.merge(if($meta, $meta, ()), ( - variant: map.get($schema, '_meta', 'theme'), - theme-variant: map.get($schema, '_meta', 'variant') - )), )); } @@ -102,8 +146,8 @@ @include css-vars($theme); @include scale-in-out($start-scale: .9); - $theme-variant: map.get($theme, '_meta', 'theme-variant'); - $variant: map.get($theme, '_meta', 'variant'); + $theme-variant: map.get($theme, '_meta', 'variant'); + $variant: map.get($theme, '_meta', 'theme'); $material-theme: $variant == 'material'; $bootstrap-theme: $variant == 'bootstrap'; $not-bootstrap-theme: $variant != 'bootstrap'; @@ -462,7 +506,7 @@ box-shadow: 0 0 0 rem(4px) var-get($theme, 'focus-outline-color'); &::after { - border-color: color($color: 'primary', $variant: 200); + border-color: var-get($theme, 'focus-border-color'); } } } @@ -478,7 +522,7 @@ %igx-checkbox--focused-hovered { @if $variant == 'bootstrap' { %radio-composite:after { - border-color: color($color: 'primary', $variant: 300); + border-color: hsl(from var-get($theme, 'focus-border-color') h calc(s * 1.12) calc(l * 0.82)); } } } diff --git a/projects/igniteui-angular/src/lib/core/styles/components/ripple/_ripple-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/ripple/_ripple-theme.scss index 30d91d77268..4321a330a90 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/ripple/_ripple-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/ripple/_ripple-theme.scss @@ -37,7 +37,6 @@ name: $name, selector: $selector, color: $color, - theme: map.get($schema, '_meta', 'theme'), )); } diff --git a/projects/igniteui-angular/src/lib/core/styles/components/scrollbar/scrollbar-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/scrollbar/scrollbar-theme.scss index 66ce8b4857e..83149b01395 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/scrollbar/scrollbar-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/scrollbar/scrollbar-theme.scss @@ -81,7 +81,6 @@ sb-corner-bg: $sb-corner-bg, sb-corner-border-color: $sb-corner-border-color, sb-corner-border-size: $sb-corner-border-size, - theme: map.get($schema, '_meta', 'theme'), )); } diff --git a/projects/igniteui-angular/src/lib/core/styles/components/select/_select-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/select/_select-theme.scss index 0829bce9fad..682f6ccc616 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/select/_select-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/select/_select-theme.scss @@ -46,7 +46,39 @@ } $theme: digest-schema($select-schema); - $meta: map.get($theme, '_meta'); + $variant: map.get($theme, '_meta', 'theme'); + + @if not($toggle-button-foreground) and $toggle-button-background { + $toggle-button-foreground: adaptive-contrast(var(--toggle-button-background)); + } + + @if not($toggle-button-foreground-filled) and $toggle-button-background { + $toggle-button-foreground-filled: adaptive-contrast(var(--toggle-button-background)); + } + + @if $variant == 'material' { + @if not($toggle-button-background-focus) and $toggle-button-background { + $toggle-button-background-focus: hsl(from var(--toggle-button-background) h s calc(l * 0.9)); + } + } @else { + @if not($toggle-button-background-focus) and $toggle-button-background { + $toggle-button-background-focus: var(--toggle-button-background); + } + } + + @if $variant == 'bootstrap' or $variant == 'indigo' { + @if not($toggle-button-background-focus--border) and $toggle-button-background { + $toggle-button-background-focus--border: var(--toggle-button-background) + } + + @if not($toggle-button-foreground-focus) and $toggle-button-background-focus--border { + $toggle-button-foreground-focus: adaptive-contrast(var(--toggle-button-background-focus--border)); + } + } @else { + @if not($toggle-button-foreground-focus) and $toggle-button-background-focus { + $toggle-button-foreground-focus: adaptive-contrast(var(--toggle-button-background-focus)); + } + } @return extend($theme, ( name: $name, @@ -59,10 +91,6 @@ toggle-button-foreground-disabled: $toggle-button-foreground-disabled, toggle-button-foreground-filled: $toggle-button-foreground-filled, toggle-button-background-focus--border: $toggle-button-background-focus--border, - theme: map.get($schema, '_meta', 'theme'), - _meta: map.merge(if($meta, $meta, ()), ( - variant: map.get($schema, '_meta', 'theme') - )), )); } @@ -71,7 +99,7 @@ /// @param {Map} $theme - The theme used to style the component. @mixin select($theme) { @include css-vars($theme); - $variant: map.get($theme, '_meta', 'variant'); + $variant: map.get($theme, '_meta', 'theme'); %igx-select { position: relative; @@ -127,7 +155,7 @@ } .igx-input-group.igx-input-group--focused:not(.igx-input-group--box) { - @if $variant != 'fluent' { + @if $variant != 'fluent' and $variant != 'material' { %igx-select__toggle-button { background: var-get($theme, 'toggle-button-background-focus--border'); } diff --git a/projects/igniteui-angular/src/lib/core/styles/components/slider/_slider-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/slider/_slider-theme.scss index 850d59d8df1..313d3e25ccb 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/slider/_slider-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/slider/_slider-theme.scss @@ -71,10 +71,99 @@ } $theme: digest-schema($slider-schema); - $meta: map.get($theme, '_meta'); + $variant: map.get($theme, '_meta', 'theme'); + + @if $variant == 'fluent' or $variant == 'indigo' { + @if not($thumb-border-color) and $track-color { + $thumb-border-color: var(--track-color); + } + + @if not($track-color) and $thumb-border-color { + $track-color: var(--thumb-border-color); + } + + @if not($thumb-border-hover-color) and $thumb-border-color { + $thumb-border-hover-color: hsl(from var(--thumb-border-color) h s calc(l * 1.1)); + } + + @if $variant == 'fluent' { + @if not($thumb-focus-color) and $thumb-border-color { + $thumb-focus-color: hsl(from var(--thumb-border-color) h s calc(l * 1.2)); + } + } @else { + @if not($thumb-focus-color) and $thumb-border-color { + $thumb-focus-color: hsla(from var(--thumb-border-color) h s l / 0.3); + } + } + } + + @if $variant == 'material' { + @if not($thumb-color) and $track-color { + $thumb-color: var(--track-color); + } + + @if not($track-color) and $thumb-color { + $track-color: var(--thumb-color); + } + + @if not($base-track-color) and $track-color { + $base-track-color: hsla(from var(--track-color) h s l / 0.4); + } + } + + @if $variant == 'bootstrap' { + @if not($thumb-border-color) and $thumb-color { + $thumb-border-color: var(--thumb-color); + } + + @if not($thumb-focus-color) and $thumb-color { + $thumb-focus-color: hsla(from var(--thumb-color) h s l / 0.5); + } + } + + @if not($track-hover-color) and $track-color { + $track-hover-color: hsl(from var(--track-color) h s calc(l * 1.1)); + } + + @if $variant != 'bootstrap' { + @if not($label-background-color) and $track-color { + $label-background-color: var(--track-color); + } + } @else { + @if not($label-background-color) and $thumb-color { + $label-background-color: var(--thumb-color); + } + } + @if not($label-text-color) and $label-background-color { - $label-text-color: text-contrast($label-background-color); + $label-text-color: adaptive-contrast($label-background-color); + } + + @if $variant != 'indigo' { + @if not($base-track-hover-color) and $base-track-color { + $base-track-hover-color: var(--base-track-color); + } + } @else { + @if not($base-track-hover-color) and $base-track-color { + $base-track-hover-color: hsl(from var(--base-track-color) h s calc(l * 0.8)); + } + } + + @if not($disabled-base-track-color) and $base-track-color { + $disabled-base-track-color: hsla(from var(--base-track-color) h s l / 0.5); + } + + @if not($disabled-fill-track-color) and $track-color { + $disabled-fill-track-color: hsla(from var(--track-color) h s l / 0.5); + } + + @if not($disabled-thumb-color) and $thumb-color { + $disabled-thumb-color: hsl(from var(--thumb-color) h calc(s * 0.5) calc(l * 1.2)); + } + + @if not($thumb-disabled-border-color) and $thumb-border-color { + $thumb-disabled-border-color: hsla(from var(--thumb-border-color) h s l / 0.5); } @return extend($theme, ( @@ -98,10 +187,6 @@ disabled-fill-track-color: $disabled-fill-track-color, tick-label-color: $tick-label-color, tick-color: $tick-color, - theme: map.get($schema, '_meta', 'theme'), - _meta: map.merge(if($meta, $meta, ()), ( - variant: map.get($schema, '_meta', 'theme') - )), )); } @@ -111,7 +196,7 @@ @mixin slider($theme) { @include css-vars($theme); - $variant: map.get($theme, '_meta', 'variant'); + $variant: map.get($theme, '_meta', 'theme'); $slider-height: rem(48px); $ripple-size: rem(40px); diff --git a/projects/igniteui-angular/src/lib/core/styles/components/snackbar/_snackbar-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/snackbar/_snackbar-theme.scss index a1323ecae76..9b5b8a2922f 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/snackbar/_snackbar-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/snackbar/_snackbar-theme.scss @@ -42,14 +42,13 @@ } $theme: digest-schema($snackbar-schema); - $meta: map.get($theme, '_meta'); @if not($button-color) and $background { - $button-color: text-contrast($background); + $button-color: adaptive-contrast(var(--background)); } @if not($text-color) and $background { - $text-color: text-contrast($background); + $text-color: adaptive-contrast(var(--background)); } @if not($shadow) { @@ -64,10 +63,6 @@ text-color: $text-color, button-color: $button-color, shadow: $shadow, - theme: map.get($schema, '_meta', 'theme'), - _meta: map.merge(if($meta, $meta, ()), ( - variant: map.get($schema, '_meta', 'theme') - )), )); } @@ -78,7 +73,7 @@ @include css-vars($theme); @include fade-in(); - $variant: map.get($theme, '_meta', 'variant'); + $variant: map.get($theme, '_meta', 'theme'); $snackbar-min-height: rem(48px); $snackbar-padding: rem(7px) rem(24px); diff --git a/projects/igniteui-angular/src/lib/core/styles/components/splitter/_splitter-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/splitter/_splitter-theme.scss index e2fabbea5b9..4993a71ce78 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/splitter/_splitter-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/splitter/_splitter-theme.scss @@ -42,16 +42,27 @@ } $theme: digest-schema($splitter-schema); - $meta: map.get($theme, '_meta'); + $variant: map.get($theme, '_meta', 'theme'); @if not($handle-color) and $bar-color { - $handle-color: text-contrast($bar-color); + $handle-color: adaptive-contrast(var(--bar-color)); } @if not($expander-color) and $bar-color { - $expander-color: text-contrast($bar-color); + $expander-color: adaptive-contrast(var(--bar-color)); } + @if $variant != 'indigo' { + @if not($focus-color) and $bar-color { + $focus-color: hsl(from var(--bar-color) h s calc(l * 0.7)); + } + } @else { + @if not($focus-color) and $bar-color { + $focus-color: var(--bar-color); + } + } + + @return extend($theme, ( name: $name, bar-color: $bar-color, @@ -60,10 +71,6 @@ border-radius: $border-radius, focus-color: $focus-color, size: $size, - theme: map.get($schema, '_meta', 'theme'), - _meta: map.merge(if($meta, $meta, ()), ( - variant: map.get($schema, '_meta', 'theme') - )), )); } @@ -77,7 +84,7 @@ $debug-hitbox: false; $hitbox-debug-color: rgba(coral, .24); - $variant: map.get($theme, '_meta', 'variant'); + $variant: map.get($theme, '_meta', 'theme'); //splitter-size + borders $splitter-size: unitless(map.get($theme, 'size')) + 2; diff --git a/projects/igniteui-angular/src/lib/core/styles/components/stepper/_stepper-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/stepper/_stepper-theme.scss index 5c4a6ecac35..2dd36102d7e 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/stepper/_stepper-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/stepper/_stepper-theme.scss @@ -186,50 +186,222 @@ } $theme: digest-schema($stepper-schema); - $meta: map.get($theme, '_meta'); - @if not($indicator-background) and $step-background { - $indicator-background: text-contrast($step-background); + //default step + @if not($step-hover-background) and $step-background { + $step-hover-background: hsl(from var(--step-background) h s calc(l * 0.8)); } - @if not($indicator-color) and $indicator-background { - $indicator-color: text-contrast($indicator-background); + @if not($step-focus-background) and $step-background { + $step-focus-background: hsl(from var(--step-background) h s calc(l * 0.9)); } - @if not($complete-indicator-color) and $complete-indicator-background { - $complete-indicator-color: text-contrast($complete-indicator-background); + @if not($indicator-background) and $step-background { + $indicator-background: hsla(from adaptive-contrast(var(--step-background)) h s l / .6); } - @if not($invalid-indicator-color) and $invalid-indicator-background { - $invalid-indicator-color: text-contrast($invalid-indicator-background); + @if not($indicator-outline) and $indicator-background { + $indicator-outline: var(--indicator-background); } - @if not($current-indicator-color) and $current-indicator-background { - $current-indicator-color: text-contrast($current-indicator-background); + @if not($indicator-color) and $indicator-background { + $indicator-color: adaptive-contrast(var(--indicator-background)); } @if not($title-color) and $step-background { - $title-color: text-contrast($step-background); + $title-color: adaptive-contrast(var(--step-background)); } @if not($subtitle-color) and $step-background { - $subtitle-color: text-contrast($step-background); + $subtitle-color: adaptive-contrast(var(--step-background)); } @if not($title-hover-color) and $step-hover-background { - $title-hover-color: text-contrast($step-hover-background); + $title-hover-color: adaptive-contrast(var(--step-hover-background)); } @if not($subtitle-hover-color) and $step-hover-background { - $subtitle-hover-color: text-contrast($step-hover-background); + $subtitle-hover-color: adaptive-contrast(var(--step-hover-background)); } @if not($title-focus-color) and $step-focus-background { - $title-focus-color: text-contrast($step-focus-background); + $title-focus-color: adaptive-contrast(var(--step-focus-background)); } @if not($subtitle-focus-color) and $step-focus-background { - $subtitle-focus-color: text-contrast($step-focus-background); + $subtitle-focus-color: adaptive-contrast(var(--step-focus-background)); + } + + //current step + @if not($current-step-background) and $step-background { + $current-step-background: var(--step-background); + } + + @if not($current-step-hover-background) and $current-step-background { + $current-step-hover-background: hsl(from var(--current-step-background) h s calc(l * 0.8)); + } + + @if not($current-step-focus-background) and $current-step-background { + $current-step-focus-background: hsl(from var(--current-step-background) h s calc(l * 0.9)); + } + + @if not($current-indicator-background) and $current-step-background { + $current-indicator-background: hsl(from var(--current-step-background) h s calc(l * 0.6)); + } + + @if not($current-indicator-outline) and $current-indicator-background { + $current-indicator-outline: var(--current-indicator-background); + } + + @if not($current-indicator-color) and $current-indicator-background { + $current-indicator-color: adaptive-contrast(var(--current-indicator-background)); + } + + @if not($current-title-color) and $current-step-background { + $current-title-color: adaptive-contrast(var(--current-step-background)); + } + + @if not($current-subtitle-color) and $current-step-background { + $current-subtitle-color: adaptive-contrast(var(--current-step-background)); + } + + @if not($current-title-hover-color) and $current-step-hover-background { + $current-title-hover-color: adaptive-contrast(var(--current-step-hover-background)); + } + + @if not($current-subtitle-hover-color) and $current-step-hover-background { + $current-subtitle-hover-color: adaptive-contrast(var(--current-step-hover-background)); + } + + @if not($current-title-focus-color) and $current-step-focus-background { + $current-title-focus-color: adaptive-contrast(var(--current-step-focus-background)); + } + + @if not($current-subtitle-focus-color) and $current-step-focus-background { + $current-subtitle-focus-color: adaptive-contrast(var(--current-step-focus-background)); + } + + //invalid step + @if not($invalid-step-background) and $step-background { + $invalid-step-background: var(--step-background); + } + + @if not($invalid-step-hover-background) and $invalid-step-background { + $invalid-step-hover-background: hsl(from var(--invalid-step-background) h s calc(l * 0.8)); + } + + @if not($invalid-step-focus-background) and $invalid-step-background { + $invalid-step-focus-background: hsl(from var(--invalid-step-background) h s calc(l * 0.9)); + } + + @if not($invalid-indicator-background) and not($step-background) and $invalid-step-background { + $invalid-indicator-background: adaptive-contrast(var(--invalid-step-background)); + } + + @if not($invalid-indicator-outline) and $invalid-indicator-background { + $invalid-indicator-outline: var(--invalid-indicator-background); + } + + @if not($invalid-indicator-color) and not($step-background) and $invalid-indicator-background { + $invalid-indicator-color: adaptive-contrast(var(--invalid-indicator-background)); + } + + @if not($invalid-title-color) and $invalid-indicator-background { + $invalid-title-color: var(--invalid-indicator-background); + } + + @if not($invalid-subtitle-color) and $invalid-indicator-background { + $invalid-subtitle-color: var(--invalid-indicator-background); + } + + @if not($invalid-title-hover-color) and $invalid-indicator-background { + $invalid-title-hover-color: var(--invalid-indicator-background); + } + + @if not($invalid-subtitle-hover-color) and $invalid-indicator-background { + $invalid-subtitle-hover-color: var(--invalid-indicator-background); + } + + @if not($invalid-title-focus-color) and $invalid-indicator-background { + $invalid-title-focus-color: var(--invalid-indicator-background); + } + + @if not($invalid-subtitle-focus-color) and $invalid-indicator-background { + $invalid-subtitle-focus-color: var(--invalid-indicator-background); + } + + //completed step + @if not($complete-step-background) and $step-background { + $complete-step-background: var(--step-background); + } + + @if not($complete-step-hover-background) and $complete-step-background { + $complete-step-hover-background: hsl(from var(--complete-step-background) h s calc(l * 0.8)); + } + + @if not($complete-step-focus-background) and $complete-step-background { + $complete-step-focus-background: hsl(from var(--complete-step-background) h s calc(l * 0.9)); + } + + @if not($complete-indicator-background) and $complete-step-background { + $complete-indicator-background: adaptive-contrast(var(--complete-step-background)); + } + + @if not($complete-indicator-color) and $complete-indicator-background { + $complete-indicator-color: adaptive-contrast(var(--complete-indicator-background)); + } + + @if not($complete-title-color) and $complete-step-background { + $complete-title-color: adaptive-contrast(var(--complete-step-background)); + } + + @if not($complete-subtitle-color) and $complete-step-background { + $complete-subtitle-color: adaptive-contrast(var(--complete-step-background)); + } + + @if not($complete-title-hover-color) and $complete-step-hover-background { + $complete-title-hover-color: adaptive-contrast(var(--complete-step-hover-background)); + } + + @if not($complete-subtitle-hover-color) and $complete-step-hover-background { + $complete-subtitle-hover-color: adaptive-contrast(var(--complete-step-hover-background)); + } + + @if not($complete-title-focus-color) and $complete-step-focus-background { + $complete-title-focus-color: adaptive-contrast(var(--complete-step-focus-background)); + } + + @if not($complete-subtitle-focus-color) and $complete-step-focus-background { + $complete-subtitle-focus-color: adaptive-contrast(var(--complete-step-focus-background)); + } + + //disabled step + @if not($disabled-indicator-background) and $step-background { + $disabled-indicator-background: hsla(from (adaptive-contrast(var(--step-background)) h s l / 0.5)); + } + + @if not($disabled-indicator-color) and $disabled-indicator-background { + $disabled-indicator-color: hsla(from (adaptive-contrast(var(--disabled-indicator-background)) h s l / 0.5)); + } + + @if not($disabled-indicator-outline) and $disabled-indicator-background { + $disabled-indicator-outline: var(--disabled-indicator-background); + } + + @if not($disabled-title-color) and $step-background { + $disabled-title-color: hsla(from (adaptive-contrast(var(--step-background)) h s l / 0.3)); + } + + @if not($disabled-subtitle-color) and $step-background { + $disabled-subtitle-color: hsla(from (adaptive-contrast(var(--step-background)) h s l / 0.3)); + } + + @if not($step-separator-color) and $step-background { + $step-separator-color: var(--step-background); + } + + @if not($step-separator-color) and $indicator-background { + $step-separator-color: var(--indicator-background); } @if not($border-radius-indicator) { @@ -318,10 +490,6 @@ // Border-radius border-radius-indicator: $border-radius-indicator, border-radius-step-header: $border-radius-step-header, - theme: map.get($schema, '_meta', 'theme'), - _meta: map.merge(if($meta, $meta, ()), ( - variant: map.get($schema, '_meta', 'theme') - )), )); } @@ -331,7 +499,7 @@ @mixin stepper($theme) { @include css-vars($theme); - $variant: map.get($theme, '_meta', 'variant'); + $variant: map.get($theme, '_meta', 'theme'); $indicator-size: map.get(( 'material': rem(24px), diff --git a/projects/igniteui-angular/src/lib/core/styles/components/switch/_switch-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/switch/_switch-theme.scss index fc4dda80469..6a6055ffa76 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/switch/_switch-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/switch/_switch-theme.scss @@ -91,7 +91,116 @@ } $theme: digest-schema($switch-schema); - $meta: map.get($theme, '_meta'); + $variant: map.get($theme, '_meta', 'theme'); + + @if $variant == 'material' { + @if not($track-off-color) and $thumb-off-color { + $track-off-color: hsl(from var(--thumb-off-color) h s calc(l * 0.5)); + } + + @if not($thumb-off-color) and $track-off-color { + $thumb-off-color: hsl(from var(--track-off-color) h s calc(l * 1.3)); + } + + @if not($thumb-disabled-color) and $thumb-off-color { + $thumb-disabled-color: hsl(from var(--thumb-off-color) h s calc(l + 20)); + } + + @if not($track-on-color) and $thumb-on-color { + $track-on-color: hsl(from var(--thumb-on-color) h s calc(l * 1.3)); + } + + @if not($track-on-hover-color) and $track-on-color { + $track-on-hover-color: var(--track-on-color); + } + + @if not($thumb-on-color) and $track-on-color { + $thumb-on-color: hsl(from var(--track-on-color) h s calc(l * 0.6)); + } + + @if not($thumb-on-disabled-color) and $thumb-on-color { + $thumb-on-disabled-color: hsl(from var(--thumb-on-color) h s calc(l + 20)); + } + } @else { + @if not($thumb-off-color) and $track-off-color { + $thumb-off-color: hsla(from adaptive-contrast(var(--track-off-color)) h s l / 0.8); + } + @if not($border-color) and $thumb-off-color { + $border-color: var(--thumb-off-color); + } + + @if not($thumb-off-color) and $border-color { + $thumb-off-color: var(--border-color); + } + + @if not($border-hover-color) and $track-off-color { + $border-hover-color: hsla(from var(--thumb-off-color) h s l / 0.9); + } + + @if not($border-hover-color) and $border-color { + $border-hover-color: hsl(from var(--border-color) h s calc(l * 0.8)); + } + + @if not($thumb-on-color) and $track-on-color { + $thumb-on-color: adaptive-contrast(var(--track-on-color)); + } + + @if not($track-on-hover-color) and $track-on-color { + $track-on-hover-color: hsl(from var(--track-on-color) h s calc(l * 0.9)); + } + + @if not($border-on-color) and $track-on-color { + $border-on-color: var(--track-on-color); + } + + @if not($border-on-hover-color) and $border-on-color { + $border-on-hover-color: hsl(from var(--border-on-color) h s calc(l * 0.9)); + } + + @if not($thumb-disabled-color) and $thumb-off-color { + $thumb-disabled-color: hsla(from var(--thumb-off-color) h s l / 0.3); + } + + @if not($border-disabled-color) and $border-color { + $border-disabled-color: hsla(from var(--border-color) h s l / 0.3); + } + + @if not($thumb-on-disabled-color) and $thumb-on-color { + $thumb-on-disabled-color: hsla(from var(--thumb-on-color) h s l / 0.3); + } + + @if $variant == 'bootstrap' { + @if not($focus-fill-color) and $track-on-color { + $focus-fill-color: hsl(from var(--track-on-color) h s calc(l * 1.2)); + } + + @if not($focus-outline-color) and $focus-fill-color { + $focus-outline-color: hsla(from var(--focus-fill-color) h s l / 0.5); + } + + @if not($focus-fill-hover-color) and $focus-fill-color { + $focus-fill-hover-color: hsl(from var(--focus-fill-color) h s calc(l * 0.9)); + } + } + + @if $variant == 'indigo' { + @if not($focus-outline-color) and $border-color { + $focus-outline-color: hsla(from var(--border-color) h s l / 0.5); + } + + @if not($focus-outline-color-focused) and $border-on-color { + $focus-outline-color-focused: hsla(from var(--border-on-color) h s l / 0.5); + } + } + } + + @if not($track-disabled-color) and $track-off-color { + $track-disabled-color: hsla(from var(--track-off-color) h s l / 0.5); + } + + @if not($track-on-disabled-color) and $track-on-color { + $track-on-disabled-color: hsla(from var(--track-on-color) h s l / 0.5); + } @if not($resting-shadow) { $resting-elevation: map.get($switch-schema, 'resting-elevation'); @@ -155,11 +264,6 @@ focus-outline-color-focused: $focus-outline-color-focused, focus-fill-color: $focus-fill-color, focus-fill-hover-color: $focus-fill-hover-color, - theme: map.get($schema, '_meta', 'theme'), - _meta: map.merge(if($meta, $meta, ()), ( - variant: map.get($schema, '_meta', 'theme'), - theme-variant: map.get($schema, '_meta', 'variant') - )), )); } @@ -170,8 +274,8 @@ @include css-vars($theme); @include scale-in-out($start-scale: .9); - $variant: map.get($theme, '_meta', 'variant'); - $theme-variant: map.get($theme, '_meta', 'theme-variant'); + $variant: map.get($theme, '_meta', 'theme'); + $theme-variant: map.get($theme, '_meta', 'variant'); $switch-width: map.get(( 'material': 36px, diff --git a/projects/igniteui-angular/src/lib/core/styles/components/tabs/_tabs-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/tabs/_tabs-theme.scss index 14db55a9061..60b4c2acbf2 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/tabs/_tabs-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/tabs/_tabs-theme.scss @@ -78,82 +78,155 @@ } $theme: digest-schema($tabs-schema); - $meta: map.get($theme, '_meta'); + $variant: map.get($theme, '_meta', 'theme'); - @if not($item-text-color) and $item-background { - @if meta.type-of($item-background) == 'color' { - $item-text-color: rgba(text-contrast($item-background), .54); - } + @if not($item-active-background) and $item-background { + $item-active-background: hsl(from var(--item-background) h s calc(l * 0.9)); } - @if not($item-hover-color) and $item-background { - $item-hover-color: text-contrast($item-background); - } + @if not($item-background) { + @if not($item-text-color) and $item-icon-color { + $item-text-color: var(--item-icon-color); + } + + @if not($item-icon-color) and $item-text-color { + $item-icon-color: var(--item-text-color); + } + } @else { + @if not($item-text-color) and $item-background { + $item-text-color: hsla(from adaptive-contrast(var(--item-background)) h s l / 0.8); + } - @if not($item-hover-color) and $item-hover-background { - $item-hover-color: text-contrast($item-hover-background); + @if not($item-icon-color) and $item-background { + $item-icon-color: hsla(from adaptive-contrast(var(--item-background) h s l / 0.8)); + } } - @if not($item-active-icon-color) and $item-active-background { - $item-active-icon-color: text-contrast($item-active-background); + @if not($item-active-background) { + @if $variant != 'bootstrap' { + @if not($item-active-icon-color) and $item-icon-color { + $item-active-icon-color: var(--item-icon-color); + } + + @if not($item-active-color) and $item-text-color { + $item-active-color: var(--item-text-color); + } + } + } @else { + @if not($item-active-icon-color) and $item-active-color { + $item-active-icon-color: var(--item-active-color); + } + + @if not($item-active-color) and $item-active-icon-color { + $item-active-color: var(--item-active-icon-color); + } + + @if not($item-active-icon-color) and $item-active-background { + $item-active-icon-color: adaptive-contrast(var(--item-active-background)); + } + + @if not($item-active-color) and $item-active-background { + $item-active-color: adaptive-contrast(var(--item-active-background)); + } } - @if not($item-active-icon-color) and $item-background { - $item-active-icon-color: text-contrast($item-background); + @if not($item-hover-background) { + @if not($item-hover-color) and $item-text-color { + $item-hover-color: hsla(from var(--item-text-color) h s l / 1); + } + + @if not($item-hover-icon-color) and $item-icon-color { + $item-hover-icon-color: hsla(from var(--item-icon-color) h s l / 1); + } + } @else { + @if not($item-hover-color) { + $item-hover-color: adaptive-contrast(var(--item-hover-background)); + } + + @if not($item-hover-icon-color) { + $item-hover-icon-color: adaptive-contrast(var(--item-hover-background)); + } } - @if not($indicator-color) and $item-background { - $indicator-color: text-contrast($item-background); + @if not($item-hover-background) and $item-background { + $item-hover-background: hsl(from var(--item-background) h s calc(l * 0.9)); } - @if not($item-active-color) and $item-active-icon-color { - $item-active-color: $item-active-icon-color; + @if $variant == 'bootstrap' { + @if not($border-color) and $item-background { + $border-color: hsla(from adaptive-contrast(var(--item-background)) h s l / 0.5); + } + + @if not($border-color--hover) and $border-color { + $border-color--hover: var(--border-color); + } + } @else { + @if not($item-background) { + @if not($indicator-color) and $item-text-color { + $indicator-color: var(--item-text-color); + } + + @if not($indicator-color) and $item-icon-color { + $indicator-color: var(--item-icon-color); + } + } @else { + @if not($indicator-color) and $item-active-color { + $indicator-color: var(--item-active-color); + } + + @if not($indicator-color) { + $indicator-color: adaptive-contrast(var(--item-background)); + } + } } // Button - @if not($button-color) and $item-background { - $button-color: text-contrast($item-background); - } + @if $item-background { + @if not($button-background) and $item-background { + $button-background: var(--item-background); + } - @if not($button-color) and $button-background { - $button-color: text-contrast($button-background); - } + @if not($button-hover-background) and $item-background { + $button-hover-background: hsl(from var(--item-background) h s calc(l * 0.9)); + } + } @else if not($button-background) { + @if $variant != 'material' { + @if not($button-color) and $item-text-color { + $button-color: var(--item-text-color); + } + + @if not($button-hover-color) and $button-color { + $button-hover-color: hsl(from var(--button-color) h s calc(l * 0.9)); + } - @if not($button-color) and $item-background { - $button-background: transparent; + @if not($button-disabled-color) and $button-color { + $button-disabled-color: hsla(from var(--button-color) h s l / 0.5); + } + } } - @if not($button-hover-color) and $button-hover-background { - $button-hover-color: text-contrast($button-hover-background); + @if $button-background { + @if not($button-hover-background) and $button-background { + $button-hover-background: hsl(from var(--button-background) h s calc(l * 0.9)); + } } - @if not($button-hover-background) and $item-background { - $button-hover-color: text-contrast($item-background); + @if not($button-color) and $button-background { + $button-color: adaptive-contrast(var(--button-background)); } - @if not($button-background) and $item-background { - @if meta.type-of($item-background) == 'color' and lightness($item-background) > 50 { - $button-background: transparent; - } @else { - $button-background: rgba(255, 255, 255 , .1); - } + @if not($button-hover-color) and $button-hover-background { + $button-hover-color: adaptive-contrast(var(--button-hover-background)); } - @if not($button-hover-background) and $item-background { - @if meta.type-of($item-background) == 'color' and lightness($item-background) > 50 { - $button-hover-background: rgba(0, 0, 0, .05); - } @else { - $button-hover-background: rgba(255, 255, 255 , .14); - } + @if not($button-ripple-color) and $button-color { + $button-ripple-color: var(--button-color); } - @if not($button-ripple-color) and $button-background { - @if meta.type-of($item-background) == 'color' and lightness($item-background) > 50 { - $button-ripple-color: rgba(0, 0, 0, .4); - } @else { - $button-ripple-color: rgba(255, 255, 255, .4); - } + @if not($button-disabled-color) and $button-color { + $button-disabled-color: hsla(from var(--button-color) h s l / 0.4); } + // Button end @if not($tab-ripple-color) and $item-active-background { @@ -186,13 +259,8 @@ tab-ripple-color: $tab-ripple-color, button-ripple-color: $button-ripple-color, border-color: $border-color, - border-radius: $border-radius, border-color--hover: $border-color--hover, - theme: map.get($schema, '_meta', 'theme'), - _meta: map.merge(if($meta, $meta, ()), ( - variant: map.get($schema, '_meta', 'theme'), - theme-variant: map.get($schema, '_meta', 'variant') - )), + border-radius: $border-radius, )); } @@ -204,11 +272,11 @@ @mixin tabs($theme) { @include css-vars($theme); - $variant: map.get($theme, '_meta', 'variant'); + $variant: map.get($theme, '_meta', 'theme'); $not-bootstrap-theme: $variant != 'bootstrap'; $bootstrap-theme: $variant == 'bootstrap'; $indigo-theme: $variant == 'indigo'; - $theme-variant: map.get($theme, '_meta', 'theme-variant'); + $theme-variant: map.get($theme, '_meta', 'variant'); $item-min-width: rem(90px); $item-max-width: rem(360px); diff --git a/projects/igniteui-angular/src/lib/core/styles/components/time-picker/_time-picker-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/time-picker/_time-picker-theme.scss index b91921d5877..13d9f0b869f 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/time-picker/_time-picker-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/time-picker/_time-picker-theme.scss @@ -71,36 +71,57 @@ } $theme: digest-schema($time-picker-schema); - $meta: map.get($theme, '_meta'); @if not($text-color) and $background-color { - $text-color: text-contrast($background-color); + $text-color: hsla(from adaptive-contrast(var(--background-color)) h s l / 0.7); + } + + @if not($hover-text-color) and $text-color { + $hover-text-color: hsla(from var(--text-color) h s l / 1); + } + + @if not($header-background) and $selected-text-color { + $header-background: var(--selected-text-color); + } + + @if not($header-background) and $background-color { + $header-background: var(--background-color); } @if not($header-hour-text-color) and $header-background { - $header-hour-text-color: text-contrast($header-background); + $header-hour-text-color: adaptive-contrast(var(--header-background)); } @if not($selected-text-color) and $active-item-background { - $selected-text-color: text-contrast($active-item-background); + $selected-text-color: var(--active-item-background); + } + + @if not($active-item-background) and $selected-text-color { + $active-item-background: var(--selected-text-color); } @if not($active-item-background) and $background-color { - @if meta.type-of($background-color) == 'color' { - $active-item-background: rgba(text-contrast($background-color), .12); - } + $active-item-background: hsla(from adaptive-contrast(var(--background-color)) h s l / .5); + } + + @if not($active-item-foreground) and $active-item-background { + $active-item-foreground: adaptive-contrast(var(--active-item-background)); + } + + @if not($selected-text-color) and $background-color { + $selected-text-color: adaptive-contrast(var(--background-color)); } @if not($disabled-text-color) and $disabled-item-background { - @if meta.type-of($disabled-item-background) == 'color' { - $disabled-text-color: rgba(text-contrast($disabled-item-background), .6); - } + $disabled-text-color: hsla(from adaptive-contrast(var(--disabled-item-background)) h s l / .6); + } + + @if not($border-color) and $background-color { + $border-color: hsla(from adaptive-contrast(var(--background-color)) h s l / .6); } @if not($divider-color) and $border-color { - @if meta.type-of($border-color) == 'color' { - $divider-color: $border-color; - } + $divider-color: var(--border-color); } @if not($modal-shadow) { @@ -133,10 +154,6 @@ divider-color: $divider-color, time-item-size: $time-item-size, active-item-border-radius: $active-item-border-radius, - theme: map.get($schema, '_meta', 'theme'), - _meta: map.merge(if($meta, $meta, ()), ( - variant: map.get($schema, '_meta', 'theme') - )), )); } @@ -146,7 +163,7 @@ @mixin time-picker($theme) { @include css-vars($theme); - $variant: map.get($theme, '_meta', 'variant'); + $variant: map.get($theme, '_meta', 'theme'); $not-bootstrap-theme: $variant != 'bootstrap'; $picker-buttons-padding: map.get(( diff --git a/projects/igniteui-angular/src/lib/core/styles/components/toast/_toast-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/toast/_toast-theme.scss index e7cee91389c..acce0d38e78 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/toast/_toast-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/toast/_toast-theme.scss @@ -46,17 +46,20 @@ } $theme: digest-schema($toast-schema); - $meta: map.get($theme, '_meta'); + + @if not($text-color) and $background { + $text-color: adaptive-contrast(var(--background)); + } + + @if not($border-color) and $text-color { + $border-color: hsla(from var(--text-color) h s l / 0.3); + } @if not($shadow) { $elevation: map.get($toast-schema, 'elevation'); $shadow: elevation($elevation); } - @if not($text-color) and $background { - $text-color: text-contrast($background); - } - @return extend($theme, ( name: $name, background: $background, @@ -64,10 +67,6 @@ text-color: $text-color, border-color: $border-color, shadow: $shadow, - theme: map.get($schema, '_meta', 'theme'), - _meta: map.merge(if($meta, $meta, ()), ( - variant: map.get($schema, '_meta', 'theme') - )), )); } @@ -77,8 +76,8 @@ /// @param {Map} $theme - The theme used to style the component. @mixin toast($theme) { @include css-vars($theme); - $variant: map.get($theme, '_meta', 'variant'); + $variant: map.get($theme, '_meta', 'theme'); $width: rem(52px); $margin: rem(42px) auto; diff --git a/projects/igniteui-angular/src/lib/core/styles/components/tooltip/_tooltip-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/tooltip/_tooltip-theme.scss index 6ddc20f8d80..d3e21b45036 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/tooltip/_tooltip-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/tooltip/_tooltip-theme.scss @@ -43,7 +43,6 @@ } $theme: digest-schema($tooltip-schema); - $meta: map.get($theme, '_meta'); @if not($shadow) { $elevation: map.get($tooltip-schema, 'elevation'); @@ -51,7 +50,7 @@ } @if not($text-color) and $background { - $text-color: text-contrast($background); + $text-color: adaptive-contrast($background); } @return extend($theme, ( @@ -61,10 +60,6 @@ text-color: $text-color, border-radius: $border-radius, shadow: $shadow, - theme: map.get($schema, '_meta', 'theme'), - _meta: map.merge(if($meta, $meta, ()), ( - variant: map.get($schema, '_meta', 'theme') - )), )); } @@ -73,7 +68,7 @@ /// @param {Map} $theme - The theme used to style the component. @mixin tooltip($theme) { @include css-vars($theme); - $variant: map.get($theme, '_meta', 'variant'); + $variant: map.get($theme, '_meta', 'theme'); %tooltip-display { display: inline-flex; diff --git a/projects/igniteui-angular/src/lib/core/styles/components/tree/_tree-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/tree/_tree-theme.scss index f5e40bcb62e..f64a00a367d 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/tree/_tree-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/tree/_tree-theme.scss @@ -62,22 +62,49 @@ } $theme: digest-schema($tree-schema); - $meta: map.get($theme, '_meta'); @if not($foreground) and $background { - $foreground: text-contrast($background); + $foreground: adaptive-contrast(var(--background)); + } + + @if not($background-selected) and $background { + $background-selected: hsl(from var(--background) h s calc(l * 0.9)); + } + + @if not($hover-color) and $background { + $hover-color: hsla(from adaptive-contrast(var(--background)) h s l / 0.1); + } + + @if not($hover-selected-color) and $background-selected { + $hover-selected-color: hsl(from var(--background-selected) h s calc(l * 0.9)); } @if not($foreground-selected) and $background-selected { - $foreground-selected: text-contrast($background-selected); + $foreground-selected: adaptive-contrast(var(--background-selected)); + } + + @if not($background-active) and $background { + $background-active: hsl(from var(--background) h s calc(l * 0.9)); } @if not($foreground-active) and $background-active { - $foreground-active: text-contrast($background-active); + $foreground-active: adaptive-contrast(var(--background-active)); + } + + @if not($background-active-selected) and $background-active { + $background-active-selected: hsl(from var(--background-active) h s calc(l * 0.9)); } @if not($foreground-active-selected) and $background-active-selected { - $foreground-active-selected: text-contrast($background-active-selected); + $foreground-active-selected: adaptive-contrast(var(--background-active-selected)); + } + + @if not($background-disabled) and $background { + $background-disabled: color-mix(in hsl, var(--background), transparent 50%); + } + + @if not($foreground-disabled) and $background-disabled { + $foreground-disabled: adaptive-contrast(var(--background-disabled)); } @return extend($theme, ( @@ -98,10 +125,6 @@ border-color: $border-color, hover-color: $hover-color, hover-selected-color: $hover-selected-color, - theme: map.get($schema, '_meta', 'theme'), - _meta: map.merge(if($meta, $meta, ()), ( - variant: map.get($schema, '_meta', 'theme') - )), size: $size, )); } @@ -112,7 +135,7 @@ @mixin tree($theme) { @include css-vars($theme); - $variant: map.get($theme, '_meta', 'variant'); + $variant: map.get($theme, '_meta', 'theme'); $indigo-theme: $variant == 'indigo'; $node-indent-default: ( diff --git a/projects/igniteui-angular/src/lib/core/styles/components/watermark/_watermark-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/watermark/_watermark-theme.scss index d43f68ae3f6..1fa70ac2dd5 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/watermark/_watermark-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/watermark/_watermark-theme.scss @@ -58,7 +58,6 @@ color: $color, border-color: $border-color, border-radius: $border-radius, - theme: map.get($schema, '_meta', 'theme'), )); } diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/generators/_base.scss b/projects/igniteui-angular/src/lib/core/styles/themes/generators/_base.scss index 28be2e20fee..072eeaf10e8 100644 --- a/projects/igniteui-angular/src/lib/core/styles/themes/generators/_base.scss +++ b/projects/igniteui-angular/src/lib/core/styles/themes/generators/_base.scss @@ -12,6 +12,7 @@ @use 'igniteui-theming/sass/utils' as *; @use 'igniteui-theming/sass/themes' as *; @use 'igniteui-theming/sass/themes/charts' as *; +@use 'igniteui-theming/sass/themes/schemas/components/light/button' as *; //// /// @group themes @@ -21,7 +22,9 @@ /// Default noop handler for theme map transforms /// @access private -@function theme-noop($arg) { @return $arg; } +@function theme-noop($arg) { + @return $arg; +} /// Generates an Ignite UI for Angular global theme. /// @param {Map} $palette - An palette to be used by the global theme. @@ -39,7 +42,7 @@ $exclude: (), $roundness: null, $elevation: true, - $elevations: elevations.$material-elevations, + $elevations: elevations.$material-elevations ) { @include theme-internal( $palette: $palette, @@ -48,7 +51,7 @@ $roundness: $roundness, $elevation: $elevation, $elevations: $elevations - ) + ); } /// Generates an Ignite UI for Angular global theme. @@ -69,7 +72,7 @@ $roundness: null, $elevation: true, $elevations: elevations.$material-elevations, - $theme-handler: meta.get-function('theme-noop'), + $theme-handler: meta.get-function('theme-noop') ) { // Stores all excluded component styles $excluded: (); @@ -146,7 +149,10 @@ $action-strip-theme-map: action-strip-theme( $schema: $schema, ); - $action-strip-theme-map: meta.call($theme-handler, $action-strip-theme-map); + $action-strip-theme-map: meta.call( + $theme-handler, + $action-strip-theme-map + ); @include action-strip($action-strip-theme-map); } @@ -167,18 +173,38 @@ } @if is-used('igx-button', $exclude) { - $button-theme-map: button-theme( + $flat-theme-map: flat-button-theme( + $schema: $schema, + ); + + $contained-theme-map: contained-button-theme( $schema: $schema, ); - $button-theme-map: meta.call($theme-handler, $button-theme-map); - @include button($button-theme-map); + + $outlined-theme-map: outlined-button-theme( + $schema: $schema, + ); + + $fab-theme-map: fab-button-theme( + $schema: $schema, + ); + + @include button( + $flat: meta.call($theme-handler, $flat-theme-map), + $contained: meta.call($theme-handler, $contained-theme-map), + $outlined: meta.call($theme-handler, $outlined-theme-map), + $fab:meta.call($theme-handler, $fab-theme-map) + ); } @if is-used('igx-button-group', $exclude) { $button-group-theme-map: button-group-theme( $schema: $schema, ); - $button-group-theme-map: meta.call($theme-handler, $button-group-theme-map); + $button-group-theme-map: meta.call( + $theme-handler, + $button-group-theme-map + ); @include button-group($button-group-theme-map); } @@ -227,55 +253,73 @@ $schema: $schema, ); $data-chart-theme-map: meta.call($theme-handler, $data-chart-theme-map); - @include css-vars($data-chart-theme-map); + @include css-vars($data-chart-theme-map); } @if is-used('doughnut-chart', $exclude) { $doughnut-chart-theme-map: doughnut-chart-theme( $schema: $schema, ); - $doughnut-chart-theme-map: meta.call($theme-handler, $doughnut-chart-theme-map); - @include css-vars($doughnut-chart-theme-map); + $doughnut-chart-theme-map: meta.call( + $theme-handler, + $doughnut-chart-theme-map + ); + @include css-vars($doughnut-chart-theme-map); } @if is-used('linear-gauge', $exclude) { $linear-gauge-theme-map: linear-gauge-theme( $schema: $schema, ); - $linear-gauge-theme-map: meta.call($theme-handler, $linear-gauge-theme-map); - @include css-vars($linear-gauge-theme-map); + $linear-gauge-theme-map: meta.call( + $theme-handler, + $linear-gauge-theme-map + ); + @include css-vars($linear-gauge-theme-map); } @if is-used('radial-gauge', $exclude) { $radial-gauge-theme-map: radial-gauge-theme( $schema: $schema, ); - $radial-gauge-theme-map: meta.call($theme-handler, $radial-gauge-theme-map); - @include css-vars($radial-gauge-theme-map); + $radial-gauge-theme-map: meta.call( + $theme-handler, + $radial-gauge-theme-map + ); + @include css-vars($radial-gauge-theme-map); } @if is-used('financial-chart', $exclude) { $financial-chart-theme-map: financial-chart-theme( $schema: $schema, ); - $financial-chart-theme-map: meta.call($theme-handler, $financial-chart-theme-map); - @include css-vars($financial-chart-theme-map); + $financial-chart-theme-map: meta.call( + $theme-handler, + $financial-chart-theme-map + ); + @include css-vars($financial-chart-theme-map); } @if is-used('bullet-graph', $exclude) { $bullet-graph-theme-map: bullet-graph-theme( $schema: $schema, ); - $bullet-graph-theme-map: meta.call($theme-handler, $bullet-graph-theme-map); - @include css-vars($bullet-graph-theme-map); + $bullet-graph-theme-map: meta.call( + $theme-handler, + $bullet-graph-theme-map + ); + @include css-vars($bullet-graph-theme-map); } @if is-used('category-chart', $exclude) { $category-chart-theme-map: category-chart-theme( $schema: $schema, ); - $category-chart-theme-map: meta.call($theme-handler, $category-chart-theme-map); - @include css-vars($category-chart-theme-map); + $category-chart-theme-map: meta.call( + $theme-handler, + $category-chart-theme-map + ); + @include css-vars($category-chart-theme-map); } @if is-used('geo-map', $exclude) { @@ -283,7 +327,7 @@ $schema: $schema, ); $geo-map-theme-map: meta.call($theme-handler, $geo-map-theme-map); - @include css-vars($geo-map-theme-map); + @include css-vars($geo-map-theme-map); } @if is-used('pie-chart', $exclude) { @@ -291,7 +335,7 @@ $schema: $schema, ); $pie-chart-theme-map: meta.call($theme-handler, $pie-chart-theme-map); - @include css-vars($pie-chart-theme-map); + @include css-vars($pie-chart-theme-map); } @if is-used('sparkline', $exclude) { @@ -299,23 +343,29 @@ $schema: $schema, ); $sparkline-theme-map: meta.call($theme-handler, $sparkline-theme-map); - @include css-vars($sparkline-theme-map); + @include css-vars($sparkline-theme-map); } @if is-used('funnel-chart', $exclude) { $funnel-chart-theme-map: funnel-chart-theme( $schema: $schema, ); - $funnel-chart-theme-map: meta.call($theme-handler, $funnel-chart-theme-map); - @include css-vars($funnel-chart-theme-map); + $funnel-chart-theme-map: meta.call( + $theme-handler, + $funnel-chart-theme-map + ); + @include css-vars($funnel-chart-theme-map); } @if is-used('shape-chart', $exclude) { $shape-chart-theme-map: shape-chart-theme( $schema: $schema, ); - $shape-chart-theme-map: meta.call($theme-handler, $shape-chart-theme-map); - @include css-vars($shape-chart-theme-map); + $shape-chart-theme-map: meta.call( + $theme-handler, + $shape-chart-theme-map + ); + @include css-vars($shape-chart-theme-map); } @if is-used('igx-checkbox', $exclude) { @@ -338,7 +388,10 @@ $column-actions-theme-map: column-actions-theme( $schema: $schema, ); - $column-actions-theme-map: meta.call($theme-handler, $column-actions-theme-map); + $column-actions-theme-map: meta.call( + $theme-handler, + $column-actions-theme-map + ); @include column-actions($column-actions-theme-map); } @@ -370,7 +423,10 @@ $date-range-picker-theme-map: date-range-picker-theme( $schema: $schema, ); - $date-range-picker-theme-map: meta.call($theme-handler, $date-range-picker-theme-map); + $date-range-picker-theme-map: meta.call( + $theme-handler, + $date-range-picker-theme-map + ); @include date-range-picker($date-range-picker-theme-map); } @@ -394,7 +450,10 @@ $dock-manager-theme-map: dock-manager-theme( $schema: $schema, ); - $dock-manager-theme-map: meta.call($theme-handler, $dock-manager-theme-map); + $dock-manager-theme-map: meta.call( + $theme-handler, + $dock-manager-theme-map + ); @include dock-manager($dock-manager-theme-map); } @@ -418,7 +477,10 @@ $expansion-panel-theme-map: expansion-panel-theme( $schema: $schema, ); - $expansion-panel-theme-map: meta.call($theme-handler, $expansion-panel-theme-map); + $expansion-panel-theme-map: meta.call( + $theme-handler, + $expansion-panel-theme-map + ); @include expansion-panel($expansion-panel-theme-map); } @@ -434,7 +496,10 @@ $grid-summary-theme-map: grid-summary-theme( $schema: $schema, ); - $grid-summary-theme-map: meta.call($theme-handler, $grid-summary-theme-map); + $grid-summary-theme-map: meta.call( + $theme-handler, + $grid-summary-theme-map + ); @include grid-summary($grid-summary-theme-map); } @@ -442,7 +507,10 @@ $grid-toolbar-theme-map: grid-toolbar-theme( $schema: $schema, ); - $grid-toolbar-theme-map: meta.call($theme-handler, $grid-toolbar-theme-map); + $grid-toolbar-theme-map: meta.call( + $theme-handler, + $grid-toolbar-theme-map + ); @include grid-toolbar($grid-toolbar-theme-map); } @@ -450,7 +518,10 @@ $pivot-data-selector-theme-map: pivot-data-selector-theme( $schema: $schema, ); - $pivot-data-selector-theme-map: meta.call($theme-handler, $pivot-data-selector-theme-map); + $pivot-data-selector-theme-map: meta.call( + $theme-handler, + $pivot-data-selector-theme-map + ); @include pivot-data-selector($pivot-data-selector-theme-map); } @@ -471,18 +542,33 @@ } @if is-used('igx-icon-button', $exclude) { - $icon-button-theme-map: icon-button-theme( + $flat-theme-map: flat-icon-button-theme( + $schema: $schema, + ); + + $contained-theme-map: contained-icon-button-theme( + $schema: $schema, + ); + + $outlined-theme-map: outlined-icon-button-theme( $schema: $schema, ); - $icon-button-theme-map: meta.call($theme-handler, $icon-button-theme-map); - @include icon-button($icon-button-theme-map); + + @include icon-button( + $flat: meta.call($theme-handler, $flat-theme-map), + $contained: meta.call($theme-handler, $contained-theme-map), + $outlined: meta.call($theme-handler, $outlined-theme-map), + ); } @if is-used('igx-input-group', $exclude) { $input-group-theme-map: input-group-theme( $schema: $schema, ); - $input-group-theme-map: meta.call($theme-handler, $input-group-theme-map); + $input-group-theme-map: meta.call( + $theme-handler, + $input-group-theme-map + ); @include input-group($input-group-theme-map); } @@ -538,7 +624,10 @@ $progress-circular-theme-map: progress-circular-theme( $schema: $schema, ); - $progress-circular-theme-map: meta.call($theme-handler, $progress-circular-theme-map); + $progress-circular-theme-map: meta.call( + $theme-handler, + $progress-circular-theme-map + ); @include progress-circular($progress-circular-theme-map); } @@ -546,7 +635,10 @@ $progress-linear-theme-map: progress-linear-theme( $schema: $schema, ); - $progress-linear-theme-map: meta.call($theme-handler, $progress-linear-theme-map); + $progress-linear-theme-map: meta.call( + $theme-handler, + $progress-linear-theme-map + ); @include progress-linear($progress-linear-theme-map); } @@ -562,7 +654,10 @@ $query-builder-theme-map: query-builder-theme( $schema: $schema, ); - $query-builder-theme-map: meta.call($theme-handler, $query-builder-theme-map); + $query-builder-theme-map: meta.call( + $theme-handler, + $query-builder-theme-map + ); @include query-builder($query-builder-theme-map); } @@ -634,7 +729,10 @@ $time-picker-theme-map: time-picker-theme( $schema: $schema, ); - $time-picker-theme-map: meta.call($theme-handler, $time-picker-theme-map); + $time-picker-theme-map: meta.call( + $theme-handler, + $time-picker-theme-map + ); @include time-picker($time-picker-theme-map); } @@ -664,12 +762,7 @@ /// @param {List} $exclude [( )] - A list of ig components to be excluded from the global theme styles. /// @see {mixin} theme /// @deprecated - Use the theme mixin instead. -@mixin light-theme( - $palette, - $exclude: (), - $roundness: null, - $elevation: true, -) { +@mixin light-theme($palette, $exclude: (), $roundness: null, $elevation: true) { $gray: color($palette, gray); $surface: color($palette, surface); @@ -689,7 +782,7 @@ $schema: $light-material-schema, $exclude: $exclude, $roundness: $roundness, - $elevation: $elevation, + $elevation: $elevation ); } @@ -698,12 +791,7 @@ /// @param {List} $exclude [( )] - A list of igx components to be excluded from the global theme styles. /// @see {mixin} theme /// @deprecated - Use the theme mixin instead. -@mixin dark-theme( - $palette, - $exclude: (), - $roundness: null, - $elevation: true, -) { +@mixin dark-theme($palette, $exclude: (), $roundness: null, $elevation: true) { $gray: color($palette, gray); $surface: color($palette, surface); @@ -723,6 +811,6 @@ $schema: $dark-material-schema, $exclude: $exclude, $roundness: $roundness, - $elevation: $elevation, + $elevation: $elevation ); } From 61324de98c3b4667e846dbb45fa5c754a520d4c3 Mon Sep 17 00:00:00 2001 From: Silvia Ivanova <59446295+SisIvanova@users.noreply.github.com> Date: Tue, 17 Jun 2025 10:39:04 +0300 Subject: [PATCH 11/29] refactor(input-group): label position when placeholder is removed (#15933) --- .../components/input/_input-group-theme.scss | 44 +++++++++++++++++-- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/projects/igniteui-angular/src/lib/core/styles/components/input/_input-group-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/input/_input-group-theme.scss index a716c1b2434..82406dd8fd0 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/input/_input-group-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/input/_input-group-theme.scss @@ -747,12 +747,23 @@ } } } + + &:not(%form-group-display--focused, %form-group-display--filled) { + &:has(input:not(:placeholder-shown, [type='file'])) { + %form-group-label { + @include type-style('subtitle-1'); + transform: translateY(0); + } + } + } } } %form-group-placeholder { - %form-group-label { - transition: none !important; + &:has(input:placeholder-shown, textarea:placeholder-shown) { + %form-group-label { + transition: none !important; + } } } @@ -1255,13 +1266,20 @@ %form-group-label--focused-border, %form-group-label--filled-border, - %form-group-label--placeholder-border, %form-group-label--file-border { %igx-input-group__notch { border-block-start-color: transparent !important; } } + %form-group-label--placeholder-border { + &:has(input:placeholder-shown, textarea:placeholder-shown) { + %igx-input-group__notch { + border-block-start-color: transparent !important; + } + } + } + %form-group-label--focused-border { %form-group-bundle-start { border-inline-start-width: rem(2px); @@ -1349,6 +1367,26 @@ width: calc(100% - #{rem(2px)}); } } + + %textarea-group:not(%form-group-display--focused, %form-group-display--filled) { + &:has(textarea:not(:placeholder-shown)) { + %form-group-textarea-label:not(%textarea-group-label--focused) { + @include type-style('subtitle-1'); + + top: calc($input-top-padding - #{rem(3px)}); + transform: translateY(0); + margin-bottom: auto; + } + } + } + + %textarea-group:not(%form-group-display--focused, %form-group-display--filled) { + &:has(%form-group-display--border, textarea:not(:placeholder-shown)) { + %igx-input-group__notch { + border-block-start-width: rem(1px); + } + } + } } %form-group-textarea-group-bundle { From cefaccae98a518d86ede933d9265e435ced0f897 Mon Sep 17 00:00:00 2001 From: Adrian Petrov <99720888+adrianptrv@users.noreply.github.com> Date: Wed, 18 Jun 2025 16:03:24 +0300 Subject: [PATCH 12/29] fix(grid): remove column actions input field negative margin (#15949) --- .../styles/components/column-actions/_column-actions-theme.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/igniteui-angular/src/lib/core/styles/components/column-actions/_column-actions-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/column-actions/_column-actions-theme.scss index 10bc31b20f6..819dae048fa 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/column-actions/_column-actions-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/column-actions/_column-actions-theme.scss @@ -95,7 +95,7 @@ %column-actions-input { font-size: rem(16px) !important; - margin: rem(-16px) 0 0 !important; + margin: 0 !important; padding: rem(8px) rem(16px); } From 5974ae706b8790366f4e596018aa74f0685a96cf Mon Sep 17 00:00:00 2001 From: Adrian Petrov <99720888+adrianptrv@users.noreply.github.com> Date: Wed, 18 Jun 2025 16:23:46 +0300 Subject: [PATCH 13/29] fix(combo): clear button foreground and abckground parameters (#15944) Co-authored-by: Simeon Simeonoff --- .../src/lib/core/styles/components/combo/_combo-theme.scss | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/projects/igniteui-angular/src/lib/core/styles/components/combo/_combo-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/combo/_combo-theme.scss index b04cb960e80..5a90d871e28 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/combo/_combo-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/combo/_combo-theme.scss @@ -301,6 +301,13 @@ padding: 0; } } + + &:not(.igx-input-group--disabled){ + %igx-combo__clear-button { + color: var-get($theme, 'clear-button-foreground'); + background: var-get($theme, 'clear-button-background'); + } + } } %form-group-bundle:not(%form-group-bundle--disabled):focus-within { From e7be93c11fdf2c5f170ed5eb5adf8eab84d823e8 Mon Sep 17 00:00:00 2001 From: Silvia Ivanova <59446295+SisIvanova@users.noreply.github.com> Date: Thu, 19 Jun 2025 18:19:01 +0300 Subject: [PATCH 14/29] fix(combo/select): remove suffix dynamically (#15956) --- .../src/lib/combo/combo.common.ts | 17 ++++-- .../lib/input-group/input-group.component.ts | 2 +- .../src/lib/select/select.component.ts | 17 ++++-- .../input-group-showcase.sample.html | 54 +++++++++++++------ 4 files changed, 67 insertions(+), 23 deletions(-) diff --git a/projects/igniteui-angular/src/lib/combo/combo.common.ts b/projects/igniteui-angular/src/lib/combo/combo.common.ts index dc77a33d87c..6084b0ef637 100644 --- a/projects/igniteui-angular/src/lib/combo/combo.common.ts +++ b/projects/igniteui-angular/src/lib/combo/combo.common.ts @@ -22,7 +22,8 @@ import { QueryList, TemplateRef, ViewChild, - DOCUMENT + DOCUMENT, + ViewChildren } from '@angular/core'; import { AbstractControl, ControlValueAccessor, NgControl } from '@angular/forms'; import { caseSensitive } from '@igniteui/material-icons-extended'; @@ -748,6 +749,9 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh @ContentChildren(IgxSuffixDirective, { descendants: true }) protected suffixes: QueryList; + @ViewChildren(IgxSuffixDirective) + protected internalSuffixes: QueryList; + /** @hidden @internal */ public get searchValue(): string { return this._searchValue; @@ -984,8 +988,15 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh this.inputGroup.prefixes = this.prefixes; } - if (this.inputGroup && this.suffixes?.length > 0) { - this.inputGroup.suffixes = this.suffixes; + if (this.inputGroup) { + const suffixesArray = this.suffixes?.toArray() ?? []; + const internalSuffixesArray = this.internalSuffixes?.toArray() ?? []; + const mergedSuffixes = new QueryList(); + mergedSuffixes.reset([ + ...suffixesArray, + ...internalSuffixesArray + ]); + this.inputGroup.suffixes = mergedSuffixes; } } diff --git a/projects/igniteui-angular/src/lib/input-group/input-group.component.ts b/projects/igniteui-angular/src/lib/input-group/input-group.component.ts index 4c72cf41424..93b8a4579cf 100644 --- a/projects/igniteui-angular/src/lib/input-group/input-group.component.ts +++ b/projects/igniteui-angular/src/lib/input-group/input-group.component.ts @@ -285,7 +285,7 @@ export class IgxInputGroupComponent implements IgxInputGroupBase { } /** @hidden @internal */ - public set suffixes(items: QueryList) { + public set suffixes(items: QueryList) { this._suffixes = items; } diff --git a/projects/igniteui-angular/src/lib/select/select.component.ts b/projects/igniteui-angular/src/lib/select/select.component.ts index 3cff7cfe7ee..d448e4fe6dc 100644 --- a/projects/igniteui-angular/src/lib/select/select.component.ts +++ b/projects/igniteui-angular/src/lib/select/select.component.ts @@ -22,7 +22,8 @@ import { QueryList, TemplateRef, ViewChild, - DOCUMENT + DOCUMENT, + ViewChildren } from '@angular/core'; import { NgTemplateOutlet } from '@angular/common'; import { AbstractControl, ControlValueAccessor, NgControl, NG_VALUE_ACCESSOR } from '@angular/forms'; @@ -123,6 +124,9 @@ export class IgxSelectComponent extends IgxDropDownComponent implements IgxSelec @ContentChildren(IgxSuffixDirective, { descendants: true }) protected suffixes: QueryList; + @ViewChildren(IgxSuffixDirective) + protected internalSuffixes: QueryList; + /** @hidden @internal */ @ContentChild(forwardRef(() => IgxLabelDirective), { static: true }) public label: IgxLabelDirective; @@ -546,8 +550,15 @@ export class IgxSelectComponent extends IgxDropDownComponent implements IgxSelec this.inputGroup.prefixes = this.prefixes; } - if (this.inputGroup && this.suffixes?.length > 0) { - this.inputGroup.suffixes = this.suffixes; + if (this.inputGroup) { + const suffixesArray = this.suffixes?.toArray() ?? []; + const internalSuffixesArray = this.internalSuffixes?.toArray() ?? []; + const mergedSuffixes = new QueryList(); + mergedSuffixes.reset([ + ...suffixesArray, + ...internalSuffixesArray + ]); + this.inputGroup.suffixes = mergedSuffixes; } } diff --git a/src/app/input-group-showcase/input-group-showcase.sample.html b/src/app/input-group-showcase/input-group-showcase.sample.html index f3561b9729d..646f3df2cba 100644 --- a/src/app/input-group-showcase/input-group-showcase.sample.html +++ b/src/app/input-group-showcase/input-group-showcase.sample.html @@ -26,9 +26,11 @@

Angular

[attr.placeholder]="getPlaceholder()" igxInput /> - - face - + @if (!hideSuffix()) { + + face + + } Type your web address @@ -48,9 +50,11 @@

Angular

[attr.placeholder]="getPlaceholder()" igxInput> - - face - + @if (!hideSuffix()) { + + face + + } Hint text @@ -68,9 +72,11 @@

Angular

I am a Hint - - favorite - + @if (!hideSuffix()) { + + favorite + + } Apple Orange Grapes @@ -88,7 +94,11 @@

Angular

} favorite - favorite + @if (!hideSuffix()) { + + favorite + + } Select a unique falsy value @@ -108,9 +118,11 @@

Angular

[readOnly]="isReadonly()" igxInput /> - - face - + @if (!hideSuffix()) { + + face + + } Type your web address @@ -157,7 +169,9 @@

Web components

[type]="getNativeInputType()" [outlined]="isOutlined()"> - + @if (!hideSuffix()) { + + } Type your web address @@ -171,7 +185,9 @@

Web components

[attr.placeholder]="getPlaceholder()" [outlined]="isOutlined()"> - + @if (!hideSuffix()) { + + } Hint text @@ -183,7 +199,9 @@

Web components

[outlined]="isOutlined()" [style.--ig-size]="getSize()"> - + @if (!hideSuffix()) { + + } I am a Hint Apple Orange @@ -199,6 +217,10 @@

Web components

[disabled]="isDisabled()" [style.--ig-size]="getSize()"> I am a Hint + + @if (!hideSuffix()) { + + } From 625769a54332ea7dd4c800f76ff27136f031af94 Mon Sep 17 00:00:00 2001 From: Adrian Petrov <99720888+adrianptrv@users.noreply.github.com> Date: Thu, 19 Jun 2025 20:30:23 +0300 Subject: [PATCH 15/29] fix(input-group): bootstrap invalid and success state shadows (#15959) --- .../input/_input-group-component.scss | 30 +++++++++++++++++++ .../components/input/_input-group-theme.scss | 30 +++++++++++++++++-- 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/projects/igniteui-angular/src/lib/core/styles/components/input/_input-group-component.scss b/projects/igniteui-angular/src/lib/core/styles/components/input/_input-group-component.scss index 5b001acd553..9638b638ca7 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/input/_input-group-component.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/input/_input-group-component.scss @@ -1000,6 +1000,36 @@ } } + @include mx(bootstrap, warning) { + @include e(input) { + @extend %bootstrap-input--warning !optional; + + &:hover { + @extend %bootstrap-input--warning !optional; + } + } + + @include e(file-input) { + @extend %bootstrap-input--warning !optional; + + &:hover { + @extend %bootstrap-input--warning !optional; + } + } + + @include e(label) { + @extend %bootstrap-label !optional; + } + + @include e(textarea) { + @extend %bootstrap-input--warning !optional; + + &:hover { + @extend %bootstrap-input--warning !optional; + } + } + } + @include mx(bootstrap, textarea-group) { @include e(bundle) { @extend %form-group-bundle-bootstrap--textarea !optional; diff --git a/projects/igniteui-angular/src/lib/core/styles/components/input/_input-group-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/input/_input-group-theme.scss index 82406dd8fd0..36ab839fdcf 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/input/_input-group-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/input/_input-group-theme.scss @@ -2461,12 +2461,38 @@ %bootstrap-input--success { border: rem(1px) solid var-get($theme, 'success-secondary-color'); - box-shadow: 0 0 0 rem(4px) var-get($theme, 'success-shadow-color'); + + &:focus { + box-shadow: 0 0 0 rem(4px) var-get($theme, 'success-shadow-color'); + + + %bootstrap-file-input { + box-shadow: 0 0 0 rem(4px) var-get($theme, 'success-shadow-color'); + } + } } %bootstrap-input--error { border: rem(1px) solid var-get($theme, 'error-secondary-color'); - box-shadow: 0 0 0 rem(4px) var-get($theme, 'error-shadow-color'); + + &:focus { + box-shadow: 0 0 0 rem(4px) var-get($theme, 'error-shadow-color'); + + + %bootstrap-file-input { + box-shadow: 0 0 0 rem(4px) var-get($theme, 'error-shadow-color'); + } + } + } + + %bootstrap-input--warning { + border: rem(1px) solid var-get($theme, 'warning-secondary-color'); + + &:focus { + box-shadow: 0 0 0 rem(4px) color($color: 'warn', $variant: 500, $opacity: 0.38); + + + %bootstrap-file-input { + box-shadow: 0 0 0 rem(4px) color($color: 'warn', $variant: 500, $opacity: 0.38); + } + } } %bootstrap-input--disabled { From 02b8735811b0bd6420e905d383edfe526a0db391 Mon Sep 17 00:00:00 2001 From: Martin Dragnev <37667452+mddragnev@users.noreply.github.com> Date: Fri, 20 Jun 2025 14:49:56 +0300 Subject: [PATCH 16/29] fix(esf): use requestAnimationFrame only when in browser environment (#15955) --- .../filtering/excel-style/excel-style-search.component.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/projects/igniteui-angular/src/lib/grids/filtering/excel-style/excel-style-search.component.ts b/projects/igniteui-angular/src/lib/grids/filtering/excel-style/excel-style-search.component.ts index 25199db8605..d366da1a43c 100644 --- a/projects/igniteui-angular/src/lib/grids/filtering/excel-style/excel-style-search.component.ts +++ b/projects/igniteui-angular/src/lib/grids/filtering/excel-style/excel-style-search.component.ts @@ -254,7 +254,10 @@ export class IgxExcelStyleSearchComponent implements AfterViewInit, OnDestroy { } public ngAfterViewInit() { - requestAnimationFrame(this.refreshSize); + if (this.platform.isBrowser) { + // SSR workaround + requestAnimationFrame(this.refreshSize); + } } public ngOnDestroy(): void { From cdbc56046c1e1168fcd5425a8f2f72e7459b3d11 Mon Sep 17 00:00:00 2001 From: Tihomir Tonev Date: Fri, 20 Jun 2025 16:21:50 +0300 Subject: [PATCH 17/29] fix(pivot-grid): add IgxPivotGridRow to latest master (#15893) --- .../src/analyzer/elements.config.ts | 8 +-- .../src/lib/grids/grid-public-row.ts | 70 +++++++++++++++++++ .../grids/pivot-grid/pivot-grid.component.ts | 17 +++++ .../lib/grids/pivot-grid/pivot-grid.spec.ts | 20 +++++- 4 files changed, 109 insertions(+), 6 deletions(-) diff --git a/projects/igniteui-angular-elements/src/analyzer/elements.config.ts b/projects/igniteui-angular-elements/src/analyzer/elements.config.ts index be2f3f4d6d5..52222c1a819 100644 --- a/projects/igniteui-angular-elements/src/analyzer/elements.config.ts +++ b/projects/igniteui-angular-elements/src/analyzer/elements.config.ts @@ -14,16 +14,16 @@ import { IgxGridToolbarComponent } from "../../../igniteui-angular/src/lib/grids import { IgxToolbarToken } from "../../../igniteui-angular/src/lib/grids/toolbar/token"; import { IgxColumnComponent } from "../../../igniteui-angular/src/lib/grids/columns/column.component"; import { IgxColumnGroupComponent } from "../../../igniteui-angular/src/lib/grids/columns/column-group.component"; +import { IgxColumnLayoutComponent } from "../../../igniteui-angular/src/lib/grids/columns/column-layout.component"; +import { IgxGridToolbarExporterComponent } from "../../../igniteui-angular/src/lib/grids/toolbar/grid-toolbar-exporter.component"; +import { IgxGridToolbarHidingComponent } from "../../../igniteui-angular/src/lib/grids/toolbar/grid-toolbar-hiding.component"; +import { IgxGridToolbarPinningComponent } from "../../../igniteui-angular/src/lib/grids/toolbar/grid-toolbar-pinning.component"; import { IgxRowIslandComponent } from "../../../igniteui-angular/src/lib/grids/hierarchical-grid/row-island.component"; import { IgxActionStripComponent } from "../../../igniteui-angular/src/lib/action-strip/action-strip.component"; import { IgxActionStripToken } from "../../../igniteui-angular/src/lib/action-strip/token"; import { IgxGridEditingActionsComponent } from "../../../igniteui-angular/src/lib/action-strip/grid-actions/grid-editing-actions.component"; import { IgxGridActionsBaseDirective } from "../../../igniteui-angular/src/lib/action-strip/grid-actions/grid-actions-base.directive"; import { IgxGridPinningActionsComponent } from "../../../igniteui-angular/src/lib/action-strip/grid-actions/grid-pinning-actions.component"; -import { IgxColumnLayoutComponent } from "../../../igniteui-angular/src/lib/grids/columns/column-layout.component"; -import { IgxGridToolbarExporterComponent } from "../../../igniteui-angular/src/lib/grids/toolbar/grid-toolbar-exporter.component"; -import { IgxGridToolbarHidingComponent } from "../../../igniteui-angular/src/lib/grids/toolbar/grid-toolbar-hiding.component"; -import { IgxGridToolbarPinningComponent } from "../../../igniteui-angular/src/lib/grids/toolbar/grid-toolbar-pinning.component"; import { IgxGridStateComponent } from "../lib/state.component"; export const registerComponents = [ diff --git a/projects/igniteui-angular/src/lib/grids/grid-public-row.ts b/projects/igniteui-angular/src/lib/grids/grid-public-row.ts index b85b4f1c97c..14395046ac4 100644 --- a/projects/igniteui-angular/src/lib/grids/grid-public-row.ts +++ b/projects/igniteui-angular/src/lib/grids/grid-public-row.ts @@ -4,6 +4,8 @@ import { GridSummaryCalculationMode, GridSummaryPosition } from './common/enums' import { IgxGridCell } from './grid-public-cell'; import { IgxSummaryResult } from './summaries/grid-summary'; import { ITreeGridRecord } from './tree-grid/tree-grid.interfaces'; +import { IgxPivotGridComponent } from './pivot-grid/pivot-grid.component'; +import { PivotUtil } from './pivot-grid/pivot-util'; import { mergeWith } from 'lodash-es'; import { CellType, GridServiceType, GridType, IGridValidationState, RowType, ValidationStatus } from './common/grid.interface'; @@ -791,3 +793,71 @@ export class IgxSummaryRow implements RowType { return row; } } + + export class IgxPivotGridRow implements RowType { + + /** The index of the row within the grid */ + public index: number; + + /** + * The grid that contains the row. + */ + public grid: IgxPivotGridComponent; + private _data?: any; + + constructor(grid: IgxPivotGridComponent, index: number, data?: any) { + this.grid = grid; + this.index = index; + this._data = data && data.addRow && data.recordRef ? data.recordRef : data; + } + + /** + * The data passed to the row component. + */ + public get data(): any { + return this._data ?? this.grid.dataView[this.index]; + } + + /** + * Returns the view index calculated per the grid page. + */ + public get viewIndex(): number { + return this.index + this.grid.page * this.grid.perPage; + } + + /** + * Gets the row key. + * A row in the grid is identified either by: + * - primaryKey data value, + * - the whole rowData, if the primaryKey is omitted. + * + * ```typescript + * let rowKey = row.key; + * ``` + */ + public get key(): any { + const dimension = this.grid.visibleRowDimensions[this.grid.visibleRowDimensions.length - 1]; + const recordKey = PivotUtil.getRecordKey(this.data, dimension); + return recordKey ? recordKey : null; + } + + /** + * Gets whether the row is selected. + * Default value is `false`. + * ```typescript + * row.selected = true; + * ``` + */ + public get selected(): boolean { + return this.grid.selectionService.isRowSelected(this.key); + } + + public set selected(val: boolean) { + if (val) { + this.grid.selectionService.selectRowsWithNoEvent([this.key]); + } else { + this.grid.selectionService.deselectRowsWithNoEvent([this.key]); + } + this.grid.cdr.markForCheck(); + } +} diff --git a/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-grid.component.ts b/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-grid.component.ts index 441771d3df2..5cf939e1877 100644 --- a/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-grid.component.ts +++ b/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-grid.component.ts @@ -103,6 +103,7 @@ import { IgxTextHighlightService } from '../../directives/text-highlight/text-hi import { IgxPivotRowHeaderGroupComponent } from './pivot-row-header-group.component'; import { IgxPivotDateDimension } from './pivot-grid-dimensions'; import { IgxPivotRowDimensionMrlRowComponent } from './pivot-row-dimension-mrl-row.component'; +import { IgxPivotGridRow } from '../grid-public-row'; let NEXT_ID = 0; const MINIMUM_COLUMN_WIDTH = 200; @@ -2521,4 +2522,20 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni this.regroupTrigger++; } } + + /** + * @hidden @internal + */ + public createRow(index: number, data?: any): RowType { + let row: RowType; + + const dataIndex = this._getDataViewIndex(index); + const rec = data ?? this.dataView[dataIndex]; + + + if (!row && rec) { + row = new IgxPivotGridRow(this, index, rec); + } + return row; + } } diff --git a/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-grid.spec.ts b/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-grid.spec.ts index 7575a86ad87..30777c67385 100644 --- a/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-grid.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-grid.spec.ts @@ -1,7 +1,7 @@ import { ComponentFixture, fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { FilteringExpressionsTree, FilteringLogic, GridColumnDataType, IgxIconComponent, IgxPivotGridComponent, IgxStringFilteringOperand } from 'igniteui-angular'; +import { CellType, FilteringExpressionsTree, FilteringLogic, GridColumnDataType, IGridCellEventArgs, IgxIconComponent, IgxPivotGridComponent, IgxStringFilteringOperand } from 'igniteui-angular'; import { IgxChipComponent } from '../../chips/chip.component'; import { IgxChipsAreaComponent } from '../../chips/chips-area.component'; import { DefaultPivotSortingStrategy } from '../../data-operations/pivot-sort-strategy'; @@ -22,6 +22,7 @@ import { Size } from '../common/enums'; import { setElementSize } from '../../test-utils/helper-utils.spec'; import { IgxPivotRowDimensionMrlRowComponent } from './pivot-row-dimension-mrl-row.component'; import { IgxPivotRowDimensionContentComponent } from './pivot-row-dimension-content.component'; +import { IgxGridCellComponent } from '../cell.component'; const CSS_CLASS_LIST = 'igx-drop-down__list'; const CSS_CLASS_ITEM = 'igx-drop-down__item'; @@ -2104,8 +2105,23 @@ describe('IgxPivotGrid #pivotGrid', () => { expect(pivotGrid.rowList.length).toBe(10); }); - }); + it('should have the correct IGridCellEventArgs when clicking on a cell', () => { + const pivotGrid = fixture.componentInstance.pivotGrid; + spyOn(pivotGrid.cellClick, 'emit').and.callThrough(); + fixture.detectChanges(); + + const cell = pivotGrid.gridAPI.get_cell_by_index(0, 'Bulgaria-UnitsSold') as CellType; + + pivotGrid.cellClick.emit({ cell, event: null }); + cell.nativeElement.click(); + const cellClickargs: IGridCellEventArgs = { cell, event: new MouseEvent('click') }; + + const gridCell = cellClickargs.cell as IgxGridCellComponent; + const firstEntry = gridCell.rowData.aggregationValues.entries().next().value; + expect(firstEntry).toEqual(['USA-UnitsSold', 829]); + }); + }); }); describe('IgxPivotGrid complex hierarchy #pivotGrid', () => { From 7167adce62dfe9cbd20830410d7dacd4d0225928 Mon Sep 17 00:00:00 2001 From: Riva Ivanova <49126110+RivaIvanova@users.noreply.github.com> Date: Mon, 23 Jun 2025 14:18:48 +0300 Subject: [PATCH 18/29] fix(tooltip): use inject document for ssr (#15951) --- .../src/lib/directives/tooltip/tooltip.directive.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/projects/igniteui-angular/src/lib/directives/tooltip/tooltip.directive.ts b/projects/igniteui-angular/src/lib/directives/tooltip/tooltip.directive.ts index e89a280614c..e03128ec49c 100644 --- a/projects/igniteui-angular/src/lib/directives/tooltip/tooltip.directive.ts +++ b/projects/igniteui-angular/src/lib/directives/tooltip/tooltip.directive.ts @@ -1,5 +1,5 @@ import { - Directive, ElementRef, Input, ChangeDetectorRef, Optional, HostBinding, Inject, OnDestroy + Directive, ElementRef, Input, ChangeDetectorRef, Optional, HostBinding, Inject, OnDestroy, inject, DOCUMENT } from '@angular/core'; import { IgxOverlayService } from '../../services/overlay/overlay'; import { OverlaySettings } from '../../services/public_api'; @@ -110,6 +110,7 @@ export class IgxTooltipDirective extends IgxToggleDirective implements OnDestroy public tooltipTarget: IgxTooltipTargetDirective; private _destroy$ = new Subject(); + private _document = inject(DOCUMENT); /** @hidden */ constructor( @@ -122,10 +123,10 @@ export class IgxTooltipDirective extends IgxToggleDirective implements OnDestroy this.onDocumentTouchStart = this.onDocumentTouchStart.bind(this); this.overlayService.opening.pipe(takeUntil(this._destroy$)).subscribe(() => { - document.addEventListener('touchstart', this.onDocumentTouchStart, { passive: true }); + this._document.addEventListener('touchstart', this.onDocumentTouchStart, { passive: true }); }); this.overlayService.closed.pipe(takeUntil(this._destroy$)).subscribe(() => { - document.removeEventListener('touchstart', this.onDocumentTouchStart); + this._document.removeEventListener('touchstart', this.onDocumentTouchStart); }); } @@ -133,7 +134,7 @@ export class IgxTooltipDirective extends IgxToggleDirective implements OnDestroy public override ngOnDestroy() { super.ngOnDestroy(); - document.removeEventListener('touchstart', this.onDocumentTouchStart); + this._document.removeEventListener('touchstart', this.onDocumentTouchStart); this._destroy$.next(true); this._destroy$.complete(); } From dd329690790b2ad28ebd4644450c5c29f693ca8f Mon Sep 17 00:00:00 2001 From: Simeon Simeonoff Date: Mon, 23 Jun 2025 14:53:05 +0300 Subject: [PATCH 19/29] fix(calendar): adhere to ISO 8601 when calculating week number if the week starts on Monday (#15964) --- .../lib/calendar/calendar.component.spec.ts | 25 ++-- .../src/lib/calendar/common/model.spec.ts | 124 +++++++++++++++++- .../src/lib/calendar/common/model.ts | 103 ++++++++++++++- .../calendar/days-view/days-view.component.ts | 2 +- src/app/calendar/calendar.sample.ts | 25 +++- .../properties-panel.component.html | 4 +- .../properties-panel.component.ts | 4 +- .../property-change.service.ts | 2 +- 8 files changed, 257 insertions(+), 32 deletions(-) diff --git a/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts b/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts index 1a4454e13af..9da0f57cb38 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts +++ b/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts @@ -596,18 +596,13 @@ describe("IgxCalendar - ", () => { By.css(`${HelperTestFunctions.CALENDAR_ROW_CSSCLASS}`), ); + const expectedWeeks = ["W", "1", "2", "3", "4", "5", "6"]; + calendarRows.forEach((row, idx) => { const firstRowItem = row.nativeElement.children[0]; - - if (idx === 0) { - expect(firstRowItem.firstChild.innerText).toEqual( - "W", - ); - } else { - expect(firstRowItem.firstChild.innerText).toEqual( - idx.toString(), - ); - } + expect(firstRowItem.firstChild.innerText).toEqual( + expectedWeeks[idx], + ); }); }); @@ -626,12 +621,7 @@ describe("IgxCalendar - ", () => { const firstRowItem = row.nativeElement.children[0]; if (idx === 5) { expect(firstRowItem.firstChild.innerText).toEqual( - "13", - ); - } - if (idx === 6) { - expect(firstRowItem.firstChild.innerText).toEqual( - "14", + "12", ); } }); @@ -648,7 +638,7 @@ describe("IgxCalendar - ", () => { const firstRowItem = row.nativeElement.children[0]; if (idx === 5) { expect(firstRowItem.firstChild.innerText).toEqual( - "44", + "43", ); } }); @@ -664,6 +654,7 @@ describe("IgxCalendar - ", () => { calendarRowsDec.forEach((row, idx) => { const firstRowItem = row.nativeElement.children[0]; if (idx === 6) { + // With simple counting for Sunday start, expect 53 expect(firstRowItem.firstChild.innerText).toEqual( "53", ); diff --git a/projects/igniteui-angular/src/lib/calendar/common/model.spec.ts b/projects/igniteui-angular/src/lib/calendar/common/model.spec.ts index ee8ed28d1df..1c7362932fa 100644 --- a/projects/igniteui-angular/src/lib/calendar/common/model.spec.ts +++ b/projects/igniteui-angular/src/lib/calendar/common/model.spec.ts @@ -20,9 +20,13 @@ describe("Calendar Day Model", () => { const { year, month, date } = firstOfJan; expect([year, month, date]).toEqual([2024, 0, 1]); - // First week of 2024 + // First week of 2024 (ISO 8601 - January 1, 2024 is Monday, so Week 1) expect(firstOfJan.week).toEqual(1); + // Test week numbering with different week starts + expect(firstOfJan.getWeekNumber(1)).toEqual(1); // Monday start (ISO 8601) + expect(firstOfJan.getWeekNumber(0)).toBeGreaterThan(50); // Sunday start (belongs to prev year) + // 2024/01/01 is a Monday expect(firstOfJan.day).toEqual(1); expect(firstOfJan.weekend).toBeFalse(); @@ -79,6 +83,124 @@ describe("Calendar Day Model", () => { }); }); + describe("Week numbering", () => { + it("should use ISO 8601 for Monday start and simple counting for others", () => { + // January 1, 2025 is a Wednesday + const jan1_2025 = new CalendarDay({ year: 2025, month: 0, date: 1 }); + expect(jan1_2025.day).toEqual(3); // Wednesday + + // Monday start: Uses ISO 8601 standard + expect(jan1_2025.getWeekNumber(1)).toEqual(1); // Week 1 contains Jan 1 + + // Sunday start: Uses simple counting - Jan 1 (Wed) belongs to prev year + expect(jan1_2025.getWeekNumber(0)).toBeGreaterThan(50); // Week 52 of 2024 + }); + + it("should handle ISO 8601 year boundaries for Monday start", () => { + // January 1, 2026 is a Thursday + const jan1_2026 = new CalendarDay({ year: 2026, month: 0, date: 1 }); + expect(jan1_2026.day).toEqual(4); // Thursday + + // Monday start: ISO 8601 logic applies + expect(jan1_2026.getWeekNumber(1)).toEqual(1); // Week 1 of 2026 + }); + + it("should handle previous year's last week for Monday start", () => { + // January 1, 2027 is a Friday + const jan1_2027 = new CalendarDay({ year: 2027, month: 0, date: 1 }); + expect(jan1_2027.day).toEqual(5); // Friday + + // Monday start: ISO 8601 logic - belongs to previous year + const actualWeek = jan1_2027.getWeekNumber(1); + expect(actualWeek).toBeGreaterThan(50); // Should be Week 52 or 53 of 2026 + }); + + it("should work correctly with custom week starts using appropriate logic", () => { + const testDate = new CalendarDay({ year: 2024, month: 2, date: 15 }); // March 15, 2024 (Friday) + + // Test different week start days + const mondayStart = testDate.getWeekNumber(1); // ISO 8601 + const tuesdayStart = testDate.getWeekNumber(2); // Simple counting + const wednesdayStart = testDate.getWeekNumber(3); // Simple counting + const thursdayStart = testDate.getWeekNumber(4); // Simple counting + const fridayStart = testDate.getWeekNumber(5); // Simple counting + const saturdayStart = testDate.getWeekNumber(6); // Simple counting + const sundayStart = testDate.getWeekNumber(0); // Simple counting + + // All should be valid week numbers (positive integers) + expect(mondayStart).toBeGreaterThan(0); + expect(tuesdayStart).toBeGreaterThan(0); + expect(wednesdayStart).toBeGreaterThan(0); + expect(thursdayStart).toBeGreaterThan(0); + expect(fridayStart).toBeGreaterThan(0); + expect(saturdayStart).toBeGreaterThan(0); + expect(sundayStart).toBeGreaterThan(0); + }); + + it("should apply ISO 8601 logic only for Monday start", () => { + // January 4, 2024 is a Thursday - always Week 1 in ISO 8601 + const jan4_2024 = new CalendarDay({ year: 2024, month: 0, date: 4 }); + expect(jan4_2024.day).toEqual(4); // Thursday + + // Only Monday start uses ISO 8601 + expect(jan4_2024.getWeekNumber(1)).toEqual(1); // Monday start: ISO 8601 + + // Other starts use simple counting, so results may vary + const sundayWeek = jan4_2024.getWeekNumber(0); + const tuesdayWeek = jan4_2024.getWeekNumber(2); + expect(sundayWeek).toBeGreaterThan(0); + expect(tuesdayWeek).toBeGreaterThan(0); + }); + + it("should handle December dates that belong to next year's Week 1 for Monday start", () => { + // December 30, 2024 is a Monday + const dec30_2024 = new CalendarDay({ year: 2024, month: 11, date: 30 }); + expect(dec30_2024.day).toEqual(1); // Monday + + // Monday start: This should be Week 1 of 2025 in ISO 8601 + expect(dec30_2024.getWeekNumber(1)).toEqual(1); // Week 1 of 2025 + }); + + it("should default to Monday start when no parameter provided", () => { + const testDate = new CalendarDay({ year: 2024, month: 0, date: 1 }); + + // Should default to Monday start (ISO 8601 standard) + expect(testDate.getWeekNumber()).toEqual(testDate.getWeekNumber(1)); + expect(testDate.week).toEqual(testDate.getWeekNumber(1)); + }); + + it("should handle leap years correctly", () => { + // Test February 29, 2024 (leap year) + const feb29_2024 = new CalendarDay({ year: 2024, month: 1, date: 29 }); + expect(feb29_2024.day).toEqual(4); // Thursday + + // Should calculate week number correctly for leap year date + const weekNumber = feb29_2024.getWeekNumber(1); + expect(weekNumber).toBeGreaterThan(0); + expect(weekNumber).toBeLessThan(54); // Valid week range + }); + + it("should correctly handle the January 2024 Sunday start case", () => { + // January 1, 2024 is a Monday, with Sunday start (0) + const jan1_2024 = new CalendarDay({ year: 2024, month: 0, date: 1 }); + const jan7_2024 = new CalendarDay({ year: 2024, month: 0, date: 7 }); // Sunday + const jan8_2024 = new CalendarDay({ year: 2024, month: 0, date: 8 }); // Monday + + expect(jan1_2024.day).toEqual(1); // Monday + expect(jan7_2024.day).toEqual(0); // Sunday + expect(jan8_2024.day).toEqual(1); // Monday + + // With Sunday start, Jan 1 should be in previous year's last week + expect(jan1_2024.getWeekNumber(0)).toBeGreaterThan(50); // Week 53 of 2023 + + // Jan 7 (first Sunday) should be Week 1 + expect(jan7_2024.getWeekNumber(0)).toEqual(1); + + // Jan 8 should also be Week 1 (same week as Jan 7) + expect(jan8_2024.getWeekNumber(0)).toEqual(1); + }); + }); + describe("Date ranges", () => { start = new CalendarDay({ year: 2024, month: 0, date: 11 }); const endFuture = start.add("day", 7); diff --git a/projects/igniteui-angular/src/lib/calendar/common/model.ts b/projects/igniteui-angular/src/lib/calendar/common/model.ts index 43b57bfac62..b91c878d303 100644 --- a/projects/igniteui-angular/src/lib/calendar/common/model.ts +++ b/projects/igniteui-angular/src/lib/calendar/common/model.ts @@ -115,13 +115,104 @@ export class CalendarDay { return this._date.getTime(); } - /** Returns the current week number. */ + /** Returns the ISO 8601 week number. */ public get week() { - const firstDay = new CalendarDay({ year: this.year, month: 0 }) - .timestamp; - const currentDay = - (this.timestamp - firstDay + millisecondsInDay) / millisecondsInDay; - return Math.ceil(currentDay / daysInWeek); + return this.getWeekNumber(); + } + + /** + * Gets the week number based on week start day. + * Uses ISO 8601 (first Thursday rule) only when weekStart is Monday (1). + * For other week starts, uses simple counting from January 1st. + */ + public getWeekNumber(weekStart: number = 1): number { + if (weekStart === 1) { + return this.calculateISO8601WeekNumber(); + } else { + return this.calculateSimpleWeekNumber(weekStart); + } + } + + /** + * Calculates week number using ISO 8601 standard (Monday start, first Thursday rule). + */ + private calculateISO8601WeekNumber(): number { + const currentThursday = this.getThursdayOfWeek(); + const firstWeekThursday = this.getFirstWeekThursday(currentThursday.year); + + const weeksDifference = this.getWeeksDifference(currentThursday, firstWeekThursday); + const weekNumber = weeksDifference + 1; + + // Handle dates that belong to the previous year's last week + if (weekNumber <= 0) { + return this.getPreviousYearLastWeek(currentThursday.year - 1); + } + + return weekNumber; + } + + /** + * Calculates week number using simple counting from January 1st. + */ + private calculateSimpleWeekNumber(weekStart: number): number { + const yearStart = new CalendarDay({ year: this.year, month: 0, date: 1 }); + const yearStartDay = yearStart.day; + + const daysUntilFirstWeek = (weekStart - yearStartDay + 7) % 7; + + if (daysUntilFirstWeek > 0) { + const firstWeekStart = yearStart.add('day', daysUntilFirstWeek); + + if (this.timestamp < firstWeekStart.timestamp) { + const prevYear = this.year - 1; + const prevYearDec31 = new CalendarDay({ year: prevYear, month: 11, date: 31 }); + return prevYearDec31.calculateSimpleWeekNumber(weekStart); + } + + const daysSinceFirstWeek = Math.floor((this.timestamp - firstWeekStart.timestamp) / millisecondsInDay); + return Math.floor(daysSinceFirstWeek / 7) + 1; + } else { + const daysSinceYearStart = Math.floor((this.timestamp - yearStart.timestamp) / millisecondsInDay); + return Math.floor(daysSinceYearStart / 7) + 1; + } + } + + /** + * Gets the Thursday of the current date's week (ISO 8601 helper). + */ + private getThursdayOfWeek(): CalendarDay { + const dayOffset = (this.day - 1 + 7) % 7; // Monday start + const thursdayOffset = 3; // Thursday is 3 days from Monday + return this.add('day', thursdayOffset - dayOffset); + } + + /** + * Gets the Thursday of the first week of the given year (ISO 8601 helper). + */ + private getFirstWeekThursday(year: number): CalendarDay { + const january4th = new CalendarDay({ year, month: 0, date: 4 }); + const dayOffset = (january4th.day - 1 + 7) % 7; // Monday start + const thursdayOffset = 3; // Thursday is 3 days from Monday + return january4th.add('day', thursdayOffset - dayOffset); + } + + /** + * Calculates the number of weeks between two Thursday dates (ISO 8601 helper). + */ + private getWeeksDifference(currentThursday: CalendarDay, firstWeekThursday: CalendarDay): number { + const daysDifference = Math.floor((currentThursday.timestamp - firstWeekThursday.timestamp) / millisecondsInDay); + return Math.floor(daysDifference / 7); + } + + /** + * Gets the last week number of the previous year (ISO 8601 helper). + */ + private getPreviousYearLastWeek(previousYear: number): number { + const december31st = new CalendarDay({ year: previousYear, month: 11, date: 31 }); + const lastWeekThursday = december31st.getThursdayOfWeek(); + const firstWeekThursday = this.getFirstWeekThursday(previousYear); + + return this.getWeeksDifference(lastWeekThursday, firstWeekThursday) + 1; } /** Returns the underlying native date instance. */ diff --git a/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts b/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts index cba03ba1379..173dbbce11d 100644 --- a/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts @@ -378,7 +378,7 @@ export class IgxDaysViewComponent extends IgxCalendarBaseDirective { * @hidden */ public getWeekNumber(date: CalendarDay): number { - return date.week; + return date.getWeekNumber(this.weekStart); } /** diff --git a/src/app/calendar/calendar.sample.ts b/src/app/calendar/calendar.sample.ts index 97bfe6d7c24..6d4827504a6 100644 --- a/src/app/calendar/calendar.sample.ts +++ b/src/app/calendar/calendar.sample.ts @@ -67,8 +67,29 @@ export class CalendarSampleComponent implements OnInit { label: 'Change Locale', control: { type: 'button-group', - options: ['EN', 'BG', 'DE', 'FR', 'JP'], - defaultValue: 'EN' + options: [ + { + value: 'en-US', + label: 'EN' + }, + { + value: 'bg-BG', + label: 'BG' + }, + { + value: 'de-DE', + label: 'DE' + }, + { + value: 'fr-FR', + label: 'FR' + }, + { + value: 'ja-JP', + label: 'JP' + } + ], + defaultValue: 'en-US' } }, weekStart: { diff --git a/src/app/properties-panel/properties-panel.component.html b/src/app/properties-panel/properties-panel.component.html index 4817e1bd28f..3063b6e079b 100644 --- a/src/app/properties-panel/properties-panel.component.html +++ b/src/app/properties-panel/properties-panel.component.html @@ -79,8 +79,8 @@
Properties Panel
@for (option of getControlOptions(key); track option) { } diff --git a/src/app/properties-panel/properties-panel.component.ts b/src/app/properties-panel/properties-panel.component.ts index c71af167c39..f63ea0afbf6 100644 --- a/src/app/properties-panel/properties-panel.component.ts +++ b/src/app/properties-panel/properties-panel.component.ts @@ -124,11 +124,11 @@ export class PropertiesPanelComponent { return this.config[key].control.options; } - protected getControlLabels(key: string): string[] { + protected getControlLabels(key: string): string[] | { label: string, value: any }[] { const labels = this.config[key].control.labels || []; const options = this.getControlOptions(key); return labels.length > 0 ? labels - : options.map((option) => option.toString()); + : options.map((option) => option.label || option.toString()); } } diff --git a/src/app/properties-panel/property-change.service.ts b/src/app/properties-panel/property-change.service.ts index 75b6be95c8d..0448b055d5b 100644 --- a/src/app/properties-panel/property-change.service.ts +++ b/src/app/properties-panel/property-change.service.ts @@ -21,7 +21,7 @@ export type PropertyPanelConfig = { label?: string; control: { type: ControlType, - options?: string[]; + options?: string[] | { label: string, value: any }[]; labels?: string[]; min?: number; max?: number; From 3674f8da8ab5a5365b237d479eee18e184a27601 Mon Sep 17 00:00:00 2001 From: Maya Date: Tue, 24 Jun 2025 10:57:33 +0300 Subject: [PATCH 20/29] fix(IgxGrid): Don't use spread operator for large collections. (#15915) --- .../src/lib/grids/common/strategy.ts | 17 ++++++------ .../src/lib/grids/grid/grid.groupby.spec.ts | 26 +++++++++++++++++++ 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/projects/igniteui-angular/src/lib/grids/common/strategy.ts b/projects/igniteui-angular/src/lib/grids/common/strategy.ts index 5dd74d52c23..69912780031 100644 --- a/projects/igniteui-angular/src/lib/grids/common/strategy.ts +++ b/projects/igniteui-angular/src/lib/grids/common/strategy.ts @@ -76,7 +76,7 @@ export class IgxSorting implements IGridSortingStrategy { grid: GridType = null, groupsRecords: any[] = [], fullResult: IGroupByResult = { data: [], metadata: [] } - ): any[] { + ): IGroupByResult { const expressions = state.expressions; const expansion = state.expansion; let i = 0; @@ -117,9 +117,10 @@ export class IgxSorting implements IGridSortingStrategy { fullResult.metadata.push(null); if (level < expressions.length - 1) { recursiveResult = this.groupDataRecursive(group, state, level + 1, groupRow, - expanded ? metadata : [], grid, groupsRecords, fullResult); + [], grid, groupsRecords, fullResult); if (expanded) { - result = result.concat(recursiveResult); + result = result.concat(recursiveResult.data); + metadata = metadata.concat(recursiveResult.metadata); } } else { for (const groupItem of group) { @@ -127,13 +128,13 @@ export class IgxSorting implements IGridSortingStrategy { fullResult.data.push(groupItem); } if (expanded) { - metadata.push(...fullResult.metadata.slice(fullResult.metadata.length - group.length)); - result.push(...fullResult.data.slice(fullResult.data.length - group.length)); + metadata = metadata.concat(fullResult.metadata.slice(fullResult.metadata.length - group.length)); + result = result.concat(fullResult.data.slice(fullResult.data.length - group.length)); } } i += group.length; } - return result; + return { data: result, metadata }; } /** @@ -264,8 +265,8 @@ export class IgxGrouping extends IgxSorting implements IGridGroupingStrategy { const grouping = this.groupDataRecursive(data, state, 0, null, metadata, grid, groupsRecords, fullResult); grid?.groupingPerformedSubject.next(); return { - data: grouping, - metadata + data: grouping.data, + metadata: grouping.metadata }; } } diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid.groupby.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/grid.groupby.spec.ts index a3d968f03d0..aa9dc341bf8 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid.groupby.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/grid.groupby.spec.ts @@ -3822,6 +3822,32 @@ describe('IgxGrid - GroupBy #grid', () => { } }); + it('should be able to build groups with 100 000+ records', () => { + const fix = TestBed.createComponent(GroupableGridComponent); + const grid = fix.componentInstance.instance; + + const data = []; + for (let i = 0; i < 1000000; i++) { + data.push({ + Downloads: i, + ID: 1, + ProductName: 'Test' + }); + } + + fix.componentInstance.data = data; + fix.detectChanges(); + + grid.groupBy({ + fieldName: 'ProductName', + dir: SortingDirection.Asc + }); + fix.detectChanges(); + + let groupRows = grid.groupsRowList.toArray(); + checkGroups(groupRows, ['Test']); + }); + describe('GroupBy with state directive', () => { let fix: ComponentFixture; let state: IgxGridStateDirective; From 3a1c7c4b5cb1cacbd417b607fa68f130f6c706a6 Mon Sep 17 00:00:00 2001 From: Maya Date: Tue, 24 Jun 2025 14:47:36 +0300 Subject: [PATCH 21/29] fix(igxHierarchicalGrid): Update existing child grids for RI on change. (#15934) --- .../hierarchical-grid.spec.ts | 32 +++++++++++++++++++ .../hierarchical-grid/row-island.component.ts | 2 +- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.spec.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.spec.ts index c4186f15c9f..7db4299d1f3 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.spec.ts @@ -1685,6 +1685,33 @@ describe('Basic IgxHierarchicalGrid #hGrid', () => { }); + it('should allow changing row islands runtime in nested child grid.', () => { + const row = hierarchicalGrid.gridAPI.get_row_by_index(0) as IgxHierarchicalRowComponent; + UIInteractions.simulateClickAndSelectEvent(row.expander); + fixture.detectChanges(); + + let childGrid = hierarchicalGrid.gridAPI.getChildGrids()[0]; + const childRow = childGrid.gridAPI.get_row_by_index(0) as IgxHierarchicalRowComponent; + UIInteractions.simulateClickAndSelectEvent(childRow.expander); + fixture.detectChanges(); + + let hGrids = fixture.debugElement.queryAll(By.css('igx-hierarchical-grid')); + expect(hGrids.length).toBe(3); + expect(childGrid.gridAPI.getChildGrids().length).toBe(1); + + fixture.componentInstance.toggleRINested = true; + fixture.detectChanges(); + + const nestedChildGrid = childGrid.gridAPI.getChildGrids()[0]; + const nestedChildRow = nestedChildGrid.gridAPI.get_row_by_index(0) as IgxHierarchicalRowComponent; + UIInteractions.simulateClickAndSelectEvent(nestedChildRow.expander); + fixture.detectChanges(); + + hGrids = fixture.debugElement.queryAll(By.css('igx-hierarchical-grid')); + expect(hGrids.length).toBe(4); + expect(nestedChildGrid.gridAPI.getChildGrids().length).toBe(1); + }); + it(`Should apply template to both parent and child grids`, () => { const customFixture = TestBed.createComponent(IgxHierarchicalGridCustomRowEditOverlayComponent); customFixture.detectChanges(); @@ -2146,6 +2173,10 @@ export class IgxHierarchicalGridSizingComponent { @if (toggleChildRI) { + @if (toggleRINested) { + + + } } @@ -2156,6 +2187,7 @@ export class IgxHierarchicalGridSizingComponent { export class IgxHierarchicalGridToggleRIComponent extends IgxHierarchicalGridTestBaseComponent { public toggleRI = true; public toggleChildRI = true; +public toggleRINested = false; } @Component({ diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/row-island.component.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/row-island.component.ts index d2e18131a4f..e0ec1491026 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/row-island.component.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/row-island.component.ts @@ -438,7 +438,7 @@ export class IgxRowIslandComponent extends IgxHierarchicalGridBaseDirective .subscribe(() => { this.updateChildren(); // update existing grids since their child ri have been changed. - this.getGridsForIsland(this.key).forEach(grid => { + this.rowIslandAPI.getChildGrids(false).forEach(grid => { (grid as any).onRowIslandChange(this.children); }); }); From 18ca4240d63a1b263ab34ed77bd478f1b85db1a3 Mon Sep 17 00:00:00 2001 From: Maya Date: Tue, 24 Jun 2025 15:07:26 +0300 Subject: [PATCH 22/29] fix(igxGrid): Use default scheduler when throttling. (#15884) --- projects/igniteui-angular/src/lib/grids/grid-base.directive.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts b/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts index 5213151e54e..62ae570165d 100644 --- a/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts +++ b/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts @@ -3813,7 +3813,7 @@ export abstract class IgxGridBaseDirective implements GridType, // notifier for column autosize requests this._autoSizeColumnsNotify.pipe( - throttleTime(0, animationFrameScheduler, { leading: false, trailing: true }), + throttleTime(0, this.platform.isBrowser ? animationFrameScheduler : undefined, { leading: false, trailing: true }), destructor ) .subscribe(() => { From 3a5d4e31131a5df77db2dbd0f1a732835449f33f Mon Sep 17 00:00:00 2001 From: Marin Popov Date: Wed, 25 Jun 2025 10:16:29 +0300 Subject: [PATCH 23/29] fix(input-group): use the correct variable for focus bg (#15909) Co-authored-by: Simeon Simeonoff --- .../lib/core/styles/components/input/_input-group-theme.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/igniteui-angular/src/lib/core/styles/components/input/_input-group-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/input/_input-group-theme.scss index 36ab839fdcf..f641fe6b10e 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/input/_input-group-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/input/_input-group-theme.scss @@ -1928,7 +1928,7 @@ } %indigo--box-focused { - background: var-get($theme, 'box-background-hover'); + background: var-get($theme, 'box-background-focus'); } %form-group-bundle--indigo--disabled { From cac01386ab4ec4bb48ba47910761c3eaa6779172 Mon Sep 17 00:00:00 2001 From: Dilyana Yarabanova <45598235+didimmova@users.noreply.github.com> Date: Wed, 25 Jun 2025 10:43:34 +0300 Subject: [PATCH 24/29] fix(grid): fix grid shadows (#15990) --- .../src/lib/core/styles/components/grid/_grid-theme.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 145d5f0dae8..df959a4eac5 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 @@ -456,12 +456,12 @@ @if not($grid-shadow) { $grid-elevation: map.get($grid-schema, 'grid-elevation'); - $grid-shadow: elevation(var(--grid-elevation)); + $grid-shadow: elevation($grid-elevation); } @if not($drag-shadow) { $drag-elevation: map.get($grid-schema, 'drag-elevation'); - $drag-shadow: elevation(var(--drag-elevation)); + $drag-shadow: elevation($drag-elevation); } @if not($drop-area-border-radius) { From 6cc820626160b0c036ce4c23e51fc8340774b376 Mon Sep 17 00:00:00 2001 From: Adrian Petrov <99720888+adrianptrv@users.noreply.github.com> Date: Thu, 26 Jun 2025 11:03:03 +0300 Subject: [PATCH 25/29] fix(grid): cropped invalid cell icon (#15991) --- .../styles/components/grid/_grid-theme.scss | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) 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 df959a4eac5..3c300860ba1 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 @@ -758,8 +758,7 @@ igx-time-picker { position: relative; height: calc(100% - #{$editing-outline-width * 2}); - width: calc(100% - #{$editing-outline-width * 2}) !important; - inset-inline-start: $editing-outline-width; + width: 100% !important; overflow: hidden; } @@ -1804,7 +1803,6 @@ padding-inline-end: rem(4px) !important; > igx-icon { - margin-inline-start: auto; color: color($color: 'error'); width: var(--igx-icon-size, rem(18px)); height: var(--igx-icon-size, rem(18px)); @@ -1910,11 +1908,10 @@ %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: 0 !important; + padding-inline: rem(4px); &.igx-grid__td--invalid { box-shadow: inset 0 0 0 rem(2px) color($color: 'error') !important; - padding-inline-end: rem(4px) !important; } &%grid-cell-number { @@ -2105,7 +2102,7 @@ .sort-icon { color: var-get($theme, 'header-selected-text-color'); - + ::after { background: var-get($theme, 'header-selected-background'); } @@ -2133,7 +2130,7 @@ &%igx-grid-th--sorted { .sort-icon { color: var-get($theme, 'header-selected-text-color'); - + > igx-icon { color: inherit; } @@ -2141,7 +2138,7 @@ &:focus, &:hover { color: var-get($theme, 'header-selected-text-color'); - + > igx-icon { color: inherit; } @@ -2198,14 +2195,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; } From 6625eeb45fd9afa51b97c0c4e9e3791411dc62e2 Mon Sep 17 00:00:00 2001 From: Maya Date: Thu, 26 Jun 2025 14:23:16 +0300 Subject: [PATCH 26/29] Merge pull request #15993 from IgniteUI/mkirova/fix-15379 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix(igxGrid): Trigger validation based on initial value for when adde… --- .../src/lib/grids/grid/grid-validation.service.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid-validation.service.ts b/projects/igniteui-angular/src/lib/grids/grid/grid-validation.service.ts index 6c0941ffb5d..a80a8aab95a 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid-validation.service.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/grid-validation.service.ts @@ -36,6 +36,7 @@ export class IgxGridValidationService { owner: this.grid }; this.grid.formGroupCreated.emit(args); + formGroup.patchValue(data); this.add(rowId, formGroup); } else { // reset to pristine. From cd00bb32460cac3b59f26d9433e1e39429ccda85 Mon Sep 17 00:00:00 2001 From: Silvia Ivanova <59446295+SisIvanova@users.noreply.github.com> Date: Thu, 26 Jun 2025 16:56:52 +0300 Subject: [PATCH 27/29] refactor(drop-down): items icon size (#15967) --- .../components/drop-down/_drop-down-theme.scss | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/projects/igniteui-angular/src/lib/core/styles/components/drop-down/_drop-down-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/drop-down/_drop-down-theme.scss index 269339629f1..c3e7b03b572 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/drop-down/_drop-down-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/drop-down/_drop-down-theme.scss @@ -299,20 +299,16 @@ bottom: 0; } - igx-icon { + igx-icon, + igc-icon { justify-content: center; - --component-size: 1; - - @if $variant == 'fluent' { - --component-size: 3; - } @if $variant == 'indigo' { $icon-size: sizable(rem(14px), rem(16px), rem(16px)); - width: var(--ig-icon-size, $icon-size); - height: var(--ig-icon-size, $icon-size); - font-size: var(--ig-icon-size, $icon-size); + --size: #{$icon-size}; + } @else { + --component-size: 1; } } } From 500cbe8701420a265b8acab75bafed8df6f75728 Mon Sep 17 00:00:00 2001 From: Maya Date: Fri, 27 Jun 2025 14:44:29 +0300 Subject: [PATCH 28/29] fix(igxSplitter): Assign pane props after zone is stable. (#15888) --- .../splitter-pane/splitter-pane.component.ts | 10 +++++-- .../lib/splitter/splitter.component.spec.ts | 26 ++++++++++++++++++- .../src/lib/splitter/splitter.component.ts | 15 ++++++----- 3 files changed, 42 insertions(+), 9 deletions(-) diff --git a/projects/igniteui-angular/src/lib/splitter/splitter-pane/splitter-pane.component.ts b/projects/igniteui-angular/src/lib/splitter/splitter-pane/splitter-pane.component.ts index d58a2d227ed..eb8802bac6a 100644 --- a/projects/igniteui-angular/src/lib/splitter/splitter-pane/splitter-pane.component.ts +++ b/projects/igniteui-angular/src/lib/splitter/splitter-pane/splitter-pane.component.ts @@ -1,4 +1,4 @@ -import { Component, HostBinding, Input, ElementRef, Output, EventEmitter, booleanAttribute } from '@angular/core'; +import { Component, HostBinding, Input, ElementRef, Output, EventEmitter, booleanAttribute, signal } from '@angular/core'; /** * Represents individual resizable/collapsible panes. @@ -22,6 +22,7 @@ import { Component, HostBinding, Input, ElementRef, Output, EventEmitter, boolea export class IgxSplitterPaneComponent { private _minSize: string; private _maxSize: string; + private _order = signal(null); /** * @hidden @internal @@ -102,7 +103,12 @@ export class IgxSplitterPaneComponent { /** @hidden @internal */ @HostBinding('style.order') - public order!: number; + public get order() { + return this._order(); + } + public set order(val) { + this._order.set(val) + } /** * @hidden @internal diff --git a/projects/igniteui-angular/src/lib/splitter/splitter.component.spec.ts b/projects/igniteui-angular/src/lib/splitter/splitter.component.spec.ts index 63a079c7e76..927e7bd8ae4 100644 --- a/projects/igniteui-angular/src/lib/splitter/splitter.component.spec.ts +++ b/projects/igniteui-angular/src/lib/splitter/splitter.component.spec.ts @@ -33,7 +33,7 @@ describe('IgxSplitter', () => { const secondPane = splitter.panes.toArray()[1].element; expect(firstPane.textContent.trim()).toBe('Pane 1'); expect(secondPane.textContent.trim()).toBe('Pane 2'); - + fixture.detectChanges(); const splitterBar = fixture.debugElement.query(By.css(SPLITTERBAR_CLASS)).nativeElement; expect(firstPane.style.order).toBe('0'); expect(splitterBar.style.order).toBe('1'); @@ -322,6 +322,13 @@ describe('IgxSplitter', () => { expect(splitterBarComponent.style.transform).not.toBe('translate3d(0px, 0px, 0px)'); }); + + it('should render correctly panes created dynamically using @for', () => { + fixture = TestBed.createComponent(SplitterForOfPanesComponent); + fixture.detectChanges(); + splitter = fixture.componentInstance.splitter; + expect(splitter.panes.length).toBe(3); + }); }); describe('IgxSplitter pane toggle', () => { @@ -336,6 +343,7 @@ describe('IgxSplitter pane toggle', () => { fixture = TestBed.createComponent(SplitterTogglePaneComponent); fixture.detectChanges(); splitter = fixture.componentInstance.splitter; + fixture.detectChanges(); })); it('should collapse/expand panes', () => { @@ -601,3 +609,19 @@ export class SplitterTogglePaneComponent extends SplitterTestComponent { }) export class SplitterCollapsedPaneComponent extends SplitterTestComponent { } + +@Component({ + template: ` + + @for (number of numbers; track number) { + +

{{ number }}

+
+ } +
+ `, + imports: [IgxSplitterComponent, IgxSplitterPaneComponent] +}) +export class SplitterForOfPanesComponent extends SplitterTestComponent { + public numbers = [1, 2, 3]; +} diff --git a/projects/igniteui-angular/src/lib/splitter/splitter.component.ts b/projects/igniteui-angular/src/lib/splitter/splitter.component.ts index 24ff3644913..6ca08559410 100644 --- a/projects/igniteui-angular/src/lib/splitter/splitter.component.ts +++ b/projects/igniteui-angular/src/lib/splitter/splitter.component.ts @@ -1,6 +1,7 @@ -import { AfterContentInit, Component, ContentChildren, ElementRef, EventEmitter, HostBinding, HostListener, Inject, Input, Output, QueryList, booleanAttribute, forwardRef, DOCUMENT } from '@angular/core'; +import { AfterContentInit, Component, ContentChildren, ElementRef, EventEmitter, HostBinding, HostListener, Inject, Input, NgZone, Output, QueryList, booleanAttribute, forwardRef, DOCUMENT } from '@angular/core'; import { DragDirection, IDragMoveEventArgs, IDragStartEventArgs, IgxDragDirective, IgxDragIgnoreDirective } from '../directives/drag-drop/drag-drop.directive'; import { IgxSplitterPaneComponent } from './splitter-pane/splitter-pane.component'; +import { take } from 'rxjs'; /** * An enumeration that defines the `SplitterComponent` panes orientation. @@ -154,7 +155,7 @@ export class IgxSplitterComponent implements AfterContentInit { */ private sibling!: IgxSplitterPaneComponent; - constructor(@Inject(DOCUMENT) public document, private elementRef: ElementRef) { } + constructor(@Inject(DOCUMENT) public document, private elementRef: ElementRef, private zone: NgZone) { } /** * Gets/Sets the splitter orientation. * @@ -197,7 +198,9 @@ export class IgxSplitterComponent implements AfterContentInit { /** @hidden @internal */ public ngAfterContentInit(): void { - this.initPanes(); + this.zone.onStable.pipe(take(1)).subscribe(() => { + this.initPanes(); + }); this.panes.changes.subscribe(() => { this.initPanes(); }); @@ -472,7 +475,7 @@ export class IgxSplitBarComponent { * @hidden @internal */ public get prevButtonHidden() { - return this.siblings[0].collapsed && !this.siblings[1].collapsed; + return this.siblings[0]?.collapsed && !this.siblings[1]?.collapsed; } /** @@ -559,7 +562,7 @@ export class IgxSplitBarComponent { * @hidden @internal */ public get nextButtonHidden() { - return this.siblings[1].collapsed && !this.siblings[0].collapsed; + return this.siblings[1]?.collapsed && !this.siblings[0]?.collapsed; } /** @@ -599,7 +602,7 @@ export class IgxSplitBarComponent { protected get resizeDisallowed() { const relatedTabs = this.siblings; - return !!relatedTabs.find(x => x.resizable === false || x.collapsed === true); + return !!relatedTabs.find(x => x?.resizable === false || x?.collapsed === true); } /** From 9953ebd3ec403099a2a559d33c89ef98d2b8911c Mon Sep 17 00:00:00 2001 From: IMinchev <61944284+IMinchev64@users.noreply.github.com> Date: Fri, 27 Jun 2025 16:36:58 +0300 Subject: [PATCH 29/29] fix(pivot-grid): Handle currency pivot values with count aggregator - master (#15894) --- .../pivot-data-selector.component.ts | 6 ++ .../grids/pivot-grid/pivot-grid.component.ts | 60 ++++++++++++------- .../pivot-grid/pivot-header-row.component.ts | 8 ++- .../src/lib/grids/pivot-grid/pivot-util.ts | 37 +++++++++--- 4 files changed, 79 insertions(+), 32 deletions(-) diff --git a/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-data-selector.component.ts b/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-data-selector.component.ts index e72a2b1b52c..52ce5e82670 100644 --- a/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-data-selector.component.ts +++ b/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-data-selector.component.ts @@ -47,6 +47,7 @@ import { IgxIconComponent } from "../../icon/icon.component"; import { IgxInputGroupComponent } from "../../input-group/input-group.component"; import { fadeIn, fadeOut } from 'igniteui-angular/animations'; import { Size } from '../common/enums'; +import { GridColumnDataType } from '../../data-operations/data-util'; interface IDataSelectorPanel { name: string; @@ -541,8 +542,13 @@ export class IgxPivotDataSelectorComponent { * @internal */ public onAggregationChange(event: ISelectionEventArgs) { + if (!this.isSelected(event.newSelection.value)) { this.value.aggregate = event.newSelection.value; + const isSingleValue = this.grid.values.length === 1; + + PivotUtil.updateColumnTypeByAggregator(this.grid.columns, this.value, isSingleValue); + this.grid.pipeTrigger++; this.grid.cdr.markForCheck(); } diff --git a/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-grid.component.ts b/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-grid.component.ts index 5cf939e1877..54dc1023651 100644 --- a/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-grid.component.ts +++ b/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-grid.component.ts @@ -32,12 +32,12 @@ import { } from '@angular/core'; import { NgTemplateOutlet, NgClass, NgStyle } from '@angular/common'; -import { first, take, takeUntil} from 'rxjs/operators'; +import { first, take, takeUntil } from 'rxjs/operators'; import { IgxGridBaseDirective } from '../grid-base.directive'; import { IgxFilteringService } from '../filtering/grid-filtering.service'; import { IgxGridSelectionService } from '../selection/selection.service'; import { IgxForOfSyncService, IgxForOfScrollSyncService } from '../../directives/for-of/for_of.sync.service'; -import { ColumnType, GridType, IGX_GRID_BASE, IGX_GRID_SERVICE_BASE, IgxColumnTemplateContext, RowType } from '../common/grid.interface'; +import { ColumnType, GridType, IGX_GRID_BASE, IGX_GRID_SERVICE_BASE, IgxColumnTemplateContext, PivotGridType, RowType } from '../common/grid.interface'; import { IgxGridCRUDService } from '../common/crud.service'; import { IgxGridSummaryService } from '../summaries/grid-summary.service'; import { DEFAULT_PIVOT_KEYS, IDimensionsChange, IgxPivotGridValueTemplateContext, IPivotConfiguration, IPivotConfigurationChangedEventArgs, IPivotDimension, IPivotValue, IValuesChange, PivotDimensionType, IPivotUISettings, PivotRowLayoutType, PivotSummaryPosition } from './pivot-grid.interface'; @@ -72,7 +72,7 @@ import { IgxPivotColumnResizingService } from '../resizing/pivot-grid/pivot-resi import { IgxFlatTransactionFactory, IgxOverlayService, State, Transaction, TransactionService } from '../../services/public_api'; import { cloneArray, PlatformUtil, resizeObservable } from '../../core/utils'; import { IgxPivotFilteringService } from './pivot-filtering.service'; -import { DataUtil } from '../../data-operations/data-util'; +import { DataUtil, GridColumnDataType } from '../../data-operations/data-util'; import { IFilteringExpressionsTree } from '../../data-operations/filtering-expressions-tree'; import { IgxGridTransaction } from '../common/types'; import { GridBaseAPIService } from '../api.service'; @@ -199,7 +199,7 @@ const MINIMUM_COLUMN_WIDTH_SUPER_COMPACT = 104; schemas: [CUSTOM_ELEMENTS_SCHEMA] }) export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnInit, AfterContentInit, - GridType, AfterViewInit, OnChanges { + PivotGridType, AfterViewInit, OnChanges { /** * Emitted when the dimension collection is changed via the grid chip area. @@ -1667,7 +1667,7 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni public autoSizeRowDimension(dimension: IPivotDimension) { if (this.getDimensionType(dimension) === PivotDimensionType.Row) { const relatedDims: string[] = PivotUtil.flatten([dimension]).map((x: IPivotDimension) => x.memberName); - const contentCollection = this.getContentCollection(dimension); + const contentCollection = this.getContentCollection(dimension); const content = contentCollection.filter(x => relatedDims.indexOf(x.dimension.memberName) !== -1); const headers = content.map(x => x.headerGroups.toArray()).flat().map(x => x.header && x.header.refInstance); if (this.pivotUI.showRowHeaders) { @@ -1941,8 +1941,8 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni */ public getRowDimensionByName(memberName: string) { const visibleRows = this.pivotUI.rowLayout === PivotRowLayoutType.Vertical ? - this.pivotConfiguration.rows : - PivotUtil.flatten(this.pivotConfiguration.rows); + this.pivotConfiguration.rows : + PivotUtil.flatten(this.pivotConfiguration.rows); const dimIndex = visibleRows.findIndex((target) => target.memberName === memberName); const dim = visibleRows[dimIndex]; return dim; @@ -2266,7 +2266,7 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni const separator = this.pivotKeys.columnDimensionSeparator; const dataArr = fields.map(x => x.split(separator)).sort(x => x.length); const hierarchy = new Map(); - const columnDimensions = PivotUtil.flatten(this.columnDimensions); + const columnDimensions = PivotUtil.flatten(this.columnDimensions); dataArr.forEach(arr => { let currentHierarchy = hierarchy; const path = []; @@ -2286,17 +2286,22 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni }); return hierarchy; } - protected generateColumnHierarchy(fields: Map, data, parent = null): IgxColumnComponent[] { let columns = []; if (fields.size === 0) { this.values.forEach((value) => { const ref = createComponent(IgxColumnComponent, { environmentInjector: this.envInjector, elementInjector: this.injector }); + let columnDataType = value.dataType || this.resolveDataTypes(data.length ? data[0][value.member] : null); + + if (value.aggregate?.key?.toLowerCase() === 'count' && (columnDataType === GridColumnDataType.Currency || columnDataType == GridColumnDataType.Percent)) { + columnDataType = GridColumnDataType.Number; + } + ref.instance.header = value.displayName; ref.instance.field = value.member; ref.instance.parent = parent; ref.instance.sortable = true; - ref.instance.dataType = value.dataType || this.resolveDataTypes(data.length ? data[0][value.member] : null); + ref.instance.dataType = columnDataType; ref.instance.formatter = value.formatter; columns.push(ref.instance); }); @@ -2310,9 +2315,20 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni } if (shouldGenerate && (value.children == null || value.children.length === 0 || value.children.size === 0)) { const col = this.createColumnForDimension(value, data, parent, this.hasMultipleValues); + + if (!this.hasMultipleValues && this.values.length > 0) { + PivotUtil.updateColumnTypeByAggregator([col], this.values[0], true); + } + columns.push(col); if (this.hasMultipleValues) { const measureChildren = this.getMeasureChildren(data, col, false, value.dimension.width); + + measureChildren.forEach((child, index) => { + const pivotValue = this.values[index]; + PivotUtil.updateColumnTypeByAggregator([child], pivotValue, this.values.length === 1); + }); + col.children.reset(measureChildren); columns = columns.concat(measureChildren); } @@ -2382,20 +2398,20 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni }; values.push(value); break; - } - case "date": - { - const dimension: IPivotDimension = new IgxPivotDateDimension( + } + case "date": { - memberName: field, - enabled: isFirstDate, - dataType: dataType + const dimension: IPivotDimension = new IgxPivotDateDimension( + { + memberName: field, + enabled: isFirstDate, + dataType: dataType + } + ) + rowDimensions.push(dimension); + isFirstDate = false; + break; } - ) - rowDimensions.push(dimension); - isFirstDate = false; - break; - } default: { const dimension: IPivotDimension = { memberName: field, diff --git a/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-header-row.component.ts b/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-header-row.component.ts index c59f905be90..d2510db1ac2 100644 --- a/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-header-row.component.ts +++ b/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-header-row.component.ts @@ -38,6 +38,7 @@ import { IgxDropDirective } from '../../directives/drag-drop/drag-drop.directive import { NgTemplateOutlet, NgClass, NgStyle } from '@angular/common'; import { IgxPivotRowHeaderGroupComponent } from './pivot-row-header-group.component'; import { IgxPivotRowDimensionHeaderGroupComponent } from './pivot-row-dimension-header-group.component'; +import { GridColumnDataType } from '../../data-operations/data-util'; /** * @@ -137,7 +138,7 @@ export class IgxPivotHeaderRowComponent extends IgxGridHeaderRowComponent implem @Inject(IGX_GRID_BASE) public override grid: PivotGridType, ref: ElementRef, cdr: ChangeDetectorRef, - protected renderer: Renderer2, + protected renderer: Renderer2 ) { super(ref, cdr); } @@ -407,8 +408,13 @@ export class IgxPivotHeaderRowComponent extends IgxGridHeaderRowComponent implem * @internal */ public onAggregationChange(event: ISelectionEventArgs) { + if (!this.isSelected(event.newSelection.value)) { this.value.aggregate = event.newSelection.value; + const isSingleValue = this.grid.values.length === 1; + + PivotUtil.updateColumnTypeByAggregator(this.grid.columns, this.value, isSingleValue); + this.grid.pipeTrigger++; } } diff --git a/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-util.ts b/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-util.ts index e4624251ca2..cd73c2360ed 100644 --- a/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-util.ts +++ b/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-util.ts @@ -3,7 +3,7 @@ import { DataUtil, GridColumnDataType } from '../../data-operations/data-util'; import { FilteringLogic } from '../../data-operations/filtering-expression.interface'; import { FilteringExpressionsTree } from '../../data-operations/filtering-expressions-tree'; import { ISortingExpression } from '../../data-operations/sorting-strategy'; -import { PivotGridType } from '../common/grid.interface'; +import { ColumnType, PivotGridType } from '../common/grid.interface'; import { IGridSortingStrategy, IgxSorting } from '../common/strategy'; import { IgxPivotAggregate, IgxPivotDateAggregate, IgxPivotNumericAggregate, IgxPivotTimeAggregate } from './pivot-grid-aggregate'; import { IPivotAggregator, IPivotConfiguration, IPivotDimension, IPivotGridRecord, IPivotKeys, IPivotValue, PivotDimensionType, PivotSummaryPosition } from './pivot-grid.interface'; @@ -88,13 +88,13 @@ export class PivotUtil { } public static flattenGroupsHorizontally(data: IPivotGridRecord[], - dimension: IPivotDimension, - expansionStates, - defaultExpand: boolean, - visibleDimensions: IPivotDimension[], - summariesPosition: PivotSummaryPosition, - parent?: IPivotDimension, - parentRec?: IPivotGridRecord) { + dimension: IPivotDimension, + expansionStates, + defaultExpand: boolean, + visibleDimensions: IPivotDimension[], + summariesPosition: PivotSummaryPosition, + parent?: IPivotDimension, + parentRec?: IPivotGridRecord) { for (let i = 0; i < data.length; i++) { const rec = data[i]; const field = dimension.memberName; @@ -316,7 +316,7 @@ export class PivotUtil { const aggregationKey = groupName ? groupName + pivotKeys.columnDimensionSeparator + key : key; rec.aggregationValues.set(aggregationKey, aggregationData[key]); }); - } else if (aggregationKeys.length === 1) { + } else if (aggregationKeys.length === 1) { const aggregationKey = aggregationKeys[0]; rec.aggregationValues.set(groupName || aggregationKey, aggregationData[aggregationKey]); } @@ -508,5 +508,24 @@ export class PivotUtil { } } + public static updateColumnTypeByAggregator(columns: any[], value: IPivotValue, isSingleValue: boolean): void { + const targetColumnType = PivotUtil.getColumnDataTypeForValue(value); + columns.forEach(column => { + if ((column.field?.includes(value.member) || isSingleValue) && targetColumnType !== undefined) { + column.dataType = targetColumnType; + } + }) + } + + private static getColumnDataTypeForValue(value: IPivotValue): GridColumnDataType { + const isCountAggregator = value.aggregate.aggregator?.name?.toLowerCase() === 'count' || value.aggregate.aggregatorName?.toLowerCase() === 'count'; + if ((value.dataType === GridColumnDataType.Currency || value.dataType === GridColumnDataType.Percent) && isCountAggregator) { + return GridColumnDataType.Number; + } else if (value.dataType === GridColumnDataType.Currency && !isCountAggregator) { + return GridColumnDataType.Currency; + } else if (value.dataType === GridColumnDataType.Percent && !isCountAggregator) { + return GridColumnDataType.Percent; + } + } }