From 91bb26bdd1455350755f7422f519721d72638bfb Mon Sep 17 00:00:00 2001 From: Simeon Simeonoff Date: Fri, 28 Aug 2026 17:13:24 +0300 Subject: [PATCH 01/22] feat(grids): add theming samples and grid theme playground --- live-editing/configs/GridConfigGenerator.ts | 5 + .../configs/PivotGridConfigGenerator.ts | 2 +- .../configs/ThemingConfigGenerator.ts | 16 + src/app/app.routes.server.ts | 10 + src/app/grid/grid-routes-data.ts | 1 + .../grid-theming/grid-theming.component.html | 64 ++++ .../grid-theming/grid-theming.component.scss | 145 ++++++++ .../grid-theming/grid-theming.component.ts | 53 +++ .../grid-validation-style.component.ts | 2 +- src/app/grid/grids.routes.ts | 6 + .../hgrid-rowStyles.component.ts | 4 +- .../hierarchical-grid-styling.component.html | 95 ++++-- .../hierarchical-grid-styling.component.scss | 149 +++++++- .../hierarchical-grid-styling.component.ts | 18 +- .../hierarchical-grid-styling/layout.scss | 8 +- ...rchical-grid-validation-style.component.ts | 2 +- src/app/index/index.component.scss | 12 +- .../pivot-styling.component.html | 34 +- .../pivot-styling.component.scss | 149 +++++++- .../pivot-styling/pivot-styling.component.ts | 32 +- .../grid-theme-playground/color-utils.ts | 12 + .../grid-theme-playground.component.html | 223 ++++++++++++ .../grid-theme-playground.component.scss | 173 ++++++++++ .../grid-theme-playground.component.ts | 318 ++++++++++++++++++ .../theme-color-field.component.html | 20 ++ .../theme-color-field.component.scss | 76 +++++ .../theme-color-field.component.ts | 48 +++ src/app/theming/theming-routes-data.ts | 3 +- src/app/theming/theming.routes.ts | 12 +- .../tree-grid-rowStyle.component.ts | 2 +- src/app/tree-grid/tree-grid-style/layout.scss | 6 +- .../tree-grid-style.component.html | 42 ++- .../tree-grid-style.component.scss | 149 +++++++- .../tree-grid-style.component.ts | 24 +- .../tree-grid-validation-style.component.ts | 2 +- 35 files changed, 1810 insertions(+), 107 deletions(-) create mode 100644 src/app/grid/grid-theming/grid-theming.component.html create mode 100644 src/app/grid/grid-theming/grid-theming.component.scss create mode 100644 src/app/grid/grid-theming/grid-theming.component.ts create mode 100644 src/app/theming/grid-theme-playground/color-utils.ts create mode 100644 src/app/theming/grid-theme-playground/grid-theme-playground.component.html create mode 100644 src/app/theming/grid-theme-playground/grid-theme-playground.component.scss create mode 100644 src/app/theming/grid-theme-playground/grid-theme-playground.component.ts create mode 100644 src/app/theming/grid-theme-playground/theme-color-field.component.html create mode 100644 src/app/theming/grid-theme-playground/theme-color-field.component.scss create mode 100644 src/app/theming/grid-theme-playground/theme-color-field.component.ts diff --git a/live-editing/configs/GridConfigGenerator.ts b/live-editing/configs/GridConfigGenerator.ts index 0675968292..472080951b 100644 --- a/live-editing/configs/GridConfigGenerator.ts +++ b/live-editing/configs/GridConfigGenerator.ts @@ -574,6 +574,11 @@ export class GridConfigGenerator implements IConfigGenerator { additionalFiles: ['/src/app/directives/prevent-scroll.directive.ts', '/src/app/data/customers.ts', '/src/app/grid/grid-sample-pinning-styling/layout.scss'], appConfig: BaseAppConfig })); + configs.push(new Config({ + component: 'GridThemingComponent', + additionalFiles: ['/src/app/directives/prevent-scroll.directive.ts', '/src/app/data/invoiceData.ts'], + appConfig: BaseAppConfig + })); configs.push(new Config({ component: 'GridGroupByStylingComponent', additionalFiles: ['/src/app/directives/prevent-scroll.directive.ts', '/src/app/data/invoiceData.ts', '/src/app/grid/grid-groupby-styling/layout.scss'], diff --git a/live-editing/configs/PivotGridConfigGenerator.ts b/live-editing/configs/PivotGridConfigGenerator.ts index 7f7fb25e2e..c7c720c47b 100644 --- a/live-editing/configs/PivotGridConfigGenerator.ts +++ b/live-editing/configs/PivotGridConfigGenerator.ts @@ -83,7 +83,7 @@ export class PivotGridConfigGenerator implements IConfigGenerator { })); configs.push(new Config({ - additionalFiles: ['/src/app/directives/prevent-scroll.directive.ts', '/src/app/data/dataToAnalyze.ts'], + additionalFiles: ['/src/app/data/pivot-data.ts', '/src/app/pivot-grid/pivot-styling/layout.scss'], appConfig: BaseAppConfig, component: 'PivotStylingComponent' })); diff --git a/live-editing/configs/ThemingConfigGenerator.ts b/live-editing/configs/ThemingConfigGenerator.ts index 3c0a10d09e..9d29d32b4e 100644 --- a/live-editing/configs/ThemingConfigGenerator.ts +++ b/live-editing/configs/ThemingConfigGenerator.ts @@ -72,6 +72,22 @@ export class ThemingConfigGenerator implements IConfigGenerator { shortenComponentPathBy: '/theming/angular/' })); + configs.push(new Config({ + component: 'GridThemePlaygroundComponent', + additionalFiles: [ + '/src/app/theming/grid-theme-playground/theme-color-field.component.ts', + '/src/app/theming/grid-theme-playground/theme-color-field.component.html', + '/src/app/theming/grid-theme-playground/theme-color-field.component.scss', + '/src/app/theming/grid-theme-playground/color-utils.ts', + '/src/app/data/invoiceData.ts', + '/src/app/data/pivot-data.ts', + '/src/app/data/singersData.ts', + '/src/app/tree-grid/data/employees-flat-avatars.ts' + ], + appConfig: BaseAppConfig, + shortenComponentPathBy: '/theming/grid-theme-playground/' + })); + configs.push(new Config({ component: 'TailwindSampleComponent', appConfig: BaseAppConfig, diff --git a/src/app/app.routes.server.ts b/src/app/app.routes.server.ts index 85274dd7e2..2960e62832 100644 --- a/src/app/app.routes.server.ts +++ b/src/app/app.routes.server.ts @@ -49,6 +49,16 @@ export const serverRoutes: ServerRoute[] = [ path: 'samples/lists/**', renderMode: RenderMode.Client // TODO: Fails with Prerender }, + { + // Hosts grid previews, and grids fail under Prerender like every other + // grid route below. Must precede the theming/** globs. + path: 'theming/grid-theme-playground', + renderMode: RenderMode.Client + }, + { + path: 'samples/theming/grid-theme-playground', + renderMode: RenderMode.Client + }, { path: 'theming/**', renderMode: RenderMode.Prerender diff --git a/src/app/grid/grid-routes-data.ts b/src/app/grid/grid-routes-data.ts index 57923487fe..10860e02df 100644 --- a/src/app/grid/grid-routes-data.ts +++ b/src/app/grid/grid-routes-data.ts @@ -4,6 +4,7 @@ export const gridsRoutesData = { 'grid-groupby': { displayName: 'Grid GroupBy', parentName: 'Grid' }, 'grid-cellMerge': { displayName: 'Grid Cell Merge', parentName: 'Grid' }, 'grid-cellMerge-custom': { displayName: 'Grid Cell Merge Custom', parentName: 'Grid' }, + 'grid-theming': { displayName: 'Grid Theming', parentName: 'Grid' }, 'grid-groupby-custom': {displayName: 'Grid GroupBy Custom', parentName: 'Grid'}, 'grid-groupby-paging': { displayName: 'Grid GroupBy Paging', parentName: 'Grid' }, 'grid-groupby-styling': { displayName: 'Grid GroupBy Styling', parentName: 'Grid' }, diff --git a/src/app/grid/grid-theming/grid-theming.component.html b/src/app/grid/grid-theming/grid-theming.component.html new file mode 100644 index 0000000000..6a044abecf --- /dev/null +++ b/src/app/grid/grid-theming/grid-theming.component.html @@ -0,0 +1,64 @@ +
+
+ Pick a theme + + + @for (theme of themes; track theme.class) { + + } + + +

+ Custom themes, not built-in: each is a grid-theme() with its + own background and accent. +

+
+ + + + + Invoices + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/app/grid/grid-theming/grid-theming.component.scss b/src/app/grid/grid-theming/grid-theming.component.scss new file mode 100644 index 0000000000..29578f9aa5 --- /dev/null +++ b/src/app/grid/grid-theming/grid-theming.component.scss @@ -0,0 +1,145 @@ +@use "igniteui-angular/theming" as *; + +$studio-bg: #faf4ed; +$studio-accent: #907aa9; +$ledger-bg: #eceff4; +$ledger-accent: #5e81ac; +$editorial-bg: #333c43; +$editorial-accent: #a7c080; +$midnight-bg: #282a36; +$midnight-accent: #bd93f9; + +:host { + display: block; + padding: 16px; +} + +.theme-studio { + --ig-size: var(--ig-size-large); + --ig-radius-factor: 0.6; + + @include tokens(grid-theme( + $background: $studio-bg, + $foreground: #575279, + $accent-color: $studio-accent, + $header-background: #fffaf3, + $header-border-color: #dfdad9, + $row-border-color: #f2e9e1, + $grid-border-color: #dfdad9, + $grid-shadow: (0 1px 3px rgba(87, 82, 121, 0.10), 0 1px 2px rgba(87, 82, 121, 0.06)) + )); +} + +.theme-ledger { + --ig-size: var(--ig-size-small); + --ig-radius-factor: 0; + + @include tokens(grid-theme( + $background: $ledger-bg, + $foreground: #2e3440, + $accent-color: $ledger-accent, + $header-background: #d8dee9, + $row-odd-background: #eceff4, + $row-even-background: #e5e9f0, + $body-column-border-color-odd: #d8dee9, + $body-column-border-color-even: #d8dee9, + $row-border-color: #d8dee9, + $grid-border-color: #c8d0dc + )); +} + +.theme-editorial { + --ig-size: var(--ig-size-large); + --ig-radius-factor: 0; + + @include tokens(grid-theme( + $schema: $dark-material-schema, + $background: $editorial-bg, + $foreground: #d3c6aa, + $accent-color: $editorial-accent, + $header-background: #3a464c, + $row-border-color: #333c43, + $grid-border-color: #333c43 + )); +} + +.theme-midnight { + --ig-size: var(--ig-size-medium); + --ig-radius-factor: 0.25; + + @include tokens(grid-theme( + $schema: $dark-material-schema, + $background: $midnight-bg, + $foreground: #f8f8f2, + $accent-color: $midnight-accent, + $header-background: #21222c, + $body-column-border-color-odd: #44475a, + $body-column-border-color-even: #44475a, + $row-border-color: #44475a, + $grid-border-color: #44475a + )); +} + +.grid-theming-sample { + display: flex; + flex-direction: column; + gap: 16px; +} + +.theme-picker { + --ig-button-group-elevation: 0; + + display: flex; + flex-direction: column; + gap: 6px; + align-self: flex-start; +} + +.theme-picker__label { + font-size: 12px; + font-weight: 500; + letter-spacing: 0.04em; + color: var(--ig-gray-700); +} + +.theme-picker__hint { + margin: 0; + font-size: 12px; + line-height: 1.45; + color: var(--ig-gray-600); + + code { + font-family: 'JetBrains Mono', 'Fira Code', Consolas, monospace; + font-size: 11px; + } +} + +.theme-swatch { + display: inline-block; + min-width: 14px; + aspect-ratio: 1; + border-radius: 50%; + border: 1px solid var(--ig-gray-300); + vertical-align: -2px; + background: linear-gradient(135deg, var(--swatch-bg) 0 50%, var(--swatch-accent) 50% 100%); +} + +.theme-swatch--studio { + --swatch-bg: #{$studio-bg}; + --swatch-accent: #{$studio-accent}; +} + +.theme-swatch--ledger { + --swatch-bg: #{$ledger-bg}; + --swatch-accent: #{$ledger-accent}; +} + +.theme-swatch--editorial { + --swatch-bg: #{$editorial-bg}; + --swatch-accent: #{$editorial-accent}; +} + +.theme-swatch--midnight { + --swatch-bg: #{$midnight-bg}; + --swatch-accent: #{$midnight-accent}; +} diff --git a/src/app/grid/grid-theming/grid-theming.component.ts b/src/app/grid/grid-theming/grid-theming.component.ts new file mode 100644 index 0000000000..97fe513f41 --- /dev/null +++ b/src/app/grid/grid-theming/grid-theming.component.ts @@ -0,0 +1,53 @@ +import { Component, signal } from '@angular/core'; +import { IgxButtonGroupComponent } from 'igniteui-angular/button-group'; +import { IgxButtonDirective } from 'igniteui-angular/directives'; +import { IgxNumberSummaryOperand, IgxSummaryResult } from 'igniteui-angular/core'; +import { IgxColumnComponent, IgxGridToolbarActionsComponent, IgxGridToolbarComponent, IgxGridToolbarHidingComponent, IgxGridToolbarPinningComponent, IgxGridToolbarTitleComponent } from 'igniteui-angular/grids/core'; +import { IgxGridComponent } from 'igniteui-angular/grids/grid'; +import { IgxPaginatorComponent } from 'igniteui-angular/paginator'; +import { INVOICE_DATA } from '../../data/invoiceData'; +import { IgxPreventDocumentScrollDirective } from '../../directives/prevent-scroll.directive'; +class CompactSummary extends IgxNumberSummaryOperand { + public override operate(data?: any[]): IgxSummaryResult[] { + return super.operate(data).filter(r => r.key === 'count' || r.key === 'sum'); + } +} + +@Component({ + selector: 'app-grid-theming', + styleUrls: ['./grid-theming.component.scss'], + templateUrl: './grid-theming.component.html', + imports: [ + IgxButtonDirective, + IgxButtonGroupComponent, + IgxColumnComponent, + IgxGridComponent, + IgxGridToolbarActionsComponent, + IgxGridToolbarComponent, + IgxGridToolbarHidingComponent, + IgxGridToolbarPinningComponent, + IgxGridToolbarTitleComponent, + IgxPaginatorComponent, + IgxPreventDocumentScrollDirective + ] +}) +export class GridThemingComponent { + public data = INVOICE_DATA; + public compactSummary = CompactSummary; + public themes = [ + { label: 'Studio', class: 'theme-studio', swatch: 'theme-swatch--studio' }, + { label: 'Ledger', class: 'theme-ledger', swatch: 'theme-swatch--ledger' }, + { label: 'Editorial', class: 'theme-editorial', swatch: 'theme-swatch--editorial' }, + { label: 'Midnight', class: 'theme-midnight', swatch: 'theme-swatch--midnight' } + ]; + + public activeTheme = signal(this.themes[0].class); + + public selectTheme(args: { index: number }) { + this.activeTheme.set(this.themes[args.index].class); + } + + public formatCurrency(value: number) { + return '$' + value.toFixed(2); + } +} diff --git a/src/app/grid/grid-validation-style/grid-validation-style.component.ts b/src/app/grid/grid-validation-style/grid-validation-style.component.ts index 89c22dfaed..ccf4d404d8 100644 --- a/src/app/grid/grid-validation-style/grid-validation-style.component.ts +++ b/src/app/grid/grid-validation-style/grid-validation-style.component.ts @@ -14,7 +14,7 @@ import { NgTemplateOutlet } from '@angular/common'; export class GridValidationStyleComponent { @ViewChild('grid', { read: IgxGridComponent, static: true }) public grid: IgxGridComponent; public data: any[]; - public rowStyles = { + public rowStyles: any = { background: (row: RowType) => row.validation.status === 'INVALID' ? '#FF000033' : '#00000000' }; public cellStyles = { diff --git a/src/app/grid/grids.routes.ts b/src/app/grid/grids.routes.ts index be9950dbc9..c5ded8e028 100644 --- a/src/app/grid/grids.routes.ts +++ b/src/app/grid/grids.routes.ts @@ -31,6 +31,7 @@ import { GridGroupByCustomSampleComponent } from './grid-groupby-custom-sample/g import { GridGroupByPagingSampleComponent } from './grid-group-by-paging-sample/grid-group-by-paging-sample.component'; import { GridGroupBySampleComponent } from './grid-groupby-sample/grid-groupby-sample.component'; import { GridGroupByStylingComponent } from './grid-groupby-styling/grid-groupby-styling.component'; +import { GridThemingComponent } from './grid-theming/grid-theming.component'; import { GridGroupBySummarySampleComponent } from './grid-groupby-summary-sample/grid-groupby-summary-sample.component'; import { GridGroupBySummaryStylingSampleComponent } from './grid-groupby-summary-styling-sample/grid-groupby-summary-styling-sample.component'; import { GridMovingSampleComponent } from './grid-moving-sample/grid-moving-sample.component'; @@ -168,6 +169,11 @@ export const GridsRoutes: Routes = [ data: gridsRoutesData['grid-cellMerge-custom'], path: 'grid-cellMerge-custom' }, + { + component: GridThemingComponent, + data: gridsRoutesData['grid-theming'], + path: 'grid-theming' + }, { component: GridGroupByStylingComponent, data: gridsRoutesData['grid-groupby-styling'], diff --git a/src/app/hierarchical-grid/hgrid-rowStyle-sample/hgrid-rowStyles.component.ts b/src/app/hierarchical-grid/hgrid-rowStyle-sample/hgrid-rowStyles.component.ts index ae92b4259b..cb950623cf 100644 --- a/src/app/hierarchical-grid/hgrid-rowStyle-sample/hgrid-rowStyles.component.ts +++ b/src/app/hierarchical-grid/hgrid-rowStyle-sample/hgrid-rowStyles.component.ts @@ -18,12 +18,12 @@ export class HGridRowStylesSampleComponent implements OnInit { private hierarchicalGrid: IgxHierarchicalGridComponent; public localdata; - public rowStyles = { + public rowStyles: any = { background:(row: RowType) => row.data['HasGrammyAward'] ? '#eeddd3' : '#f0efeb', 'border-left': (row: RowType) => row.data['HasGrammyAward'] ? '2px solid #dda15e' : null }; - public childRowStyles = { + public childRowStyles: any = { 'border-left': (row: RowType) => row.data['BillboardReview'] > 70 ? '3.5px solid #dda15e' : null }; constructor() { } diff --git a/src/app/hierarchical-grid/hierarchical-grid-styling/hierarchical-grid-styling.component.html b/src/app/hierarchical-grid/hierarchical-grid-styling/hierarchical-grid-styling.component.html index 7028f9adae..8f27753f0c 100644 --- a/src/app/hierarchical-grid/hierarchical-grid-styling/hierarchical-grid-styling.component.html +++ b/src/app/hierarchical-grid/hierarchical-grid-styling/hierarchical-grid-styling.component.html @@ -1,36 +1,67 @@
- - - - -
- -
-
-
- - - +
+ Pick a theme - - - - - - - - - - - - + + @for (theme of themes; track theme.class) { + + } + - - - - - - - +

+ Custom themes, not built-in: each is a grid-theme() with its + own background and accent. +

+
+ + + + + +
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/app/hierarchical-grid/hierarchical-grid-styling/hierarchical-grid-styling.component.scss b/src/app/hierarchical-grid/hierarchical-grid-styling/hierarchical-grid-styling.component.scss index 2c0d35a3be..9a14ff29e1 100644 --- a/src/app/hierarchical-grid/hierarchical-grid-styling/hierarchical-grid-styling.component.scss +++ b/src/app/hierarchical-grid/hierarchical-grid-styling/hierarchical-grid-styling.component.scss @@ -1,16 +1,141 @@ @use "layout.scss"; @use "igniteui-angular/theming" as *; -$background: #292826; -$foreground: #eeece1; -$accent: #ffcd0f; - -$custom-grid: grid-theme( - $background: $background, - $foreground: $foreground, - $accent-color: $accent, -); - -:host { - @include tokens($custom-grid); +$studio-bg: #faf4ed; +$studio-accent: #907aa9; +$ledger-bg: #eceff4; +$ledger-accent: #5e81ac; +$editorial-bg: #333c43; +$editorial-accent: #a7c080; +$midnight-bg: #282a36; +$midnight-accent: #bd93f9; + +.theme-studio { + --ig-size: var(--ig-size-large); + --ig-radius-factor: 0.6; + + @include tokens(grid-theme( + $background: $studio-bg, + $foreground: #575279, + $accent-color: $studio-accent, + $header-background: #fffaf3, + $header-border-color: #dfdad9, + $row-border-color: #f2e9e1, + $grid-border-color: #dfdad9, + $grid-shadow: (0 1px 3px rgba(87, 82, 121, 0.10), 0 1px 2px rgba(87, 82, 121, 0.06)) + )); +} + +.theme-ledger { + --ig-size: var(--ig-size-small); + --ig-radius-factor: 0; + + @include tokens(grid-theme( + $background: $ledger-bg, + $foreground: #2e3440, + $accent-color: $ledger-accent, + $header-background: #d8dee9, + $row-odd-background: #eceff4, + $row-even-background: #e5e9f0, + $body-column-border-color-odd: #d8dee9, + $body-column-border-color-even: #d8dee9, + $row-border-color: #d8dee9, + $grid-border-color: #c8d0dc + )); +} + +.theme-editorial { + --ig-size: var(--ig-size-large); + --ig-radius-factor: 0; + + @include tokens(grid-theme( + $schema: $dark-material-schema, + $background: $editorial-bg, + $foreground: #d3c6aa, + $accent-color: $editorial-accent, + $header-background: #3a464c, + $row-border-color: #333c43, + $grid-border-color: #333c43 + )); +} + +.theme-midnight { + --ig-size: var(--ig-size-medium); + --ig-radius-factor: 0.25; + + @include tokens(grid-theme( + $schema: $dark-material-schema, + $background: $midnight-bg, + $foreground: #f8f8f2, + $accent-color: $midnight-accent, + $header-background: #21222c, + $body-column-border-color-odd: #44475a, + $body-column-border-color-even: #44475a, + $row-border-color: #44475a, + $grid-border-color: #44475a + )); +} + +.grid__wrapper { + display: flex; + flex-direction: column; + gap: 16px; +} + +.theme-picker { + --ig-button-group-elevation: 0; + + display: flex; + flex-direction: column; + gap: 6px; + align-self: flex-start; +} + +.theme-picker__label { + font-size: 12px; + font-weight: 500; + letter-spacing: 0.04em; + color: var(--ig-gray-700); +} + +.theme-picker__hint { + margin: 0; + font-size: 12px; + line-height: 1.45; + color: var(--ig-gray-600); + + code { + font-family: 'JetBrains Mono', 'Fira Code', Consolas, monospace; + font-size: 11px; + } +} + +.theme-swatch { + display: inline-block; + min-width: 14px; + aspect-ratio: 1; + border-radius: 50%; + border: 1px solid var(--ig-gray-300); + vertical-align: -2px; + background: linear-gradient(135deg, var(--swatch-bg) 0 50%, var(--swatch-accent) 50% 100%); +} + +.theme-swatch--studio { + --swatch-bg: #{$studio-bg}; + --swatch-accent: #{$studio-accent}; +} + +.theme-swatch--ledger { + --swatch-bg: #{$ledger-bg}; + --swatch-accent: #{$ledger-accent}; +} + +.theme-swatch--editorial { + --swatch-bg: #{$editorial-bg}; + --swatch-accent: #{$editorial-accent}; +} + +.theme-swatch--midnight { + --swatch-bg: #{$midnight-bg}; + --swatch-accent: #{$midnight-accent}; } diff --git a/src/app/hierarchical-grid/hierarchical-grid-styling/hierarchical-grid-styling.component.ts b/src/app/hierarchical-grid/hierarchical-grid-styling/hierarchical-grid-styling.component.ts index fcc915ddfc..91bd07fa4c 100644 --- a/src/app/hierarchical-grid/hierarchical-grid-styling/hierarchical-grid-styling.component.ts +++ b/src/app/hierarchical-grid/hierarchical-grid-styling/hierarchical-grid-styling.component.ts @@ -1,4 +1,6 @@ -import { Component } from '@angular/core'; +import { Component, signal } from '@angular/core'; +import { IgxButtonGroupComponent } from 'igniteui-angular/button-group'; +import { IgxButtonDirective } from 'igniteui-angular/directives'; import { IgxCellTemplateDirective, IgxColumnComponent } from 'igniteui-angular/grids/core'; import { IgxHierarchicalGridComponent, IgxRowIslandComponent } from 'igniteui-angular/grids/hierarchical-grid'; import { SINGERS } from '../../data/singersData'; @@ -8,7 +10,7 @@ import { IgxPreventDocumentScrollDirective } from '../../directives/prevent-scro selector: 'app-hierarchical-grid-styling', styleUrls: ['./hierarchical-grid-styling.component.scss'], templateUrl: 'hierarchical-grid-styling.component.html', - imports: [IgxHierarchicalGridComponent, IgxPreventDocumentScrollDirective, IgxColumnComponent, IgxCellTemplateDirective, IgxRowIslandComponent] + imports: [IgxHierarchicalGridComponent, IgxPreventDocumentScrollDirective, IgxColumnComponent, IgxCellTemplateDirective, IgxRowIslandComponent, IgxButtonGroupComponent, IgxButtonDirective] }) export class HGridStylingComponent { @@ -16,11 +18,23 @@ export class HGridStylingComponent { public col: IgxColumnComponent; public pWidth: string; public nWidth: string; + public themes = [ + { label: 'Studio', class: 'theme-studio', swatch: 'theme-swatch--studio' }, + { label: 'Ledger', class: 'theme-ledger', swatch: 'theme-swatch--ledger' }, + { label: 'Editorial', class: 'theme-editorial', swatch: 'theme-swatch--editorial' }, + { label: 'Midnight', class: 'theme-midnight', swatch: 'theme-swatch--midnight' } + ]; + + public activeTheme = signal(this.themes[0].class); constructor() { this.localdata = SINGERS; } + public selectTheme(args: { index: number }) { + this.activeTheme.set(this.themes[args.index].class); + } + public onResize(event) { this.col = event.column; this.pWidth = event.prevWidth; diff --git a/src/app/hierarchical-grid/hierarchical-grid-styling/layout.scss b/src/app/hierarchical-grid/hierarchical-grid-styling/layout.scss index b620c7ade6..e2bcf0bd0e 100644 --- a/src/app/hierarchical-grid/hierarchical-grid-styling/layout.scss +++ b/src/app/hierarchical-grid/hierarchical-grid-styling/layout.scss @@ -1,12 +1,18 @@ +// Fits the smallest row density. .photo { vertical-align: middle; - max-height: 62px; + max-block-size: 24px; + border-radius: 50%; } .cell__inner_2 { margin: 1px } +:host { + display: block; +} + .grid__wrapper{ padding: 10px; } diff --git a/src/app/hierarchical-grid/hierarchical-grid-validation-style/hierarchical-grid-validation-style.component.ts b/src/app/hierarchical-grid/hierarchical-grid-validation-style/hierarchical-grid-validation-style.component.ts index 49871eb70b..ffc614547d 100644 --- a/src/app/hierarchical-grid/hierarchical-grid-validation-style/hierarchical-grid-validation-style.component.ts +++ b/src/app/hierarchical-grid/hierarchical-grid-validation-style/hierarchical-grid-validation-style.component.ts @@ -17,7 +17,7 @@ export class HGridValidationStyleComponent { @ViewChild('hierarchicalGrid', { read: IgxHierarchicalGridComponent, static: true }) public hierarchicalGrid: IgxHierarchicalGridComponent; @ViewChild('childGrid', { static: true }) private childGrid: IgxRowIslandComponent; public localData: Singer[]; - public rowStyles = { + public rowStyles: any = { background: (row: RowType) => row.validation.status === 'INVALID' ? '#FF000033' : '#00000000' }; public cellStyles = { diff --git a/src/app/index/index.component.scss b/src/app/index/index.component.scss index f6cb2bd6a5..5b2502768b 100644 --- a/src/app/index/index.component.scss +++ b/src/app/index/index.component.scss @@ -3,19 +3,21 @@ } .main { + display: flex; + flex-direction: column; width: calc(100% - 300px); + height: 100%; } -.content { - width: 100%; - // height: calc(100% - 56px); - height: 100%; +.content { + width: 100%; + flex: 1 1 auto; max-height: 1000px; min-width: 300px; min-height: 300px; justify-content: center; align-items: stretch; - overflow: auto; + overflow: auto; } .navdrawer-ellipsis { diff --git a/src/app/pivot-grid/pivot-styling/pivot-styling.component.html b/src/app/pivot-grid/pivot-styling/pivot-styling.component.html index 08df70c02f..f94ecf55aa 100644 --- a/src/app/pivot-grid/pivot-styling/pivot-styling.component.html +++ b/src/app/pivot-grid/pivot-styling/pivot-styling.component.html @@ -1,2 +1,32 @@ - - \ No newline at end of file +
+
+ Pick a theme + + + @for (theme of themes; track theme.class) { + + } + + +

+ Custom themes, not built-in: each is a grid-theme() with its + own background and accent. +

+
+ + + +
diff --git a/src/app/pivot-grid/pivot-styling/pivot-styling.component.scss b/src/app/pivot-grid/pivot-styling/pivot-styling.component.scss index 238acf9733..d703a350ad 100644 --- a/src/app/pivot-grid/pivot-styling/pivot-styling.component.scss +++ b/src/app/pivot-grid/pivot-styling/pivot-styling.component.scss @@ -1,16 +1,141 @@ @use "layout.scss"; @use "igniteui-angular/theming" as *; -$background: #292826; -$foreground: #eeece1; -$accent: #ffcd0f; - -$custom-grid: grid-theme( - $background: $background, - $foreground: $foreground, - $accent-color: $accent, -); - -igx-pivot-grid { - @include tokens($custom-grid); +$studio-bg: #faf4ed; +$studio-accent: #907aa9; +$ledger-bg: #eceff4; +$ledger-accent: #5e81ac; +$editorial-bg: #333c43; +$editorial-accent: #a7c080; +$midnight-bg: #282a36; +$midnight-accent: #bd93f9; + +.theme-studio { + --ig-size: var(--ig-size-large); + --ig-radius-factor: 0.6; + + @include tokens(grid-theme( + $background: $studio-bg, + $foreground: #575279, + $accent-color: $studio-accent, + $header-background: #fffaf3, + $header-border-color: #dfdad9, + $row-border-color: #f2e9e1, + $grid-border-color: #dfdad9, + $grid-shadow: (0 1px 3px rgba(87, 82, 121, 0.10), 0 1px 2px rgba(87, 82, 121, 0.06)) + )); +} + +.theme-ledger { + --ig-size: var(--ig-size-small); + --ig-radius-factor: 0; + + @include tokens(grid-theme( + $background: $ledger-bg, + $foreground: #2e3440, + $accent-color: $ledger-accent, + $header-background: #d8dee9, + $row-odd-background: #eceff4, + $row-even-background: #e5e9f0, + $body-column-border-color-odd: #d8dee9, + $body-column-border-color-even: #d8dee9, + $row-border-color: #d8dee9, + $grid-border-color: #c8d0dc + )); +} + +.theme-editorial { + --ig-size: var(--ig-size-large); + --ig-radius-factor: 0; + + @include tokens(grid-theme( + $schema: $dark-material-schema, + $background: $editorial-bg, + $foreground: #d3c6aa, + $accent-color: $editorial-accent, + $header-background: #3a464c, + $row-border-color: #333c43, + $grid-border-color: #333c43 + )); +} + +.theme-midnight { + --ig-size: var(--ig-size-medium); + --ig-radius-factor: 0.25; + + @include tokens(grid-theme( + $schema: $dark-material-schema, + $background: $midnight-bg, + $foreground: #f8f8f2, + $accent-color: $midnight-accent, + $header-background: #21222c, + $body-column-border-color-odd: #44475a, + $body-column-border-color-even: #44475a, + $row-border-color: #44475a, + $grid-border-color: #44475a + )); +} + +.pivot-theming-sample { + display: flex; + flex-direction: column; + gap: 16px; +} + +.theme-picker { + --ig-button-group-elevation: 0; + + display: flex; + flex-direction: column; + gap: 6px; + align-self: flex-start; +} + +.theme-picker__label { + font-size: 12px; + font-weight: 500; + letter-spacing: 0.04em; + color: var(--ig-gray-700); +} + +.theme-picker__hint { + margin: 0; + font-size: 12px; + line-height: 1.45; + color: var(--ig-gray-600); + + code { + font-family: 'JetBrains Mono', 'Fira Code', Consolas, monospace; + font-size: 11px; + } +} + +.theme-swatch { + display: inline-block; + min-width: 14px; + aspect-ratio: 1; + border-radius: 50%; + border: 1px solid var(--ig-gray-300); + vertical-align: -2px; + background: linear-gradient(135deg, var(--swatch-bg) 0 50%, var(--swatch-accent) 50% 100%); +} + +.theme-swatch--studio { + --swatch-bg: #{$studio-bg}; + --swatch-accent: #{$studio-accent}; +} + +.theme-swatch--ledger { + --swatch-bg: #{$ledger-bg}; + --swatch-accent: #{$ledger-accent}; +} + +.theme-swatch--editorial { + --swatch-bg: #{$editorial-bg}; + --swatch-accent: #{$editorial-accent}; +} + +.theme-swatch--midnight { + --swatch-bg: #{$midnight-bg}; + --swatch-accent: #{$midnight-accent}; } diff --git a/src/app/pivot-grid/pivot-styling/pivot-styling.component.ts b/src/app/pivot-grid/pivot-styling/pivot-styling.component.ts index b85a70c4fe..039ae0185f 100644 --- a/src/app/pivot-grid/pivot-styling/pivot-styling.component.ts +++ b/src/app/pivot-grid/pivot-styling/pivot-styling.component.ts @@ -1,6 +1,8 @@ -import { Component, ChangeDetectionStrategy } from "@angular/core"; +import { Component, ChangeDetectionStrategy, signal } from "@angular/core"; import { DATA } from '../../data/pivot-data'; +import { IgxButtonGroupComponent } from 'igniteui-angular/button-group'; +import { IgxButtonDirective } from 'igniteui-angular/directives'; import { IPivotConfiguration, IgxPivotNumericAggregate } from 'igniteui-angular/grids/core'; import { IgxPivotGridComponent } from 'igniteui-angular/grids/pivot-grid'; @@ -9,24 +11,38 @@ import { IgxPivotGridComponent } from 'igniteui-angular/grids/pivot-grid'; styleUrls: ['./pivot-styling.component.scss'], templateUrl: './pivot-styling.component.html', changeDetection: ChangeDetectionStrategy.Eager, - imports: [IgxPivotGridComponent] + imports: [IgxPivotGridComponent, IgxButtonGroupComponent, IgxButtonDirective] }) export class PivotStylingComponent { public data = DATA; + public themes = [ + { label: 'Studio', class: 'theme-studio', swatch: 'theme-swatch--studio' }, + { label: 'Ledger', class: 'theme-ledger', swatch: 'theme-swatch--ledger' }, + { label: 'Editorial', class: 'theme-editorial', swatch: 'theme-swatch--editorial' }, + { label: 'Midnight', class: 'theme-midnight', swatch: 'theme-swatch--midnight' } + ]; + + public activeTheme = signal(this.themes[0].class); + public pivotConfigHierarchy: IPivotConfiguration = { columns: [ { memberName: 'Product', memberFunction: (data) => data.Product.Name, enabled: true - } + } ], rows: [ { - memberName: 'Seller', - memberFunction: (data) => data.Seller.Name, - enabled: true + memberName: 'City', + memberFunction: (data) => data.Seller.City, + enabled: true, + childLevel: { + memberName: 'Seller', + memberFunction: (data) => data.Seller.Name, + enabled: true + } } ], values: [ @@ -42,4 +58,8 @@ export class PivotStylingComponent { ], filters: null }; + + public selectTheme(args: { index: number }) { + this.activeTheme.set(this.themes[args.index].class); + } } diff --git a/src/app/theming/grid-theme-playground/color-utils.ts b/src/app/theming/grid-theme-playground/color-utils.ts new file mode 100644 index 0000000000..9c3ed49e08 --- /dev/null +++ b/src/app/theming/grid-theme-playground/color-utils.ts @@ -0,0 +1,12 @@ +/** Normalizes free-typed color text to a 6-digit uppercase hex string, or null if invalid. */ +export function normalizeHexColor(raw: string): string | null { + let value = raw.trim(); + if (!value) return null; + if (!value.startsWith('#')) value = '#' + value; + + if (/^#[0-9a-fA-F]{3}$/.test(value)) { + value = '#' + value[1] + value[1] + value[2] + value[2] + value[3] + value[3]; + } + + return /^#[0-9a-fA-F]{6}$/.test(value) ? value.toUpperCase() : null; +} diff --git a/src/app/theming/grid-theme-playground/grid-theme-playground.component.html b/src/app/theming/grid-theme-playground/grid-theme-playground.component.html new file mode 100644 index 0000000000..fb39188573 --- /dev/null +++ b/src/app/theming/grid-theme-playground/grid-theme-playground.component.html @@ -0,0 +1,223 @@ +
+ +
+
+ + @switch (preview()) { + @case ('grid') { + + + + + + + + + } + @case ('tree') { + @defer (on immediate) { + + + +
+ + {{ cell.value }} +
+
+
+ + + +
+ } @placeholder { +
Loading preview…
+ } + } + @case ('hierarchical') { + @defer (on immediate) { + + + + + + + + + + + + } @placeholder { +
Loading preview…
+ } + } + @case ('pivot') { + @defer (on immediate) { + + + } @placeholder { +
Loading preview…
+ } + } + } +
+
+
+ + + +
Theme code
+
+ +
+ + + + SCSS + + + +
+
+
+ + + + CSS variables + + + +
+
+
+
+
+ +
+ +
+
diff --git a/src/app/theming/grid-theme-playground/grid-theme-playground.component.scss b/src/app/theming/grid-theme-playground/grid-theme-playground.component.scss new file mode 100644 index 0000000000..2a0e5ce636 --- /dev/null +++ b/src/app/theming/grid-theme-playground/grid-theme-playground.component.scss @@ -0,0 +1,173 @@ +@use "igniteui-angular/theming" as *; + +:host { + display: block; + block-size: 100%; +} + +.playground { + display: flex; + align-items: stretch; + gap: 20px; + padding: 16px; + box-sizing: border-box; + block-size: 100%; + min-block-size: 520px; + overflow: hidden; +} + +.playground__stage { + @include tokens(grid-theme( + $background: #08002e, + $accent-color: #ff7d52 + )); +} + +.playground__rail { + --ig-size: var(--ig-size-medium); + --ig-button-group-elevation: 0; + + flex: 0 0 280px; + display: flex; + flex-direction: column; + gap: 12px; + min-block-size: 0; + overflow-y: auto; + padding-inline-end: 4px; + + igx-expansion-panel-title { + font-size: 13px; + font-weight: 600; + letter-spacing: 0.04em; + color: var(--ig-gray-700); + } +} + +.playground__hint { + margin: 0 0 10px; + font-size: 12px; + line-height: 1.45; + color: var(--ig-gray-600); +} + +.playground__fields { + display: flex; + flex-direction: column; + gap: 14px; +} + +.playground__control { + display: flex; + flex-direction: column; + gap: 6px; +} + +.playground__label { + font-size: 12px; + color: var(--ig-gray-700); +} + +.playground__actions { + position: sticky; + inset-block-end: 0; + z-index: 1; + display: flex; + gap: 8px; + padding-block: 8px; + background: var(--ig-surface-500); + border-block-start: 1px solid var(--ig-gray-200); + + button { + flex: 1; + } +} + +.playground__dialog-title { + font-size: 16px; + font-weight: 600; +} + +.playground__dialog-body { + --ig-size: var(--ig-size-medium); + --ig-icon-size: 18px; + --ig-h5-font-size: 14px; + --ig-h5-font-weight: 600; + --ig-expansion-panel-border-radius: 4px; + --ig-expansion-panel-header-background: var(--ig-gray-100); + + inline-size: min(680px, 80vw); + + ::ng-deep .igx-expansion-panel__body { + padding: 0; + } +} + +.playground__copy { + margin-inline-start: auto; +} + +.playground__export { + border: 1px solid var(--ig-gray-300); + border-radius: 6px; + overflow: hidden; +} + +.playground__code { + ::ng-deep pre.shiki { + margin: 0; + padding: 10px 12px; + font-size: 13px; + line-height: 1.5; + font-family: 'JetBrains Mono', 'Fira Code', Consolas, monospace; + max-block-size: 55vh; + overflow: auto; + overscroll-behavior: contain; + } +} + +.playground__loading { + display: grid; + place-items: center; + block-size: 100%; + color: var(--ig-gray-600); + font-size: 13px; +} + +.playground__preview { + flex: 1 1 auto; + min-inline-size: 0; + min-block-size: 0; + display: flex; + flex-direction: column; + gap: 12px; +} + +.playground__stage { + flex: 1 1 auto; + min-block-size: 0; + overflow: hidden; +} + +.playground__cell { + display: flex; + align-items: center; + gap: 8px; + height: 100%; +} + +@media (max-width: 860px) { + .playground { + flex-direction: column; + block-size: auto; + overflow: visible; + } + + .playground__rail { + flex: 0 0 auto; + overflow: visible; + } + + .playground__stage { + min-block-size: 460px; + } +} diff --git a/src/app/theming/grid-theme-playground/grid-theme-playground.component.ts b/src/app/theming/grid-theme-playground/grid-theme-playground.component.ts new file mode 100644 index 0000000000..f16a90f90d --- /dev/null +++ b/src/app/theming/grid-theme-playground/grid-theme-playground.component.ts @@ -0,0 +1,318 @@ +import { Component, ElementRef, afterNextRender, computed, inject, signal, viewChild } from '@angular/core'; +import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; +import { IgxAccordionComponent } from 'igniteui-angular/accordion'; +import { IgxAvatarComponent } from 'igniteui-angular/avatar'; +import { IgxButtonGroupComponent } from 'igniteui-angular/button-group'; +import { IgxNumberSummaryOperand, IgxSummaryResult } from 'igniteui-angular/core'; +import { IgxIconComponent } from 'igniteui-angular/icon'; +import { IgxDialogActionsDirective, IgxDialogComponent, IgxDialogTitleDirective } from 'igniteui-angular/dialog'; +import { IgxButtonDirective, IgxIconButtonDirective } from 'igniteui-angular/directives'; +import { IGX_EXPANSION_PANEL_DIRECTIVES } from 'igniteui-angular/expansion-panel'; +import { IgxCellTemplateDirective, IgxColumnComponent, IPivotConfiguration, IgxPivotNumericAggregate } from 'igniteui-angular/grids/core'; +import { IgxGridComponent } from 'igniteui-angular/grids/grid'; +import { IgxHierarchicalGridComponent, IgxRowIslandComponent } from 'igniteui-angular/grids/hierarchical-grid'; +import { IgxPivotGridComponent } from 'igniteui-angular/grids/pivot-grid'; +import { IgxTreeGridComponent } from 'igniteui-angular/grids/tree-grid'; +import { IgxPaginatorComponent } from 'igniteui-angular/paginator'; +import { IgxSwitchComponent } from 'igniteui-angular/switch'; +import { INVOICE_DATA } from '../../data/invoiceData'; +import { DATA as PIVOT_DATA } from '../../data/pivot-data'; +import { SINGERS } from '../../data/singersData'; +import { EMPLOYEE_FLAT_AVATARS_DATA } from '../../tree-grid/data/employees-flat-avatars'; +import { ThemeColorFieldComponent } from './theme-color-field.component'; + +type TokenKey = 'background' | 'accentColor' | 'foreground' | 'headerBackground' | 'headerForeground'; + +interface TokenDescriptor { + key: TokenKey; + cssVar: string; + scss: string; + label: string; +} +class CompactSummary extends IgxNumberSummaryOperand { + public override operate(data?: any[]): IgxSummaryResult[] { + return super.operate(data).filter(r => r.key === 'count' || r.key === 'sum'); + } +} +const PRIMARY_TOKENS: TokenDescriptor[] = [ + { key: 'background', cssVar: '--ig-grid-background', scss: '$background', label: 'Background' }, + { key: 'accentColor', cssVar: '--ig-grid-accent-color', scss: '$accent-color', label: 'Accent' }, + { key: 'foreground', cssVar: '--ig-grid-foreground', scss: '$foreground', label: 'Foreground' } +]; +const HEADER_TOKENS: TokenDescriptor[] = [ + { key: 'headerBackground', cssVar: '--ig-grid-header-background', scss: '$header-background', label: 'Header background' }, + { key: 'headerForeground', cssVar: '--ig-grid-header-text-color', scss: '$header-text-color', label: 'Header foreground' } +]; + +const ALL_TOKENS = [...PRIMARY_TOKENS, ...HEADER_TOKENS]; + +const EMPTY_COLORS: Record = { + background: '', accentColor: '', foreground: '', headerBackground: '', headerForeground: '' +}; +/** What Sass emits for header text once $header-background is declared. */ +const HEADER_TEXT_ON_HEADER = 'hsla(from color(from var(--ig-grid-header-background) var(--y-contrast)) h 0 l/1)'; +const DIVIDER = 'hsl(from color-mix(in srgb, var(--ig-grid-foreground) 16%, var(--ig-grid-background)) h s l/0.38)'; +const ZEBRA = 'color-mix(in srgb, var(--ig-grid-foreground) 4%, var(--ig-grid-background))'; +const NO_DIVIDER = 'var(--ig-grid-background)'; + +@Component({ + selector: 'app-grid-theme-playground', + styleUrls: ['./grid-theme-playground.component.scss'], + templateUrl: './grid-theme-playground.component.html', + imports: [ + IgxAccordionComponent, IGX_EXPANSION_PANEL_DIRECTIVES, IgxAvatarComponent, IgxButtonDirective, + IgxButtonGroupComponent, IgxCellTemplateDirective, IgxColumnComponent, + IgxDialogActionsDirective, IgxDialogComponent, IgxDialogTitleDirective, IgxGridComponent, + IgxHierarchicalGridComponent, IgxIconButtonDirective, IgxIconComponent, IgxPaginatorComponent, IgxPivotGridComponent, IgxRowIslandComponent, + IgxSwitchComponent, IgxTreeGridComponent, ThemeColorFieldComponent + ] +}) +export class GridThemePlaygroundComponent { + protected readonly primaryTokens = PRIMARY_TOKENS; + protected readonly headerTokens = HEADER_TOKENS; + protected readonly compactSummary = CompactSummary; + + protected readonly colors = signal>({ ...EMPTY_COLORS }); + protected readonly size = signal<'small' | 'medium' | 'large'>('medium'); + protected readonly radiusFactor = signal(0.4); + protected readonly horizontalDividers = signal(true); + protected readonly verticalDividers = signal(false); + protected readonly zebra = signal(false); + protected readonly preview = signal<'grid' | 'tree' | 'hierarchical' | 'pivot'>('grid'); + + protected readonly copied = signal<'scss' | 'css' | null>(null); + + protected readonly sizes = [ + { label: 'Small', selected: false }, + { label: 'Medium', selected: true }, + { label: 'Large', selected: false } + ]; + protected readonly roundnessOptions = [ + { label: 'Square', selected: false }, + { label: 'Soft', selected: true }, + { label: 'Round', selected: false } + ]; + protected readonly previews = [ + { label: 'Flat', selected: true }, + { label: 'Tree', selected: false }, + { label: 'Hierarchical', selected: false }, + { label: 'Pivot', selected: false } + ]; + + public readonly data = INVOICE_DATA; + public readonly treeData = EMPLOYEE_FLAT_AVATARS_DATA(); + public readonly hierarchicalData = SINGERS; + public readonly pivotData = PIVOT_DATA; + + public pivotConfig: IPivotConfiguration = { + columns: [{ memberName: 'Product', memberFunction: (data) => data.Product.Name, enabled: true }], + rows: [{ + memberName: 'City', + memberFunction: (data) => data.Seller.City, + enabled: true, + childLevel: { memberName: 'Seller', memberFunction: (data) => data.Seller.Name, enabled: true } + }], + values: [{ + member: 'NumberOfUnits', + aggregate: { aggregator: IgxPivotNumericAggregate.sum, key: 'sum', label: 'Sum' }, + enabled: true + }], + filters: null + }; + + private readonly sanitizer = inject(DomSanitizer); + + protected readonly scssHtml = signal(null); + protected readonly cssHtml = signal(null); + + private highlighter: { codeToHtml: (code: string, opts: { lang: string; theme: string }) => string } | null = null; + + private readonly stage = viewChild.required>('stage'); + /** The compiled theme, read from the stylesheet: the CSS export needs every + * token, not just the roots, to work in an app with no grid-theme(). */ + private readonly themeTokens = signal>([]); + + constructor() { + afterNextRender(() => { + this.seedFromStylesheet(); + this.readCompiledTheme(); + }); + } + protected readonly previewStyle = computed>(() => { + const style: Record = {}; + const colors = this.colors(); + + for (const token of ALL_TOKENS) { + if (colors[token.key]) { + style[token.cssVar] = colors[token.key]; + } + } + if (colors.headerBackground && !colors.headerForeground) { + style['--ig-grid-header-text-color'] = HEADER_TEXT_ON_HEADER; + } + + style['--ig-size'] = `var(--ig-size-${this.size()})`; + style['--ig-radius-factor'] = `${this.radiusFactor()}`; + style['--ig-grid-row-border-color'] = this.horizontalDividers() ? DIVIDER : NO_DIVIDER; + + const columnRule = this.verticalDividers() ? DIVIDER : NO_DIVIDER; + style['--ig-grid-body-column-border-color-odd'] = columnRule; + style['--ig-grid-body-column-border-color-even'] = columnRule; + + if (this.zebra()) { + style['--ig-grid-row-even-background'] = ZEBRA; + } + + return style; + }); + protected readonly exportScss = computed(() => { + const colors = this.colors(); + const themeLines = ALL_TOKENS + .filter(token => colors[token.key]) + .map(token => ` ${token.scss}: ${colors[token.key]},`); + + if (!this.horizontalDividers()) { + themeLines.push(` $row-border-color: ${NO_DIVIDER},`); + } + if (this.verticalDividers()) { + themeLines.push(` $body-column-border-color-odd: ${DIVIDER},`); + themeLines.push(` $body-column-border-color-even: ${DIVIDER},`); + } + if (this.zebra()) { + themeLines.push(` $row-even-background: ${ZEBRA},`); + } + + const varLines = [ + ` --ig-size: var(--ig-size-${this.size()});`, + ` --ig-radius-factor: ${this.radiusFactor()};` + ]; + + if (!themeLines.length) { + return `.my-grid {\n${varLines.join('\n')}\n}`; + } + + return `.my-grid {\n${varLines.join('\n')}\n\n @include tokens(grid-theme(\n${themeLines.join('\n')}\n ));\n}`; + }); + + protected readonly exportCss = computed(() => { + const overrides = this.previewStyle(); + const base = this.themeTokens(); + + if (!base.length) { + const lines = Object.entries(overrides).map(([name, value]) => ` ${name}: ${value};`); + return `/* Overrides only -- requires a grid-theme() base to derive from. */\n.my-grid {\n${lines.join('\n')}\n}`; + } + + const emitted = new Set(); + const lines = base.map(([name, value]) => { + emitted.add(name); + return ` ${name}: ${overrides[name] ?? value};`; + }); + const extras = Object.entries(overrides) + .filter(([name]) => !emitted.has(name)) + .map(([name, value]) => ` ${name}: ${value};`); + + return `.my-grid {\n${[...extras, ...lines].join('\n')}\n}`; + }); + + protected setColor(key: TokenKey, value: string): void { + this.colors.update(current => ({ ...current, [key]: value })); + } + + protected reset(): void { + this.colors.set({ ...EMPTY_COLORS }); + this.size.set('medium'); + this.radiusFactor.set(0.4); + this.horizontalDividers.set(true); + this.verticalDividers.set(false); + this.zebra.set(false); + this.seedFromStylesheet(); + } + + protected async showCode(dialog: IgxDialogComponent): Promise { + // Loaded on demand so shiki stays out of the initial bundle. + if (!this.highlighter) { + // shiki/core with explicit grammars: the bundled entry point resolves + // languages dynamically and emits a chunk for every one it ships. + const [core, engine, scss, css, theme] = await Promise.all([ + import('shiki/core'), + import('shiki/engine/javascript'), + import('shiki/langs/scss.mjs'), + import('shiki/langs/css.mjs'), + import('shiki/themes/material-theme-lighter.mjs') + ]); + + this.highlighter = await core.createHighlighterCore({ + themes: [theme.default], + langs: [scss.default, css.default], + engine: engine.createJavaScriptRegexEngine() + }); + } + + const render = (code: string | null, lang: string) => code + ? this.sanitizer.bypassSecurityTrustHtml(this.highlighter.codeToHtml(code, { lang, theme: 'material-theme-lighter' })) + : null; + + this.scssHtml.set(render(this.exportScss(), 'scss')); + this.cssHtml.set(render(this.exportCss(), 'css')); + dialog.open(); + } + + protected copy(code: string | null, format: 'scss' | 'css'): void { + if (!code) return; + navigator.clipboard.writeText(code).then(() => { + this.copied.set(format); + setTimeout(() => this.copied.set(null), 2000); + }); + } + + protected onSize(args: { index: number }): void { + this.size.set((['small', 'medium', 'large'] as const)[args.index]); + } + + protected onRoundness(args: { index: number }): void { + this.radiusFactor.set([0, 0.4, 1][args.index]); + } + + protected onPreview(args: { index: number }): void { + this.preview.set((['grid', 'tree', 'hierarchical', 'pivot'] as const)[args.index]); + } + private readCompiledTheme(): void { + const tokens: Array<[string, string]> = []; + + for (const sheet of Array.from(document.styleSheets)) { + let rules: CSSRuleList; + + try { + rules = sheet.cssRules; + } catch { + continue; // cross-origin sheet, not ours + } + + for (const rule of Array.from(rules)) { + if (!(rule instanceof CSSStyleRule) || !rule.selectorText.includes('playground__stage')) { + continue; + } + + for (let i = 0; i < rule.style.length; i++) { + const name = rule.style.item(i); + if (name.startsWith('--ig-')) { + tokens.push([name, rule.style.getPropertyValue(name).trim()]); + } + } + } + } + + this.themeTokens.set(tokens); + } + + private seedFromStylesheet(): void { + const styles = getComputedStyle(this.stage().nativeElement); + + this.colors.update(current => ({ + ...current, + background: styles.getPropertyValue('--ig-grid-background').trim(), + accentColor: styles.getPropertyValue('--ig-grid-accent-color').trim() + })); + } +} diff --git a/src/app/theming/grid-theme-playground/theme-color-field.component.html b/src/app/theming/grid-theme-playground/theme-color-field.component.html new file mode 100644 index 0000000000..69afda312c --- /dev/null +++ b/src/app/theming/grid-theme-playground/theme-color-field.component.html @@ -0,0 +1,20 @@ +
+ {{ label() }} + + + + + + + + + @if (value()) { + + + + } + +
diff --git a/src/app/theming/grid-theme-playground/theme-color-field.component.scss b/src/app/theming/grid-theme-playground/theme-color-field.component.scss new file mode 100644 index 0000000000..f06f7a1d6a --- /dev/null +++ b/src/app/theming/grid-theme-playground/theme-color-field.component.scss @@ -0,0 +1,76 @@ +.color-field { + display: flex; + flex-direction: column; + gap: 6px; + + &__label { + font-size: 12px; + color: var(--ig-gray-700); + } + + igx-input-group { + --ig-input-group-focused-border-color: var(--ig-gray-500); + + [igxInput] { + font-size: 13px; + font-weight: 400; + } + } + + &__swatch-wrap { + position: relative; + width: 28px; + height: 28px; + flex-shrink: 0; + + input[type='color'] { + appearance: none; + position: absolute; + inset: 0; + opacity: 0; + width: 100%; + height: 100%; + cursor: pointer; + border: none; + padding: 0; + margin: 0; + } + } + + &__swatch { + position: absolute; + inset: 0; + border-radius: 5px; + border: 1px solid var(--ig-gray-400); + pointer-events: none; + } + + // "auto" -- the token is deriving rather than being overridden. + &__swatch--auto { + background: repeating-linear-gradient( + 45deg, + var(--ig-gray-200) 0 4px, + var(--ig-gray-100) 4px 8px + ); + } + + &__reset { + display: inline-flex; + align-items: center; + justify-content: center; + width: 24px; + height: 24px; + border: none; + border-radius: 4px; + background: transparent; + color: var(--ig-gray-600); + font-size: 14px; + cursor: pointer; + transition: color 120ms ease, background 120ms ease; + + &:hover { + color: var(--ig-gray-700); + background: var(--ig-gray-100); + } + } +} diff --git a/src/app/theming/grid-theme-playground/theme-color-field.component.ts b/src/app/theming/grid-theme-playground/theme-color-field.component.ts new file mode 100644 index 0000000000..47e532ae51 --- /dev/null +++ b/src/app/theming/grid-theme-playground/theme-color-field.component.ts @@ -0,0 +1,48 @@ +import { ChangeDetectionStrategy, Component, input, output } from '@angular/core'; +import { IgxInputGroupComponent, IgxInputDirective, IgxPrefixDirective, IgxSuffixDirective } from 'igniteui-angular/input-group'; +import { normalizeHexColor } from './color-utils'; + +@Component({ + selector: 'app-theme-color-field', + changeDetection: ChangeDetectionStrategy.OnPush, + templateUrl: './theme-color-field.component.html', + styleUrl: './theme-color-field.component.scss', + imports: [IgxInputGroupComponent, IgxInputDirective, IgxPrefixDirective, IgxSuffixDirective] +}) +export class ThemeColorFieldComponent { + public readonly label = input.required(); + public readonly value = input(''); + /** Seed for the native colour wheel while the value is empty ("auto"). */ + public readonly fallback = input('#808080'); + public readonly valueChange = output(); + + private pendingFrame: number | null = null; + private latestPickedValue: string | null = null; + protected onPick(event: Event): void { + this.latestPickedValue = (event.target as HTMLInputElement).value; + if (this.pendingFrame !== null) return; + + this.pendingFrame = requestAnimationFrame(() => { + this.pendingFrame = null; + if (this.latestPickedValue !== null) { + this.valueChange.emit(this.latestPickedValue); + this.latestPickedValue = null; + } + }); + } + + protected onTextChange(event: Event): void { + const inputEl = event.target as HTMLInputElement; + const normalized = normalizeHexColor(inputEl.value); + if (normalized) { + this.valueChange.emit(normalized); + inputEl.value = normalized; + } else { + inputEl.value = this.value(); + } + } + + protected reset(): void { + this.valueChange.emit(''); + } +} diff --git a/src/app/theming/theming-routes-data.ts b/src/app/theming/theming-routes-data.ts index a3a73cff12..91182ac677 100644 --- a/src/app/theming/theming-routes-data.ts +++ b/src/app/theming/theming-routes-data.ts @@ -12,5 +12,6 @@ export const themingRoutesData = { 'roundness': { displayName: 'Roundness', parentName: 'Themes' }, 'angular-sample': { displayName: 'Angular Material Theming', parentName: 'Themes' }, 'bootstrap-sample': { displayName: 'Bootstrap Theming', parentName: 'Themes' }, - 'card-sample-shadow': { displayName: 'card-sample-shadow', parentName: 'Shadows' } + 'card-sample-shadow': { displayName: 'card-sample-shadow', parentName: 'Shadows' }, + 'grid-theme-playground': { displayName: 'Grid Theme Playground', parentName: 'Themes' } }; diff --git a/src/app/theming/theming.routes.ts b/src/app/theming/theming.routes.ts index 2a0cd5e31b..e0c41f9e93 100644 --- a/src/app/theming/theming.routes.ts +++ b/src/app/theming/theming.routes.ts @@ -1,9 +1,8 @@ import { Routes } from '@angular/router'; import { AnimationsSampleComponent } from './animations/animations-sample-1/animations-sample-1.component'; import { AnimationsSample2Component } from './animations/animations-sample-2/animations-sample-2.component'; -import { AngularMaterialComponent } from './angular/angular-sample.component'; -import { BootstrapComponent } from './bootstrap/bootstrap-sample.component'; import { DefaultThemeSampleComponent } from './default-theme-sample/default-theme-sample.component'; +import { GridThemePlaygroundComponent } from './grid-theme-playground/grid-theme-playground.component'; import { DisplayDensityComponent } from './display-density/display-density.component'; import { RoundnessComponent } from './roundness/roundness-sample.component'; import { CardSampleShadowComponent} from './shadows/card-sample-shadow/card-sample-shadow'; @@ -55,12 +54,12 @@ export const ThemingRoutes: Routes = [ path: 'animations-sample-2' }, { - component: AngularMaterialComponent, + loadComponent: () => import('./angular/angular-sample.component').then(m => m.AngularMaterialComponent), data: themingRoutesData['angular-sample'], path: 'angular-sample' }, { - component: BootstrapComponent, + loadComponent: () => import('./bootstrap/bootstrap-sample.component').then(m => m.BootstrapComponent), data: themingRoutesData['bootstrap-sample'], path: 'bootstrap-sample' }, @@ -68,5 +67,10 @@ export const ThemingRoutes: Routes = [ component: TailwindSampleComponent, data: themingRoutesData['tailwind-sample'], path: 'tailwind-sample' + }, + { + component: GridThemePlaygroundComponent, + data: themingRoutesData['grid-theme-playground'], + path: 'grid-theme-playground' } ]; diff --git a/src/app/tree-grid/tree-grid-rowStyles-sample/tree-grid-rowStyle.component.ts b/src/app/tree-grid/tree-grid-rowStyles-sample/tree-grid-rowStyle.component.ts index b18c2bcc1a..324867face 100644 --- a/src/app/tree-grid/tree-grid-rowStyles-sample/tree-grid-rowStyle.component.ts +++ b/src/app/tree-grid/tree-grid-rowStyles-sample/tree-grid-rowStyle.component.ts @@ -25,7 +25,7 @@ export class TreeGridRowStylesComponent implements OnInit { row.data['Title'].includes('Senior') ? '#f8f9fa' : null; // eslint-disable-next-line @typescript-eslint/member-ordering - public rowStyles = { + public rowStyles: any = { background: this.background, 'border-left': (row: RowType) => row.data['Title'] === 'CEO' || row.data['Title'].includes('President') ? '2px solid' : null, diff --git a/src/app/tree-grid/tree-grid-style/layout.scss b/src/app/tree-grid/tree-grid-style/layout.scss index 0fda2fbb55..5c88726269 100644 --- a/src/app/tree-grid/tree-grid-style/layout.scss +++ b/src/app/tree-grid/tree-grid-style/layout.scss @@ -1,5 +1,9 @@ +:host { + display: block; +} + .grid__wrapper { - margin: 10px; + padding: 10px; } .cell__inner { diff --git a/src/app/tree-grid/tree-grid-style/tree-grid-style.component.html b/src/app/tree-grid/tree-grid-style/tree-grid-style.component.html index 9eeff6a075..751efd7181 100644 --- a/src/app/tree-grid/tree-grid-style/tree-grid-style.component.html +++ b/src/app/tree-grid/tree-grid-style/tree-grid-style.component.html @@ -1,6 +1,38 @@
- - +
+ Pick a theme + + + @for (theme of themes; track theme.class) { + + } + + +

+ Custom themes, not built-in: each is a grid-theme() with its + own background and accent. +

+
+ + +
@@ -8,8 +40,8 @@
- - - + + +
diff --git a/src/app/tree-grid/tree-grid-style/tree-grid-style.component.scss b/src/app/tree-grid/tree-grid-style/tree-grid-style.component.scss index 2c0d35a3be..9a14ff29e1 100644 --- a/src/app/tree-grid/tree-grid-style/tree-grid-style.component.scss +++ b/src/app/tree-grid/tree-grid-style/tree-grid-style.component.scss @@ -1,16 +1,141 @@ @use "layout.scss"; @use "igniteui-angular/theming" as *; -$background: #292826; -$foreground: #eeece1; -$accent: #ffcd0f; - -$custom-grid: grid-theme( - $background: $background, - $foreground: $foreground, - $accent-color: $accent, -); - -:host { - @include tokens($custom-grid); +$studio-bg: #faf4ed; +$studio-accent: #907aa9; +$ledger-bg: #eceff4; +$ledger-accent: #5e81ac; +$editorial-bg: #333c43; +$editorial-accent: #a7c080; +$midnight-bg: #282a36; +$midnight-accent: #bd93f9; + +.theme-studio { + --ig-size: var(--ig-size-large); + --ig-radius-factor: 0.6; + + @include tokens(grid-theme( + $background: $studio-bg, + $foreground: #575279, + $accent-color: $studio-accent, + $header-background: #fffaf3, + $header-border-color: #dfdad9, + $row-border-color: #f2e9e1, + $grid-border-color: #dfdad9, + $grid-shadow: (0 1px 3px rgba(87, 82, 121, 0.10), 0 1px 2px rgba(87, 82, 121, 0.06)) + )); +} + +.theme-ledger { + --ig-size: var(--ig-size-small); + --ig-radius-factor: 0; + + @include tokens(grid-theme( + $background: $ledger-bg, + $foreground: #2e3440, + $accent-color: $ledger-accent, + $header-background: #d8dee9, + $row-odd-background: #eceff4, + $row-even-background: #e5e9f0, + $body-column-border-color-odd: #d8dee9, + $body-column-border-color-even: #d8dee9, + $row-border-color: #d8dee9, + $grid-border-color: #c8d0dc + )); +} + +.theme-editorial { + --ig-size: var(--ig-size-large); + --ig-radius-factor: 0; + + @include tokens(grid-theme( + $schema: $dark-material-schema, + $background: $editorial-bg, + $foreground: #d3c6aa, + $accent-color: $editorial-accent, + $header-background: #3a464c, + $row-border-color: #333c43, + $grid-border-color: #333c43 + )); +} + +.theme-midnight { + --ig-size: var(--ig-size-medium); + --ig-radius-factor: 0.25; + + @include tokens(grid-theme( + $schema: $dark-material-schema, + $background: $midnight-bg, + $foreground: #f8f8f2, + $accent-color: $midnight-accent, + $header-background: #21222c, + $body-column-border-color-odd: #44475a, + $body-column-border-color-even: #44475a, + $row-border-color: #44475a, + $grid-border-color: #44475a + )); +} + +.grid__wrapper { + display: flex; + flex-direction: column; + gap: 16px; +} + +.theme-picker { + --ig-button-group-elevation: 0; + + display: flex; + flex-direction: column; + gap: 6px; + align-self: flex-start; +} + +.theme-picker__label { + font-size: 12px; + font-weight: 500; + letter-spacing: 0.04em; + color: var(--ig-gray-700); +} + +.theme-picker__hint { + margin: 0; + font-size: 12px; + line-height: 1.45; + color: var(--ig-gray-600); + + code { + font-family: 'JetBrains Mono', 'Fira Code', Consolas, monospace; + font-size: 11px; + } +} + +.theme-swatch { + display: inline-block; + min-width: 14px; + aspect-ratio: 1; + border-radius: 50%; + border: 1px solid var(--ig-gray-300); + vertical-align: -2px; + background: linear-gradient(135deg, var(--swatch-bg) 0 50%, var(--swatch-accent) 50% 100%); +} + +.theme-swatch--studio { + --swatch-bg: #{$studio-bg}; + --swatch-accent: #{$studio-accent}; +} + +.theme-swatch--ledger { + --swatch-bg: #{$ledger-bg}; + --swatch-accent: #{$ledger-accent}; +} + +.theme-swatch--editorial { + --swatch-bg: #{$editorial-bg}; + --swatch-accent: #{$editorial-accent}; +} + +.theme-swatch--midnight { + --swatch-bg: #{$midnight-bg}; + --swatch-accent: #{$midnight-accent}; } diff --git a/src/app/tree-grid/tree-grid-style/tree-grid-style.component.ts b/src/app/tree-grid/tree-grid-style/tree-grid-style.component.ts index 653f39c22b..f2a2472061 100644 --- a/src/app/tree-grid/tree-grid-style/tree-grid-style.component.ts +++ b/src/app/tree-grid/tree-grid-style/tree-grid-style.component.ts @@ -1,21 +1,35 @@ -import { Component, OnInit } from '@angular/core'; -import { EMPLOYEE_FLAT_AVATARS_DATA } from '../data/employees-flat-avatars'; -import { IgxTreeGridComponent } from 'igniteui-angular/grids/tree-grid'; -import { IgxCellTemplateDirective, IgxColumnComponent } from 'igniteui-angular/grids/core'; +import { Component, OnInit, signal } from '@angular/core'; import { IgxAvatarComponent } from 'igniteui-angular/avatar'; +import { IgxButtonGroupComponent } from 'igniteui-angular/button-group'; +import { IgxButtonDirective } from 'igniteui-angular/directives'; +import { IgxCellTemplateDirective, IgxColumnComponent } from 'igniteui-angular/grids/core'; +import { IgxTreeGridComponent } from 'igniteui-angular/grids/tree-grid'; +import { EMPLOYEE_FLAT_AVATARS_DATA } from '../data/employees-flat-avatars'; import { IgxPreventDocumentScrollDirective } from '../../directives/prevent-scroll.directive'; @Component({ selector: 'app-tree-grid-style', styleUrls: ['./tree-grid-style.component.scss'], templateUrl: './tree-grid-style.component.html', - imports: [IgxTreeGridComponent, IgxPreventDocumentScrollDirective, IgxColumnComponent, IgxCellTemplateDirective, IgxAvatarComponent] + imports: [IgxTreeGridComponent, IgxPreventDocumentScrollDirective, IgxColumnComponent, IgxCellTemplateDirective, IgxAvatarComponent, IgxButtonGroupComponent, IgxButtonDirective] }) export class TreeGridStyleComponent implements OnInit { public data: any[]; + public themes = [ + { label: 'Studio', class: 'theme-studio', swatch: 'theme-swatch--studio' }, + { label: 'Ledger', class: 'theme-ledger', swatch: 'theme-swatch--ledger' }, + { label: 'Editorial', class: 'theme-editorial', swatch: 'theme-swatch--editorial' }, + { label: 'Midnight', class: 'theme-midnight', swatch: 'theme-swatch--midnight' } + ]; + + public activeTheme = signal(this.themes[0].class); public ngOnInit() { this.data = EMPLOYEE_FLAT_AVATARS_DATA(); } + + public selectTheme(args: { index: number }) { + this.activeTheme.set(this.themes[args.index].class); + } } diff --git a/src/app/tree-grid/tree-grid-validation-style/tree-grid-validation-style.component.ts b/src/app/tree-grid/tree-grid-validation-style/tree-grid-validation-style.component.ts index dad7ada413..b6d515bcd4 100644 --- a/src/app/tree-grid/tree-grid-validation-style/tree-grid-validation-style.component.ts +++ b/src/app/tree-grid/tree-grid-validation-style/tree-grid-validation-style.component.ts @@ -17,7 +17,7 @@ export class TreeGridValidationStyleComponent implements OnInit { public data: IEmployee[]; public columns: any[]; public selectionMode = 'multiple'; - public rowStyles = { + public rowStyles: any = { background: (row: RowType) => row.cells.find(c => c.validation.errors !== null && c.validation.errors !== undefined) ? '#FF000033' : '#00000000' }; public cellStyles = { From dc183449b8c659fb7e3ca9aa564609f19c662d27 Mon Sep 17 00:00:00 2001 From: Simeon Simeonoff Date: Fri, 28 Aug 2026 17:18:29 +0300 Subject: [PATCH 02/22] lint: fix lint errors --- .../grid-theme-playground/grid-theme-playground.component.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/theming/grid-theme-playground/grid-theme-playground.component.ts b/src/app/theming/grid-theme-playground/grid-theme-playground.component.ts index f16a90f90d..1ed058dded 100644 --- a/src/app/theming/grid-theme-playground/grid-theme-playground.component.ts +++ b/src/app/theming/grid-theme-playground/grid-theme-playground.component.ts @@ -130,7 +130,7 @@ export class GridThemePlaygroundComponent { private readonly stage = viewChild.required>('stage'); /** The compiled theme, read from the stylesheet: the CSS export needs every * token, not just the roots, to work in an app with no grid-theme(). */ - private readonly themeTokens = signal>([]); + private readonly themeTokens = signal<[string, string][]>([]); constructor() { afterNextRender(() => { @@ -278,7 +278,7 @@ export class GridThemePlaygroundComponent { this.preview.set((['grid', 'tree', 'hierarchical', 'pivot'] as const)[args.index]); } private readCompiledTheme(): void { - const tokens: Array<[string, string]> = []; + const tokens: [string, string][] = []; for (const sheet of Array.from(document.styleSheets)) { let rules: CSSRuleList; From f7a74fc4820179bed7470d17382db2bf023abf0b Mon Sep 17 00:00:00 2001 From: Simeon Simeonoff Date: Fri, 28 Aug 2026 17:22:22 +0300 Subject: [PATCH 03/22] revert(theming): restore eager routes for Material and Bootstrap samples --- src/app/theming/theming.routes.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/app/theming/theming.routes.ts b/src/app/theming/theming.routes.ts index e0c41f9e93..b1e0d0aac8 100644 --- a/src/app/theming/theming.routes.ts +++ b/src/app/theming/theming.routes.ts @@ -1,6 +1,8 @@ import { Routes } from '@angular/router'; import { AnimationsSampleComponent } from './animations/animations-sample-1/animations-sample-1.component'; import { AnimationsSample2Component } from './animations/animations-sample-2/animations-sample-2.component'; +import { AngularMaterialComponent } from './angular/angular-sample.component'; +import { BootstrapComponent } from './bootstrap/bootstrap-sample.component'; import { DefaultThemeSampleComponent } from './default-theme-sample/default-theme-sample.component'; import { GridThemePlaygroundComponent } from './grid-theme-playground/grid-theme-playground.component'; import { DisplayDensityComponent } from './display-density/display-density.component'; @@ -54,12 +56,12 @@ export const ThemingRoutes: Routes = [ path: 'animations-sample-2' }, { - loadComponent: () => import('./angular/angular-sample.component').then(m => m.AngularMaterialComponent), + component: AngularMaterialComponent, data: themingRoutesData['angular-sample'], path: 'angular-sample' }, { - loadComponent: () => import('./bootstrap/bootstrap-sample.component').then(m => m.BootstrapComponent), + component: BootstrapComponent, data: themingRoutesData['bootstrap-sample'], path: 'bootstrap-sample' }, From e419e46753f74be0f857b3b0c3ff5c1747f7f215 Mon Sep 17 00:00:00 2001 From: Simeon Simeonoff Date: Mon, 31 Aug 2026 08:34:52 +0300 Subject: [PATCH 04/22] refactor(grid-theme-playground): fix errors and update code snippet theme --- .../grid-theme-playground.component.ts | 7 ++----- src/server.ts | 8 +++++++- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/app/theming/grid-theme-playground/grid-theme-playground.component.ts b/src/app/theming/grid-theme-playground/grid-theme-playground.component.ts index 1ed058dded..8e5a916563 100644 --- a/src/app/theming/grid-theme-playground/grid-theme-playground.component.ts +++ b/src/app/theming/grid-theme-playground/grid-theme-playground.component.ts @@ -230,16 +230,13 @@ export class GridThemePlaygroundComponent { } protected async showCode(dialog: IgxDialogComponent): Promise { - // Loaded on demand so shiki stays out of the initial bundle. if (!this.highlighter) { - // shiki/core with explicit grammars: the bundled entry point resolves - // languages dynamically and emits a chunk for every one it ships. const [core, engine, scss, css, theme] = await Promise.all([ import('shiki/core'), import('shiki/engine/javascript'), import('shiki/langs/scss.mjs'), import('shiki/langs/css.mjs'), - import('shiki/themes/material-theme-lighter.mjs') + import('shiki/themes/dark-plus.mjs') ]); this.highlighter = await core.createHighlighterCore({ @@ -250,7 +247,7 @@ export class GridThemePlaygroundComponent { } const render = (code: string | null, lang: string) => code - ? this.sanitizer.bypassSecurityTrustHtml(this.highlighter.codeToHtml(code, { lang, theme: 'material-theme-lighter' })) + ? this.sanitizer.bypassSecurityTrustHtml(this.highlighter.codeToHtml(code, { lang, theme: 'dark-plus' })) : null; this.scssHtml.set(render(this.exportScss(), 'scss')); diff --git a/src/server.ts b/src/server.ts index 72bf56bec2..3af8c6cd81 100644 --- a/src/server.ts +++ b/src/server.ts @@ -46,7 +46,13 @@ app.use('/**', (req, res, next) => { .then((response) => response ? writeResponseToNodeResponse(response, res) : next() ) - .catch(next); + .catch((error: unknown) => { + if (error instanceof Error && error.name === 'AbortError') { + return; + } + + next(error); + }); }); /** From b507b6201e7215408faa2e12fd255244a0d9277e Mon Sep 17 00:00:00 2001 From: Hristo Hristov <57346540+Hristo313@users.noreply.github.com> Date: Wed, 9 Sep 2026 11:31:43 +0300 Subject: [PATCH 05/22] feat(button): update samples content (#4019) --- live-editing/configs/ButtonConfigGenerator.ts | 87 +++++-- .../button/_bootstrap-button-theme.scss | 61 +++++ .../button-contained.component.html | 7 + .../button-contained.component.scss | 11 + .../button-contained.component.ts | 11 + .../button-download.component.html | 3 + .../button-download.component.scss | 11 + .../button-download.component.ts | 10 + .../button-fab/button-fab.component.html | 7 + .../button-fab/button-fab.component.scss | 11 + .../button-fab/button-fab.component.ts} | 8 +- .../button-flat/button-flat.component.html | 7 + .../button-flat/button-flat.component.scss | 11 + .../button-flat/button-flat.component.ts | 11 + .../button-interaction-states.component.html | 12 + .../button-interaction-states.component.scss | 48 ++++ .../button-interaction-states.component.ts | 18 ++ .../button-layout.component.html | 8 + .../button-layout.component.scss | 26 ++ .../button-layout/button-layout.component.ts | 12 + .../button-outlined.component.html | 7 + .../button-outlined.component.scss | 11 + .../button-outlined.component.ts | 11 + .../button-overview.component.html | 15 ++ .../button-overview.component.scss | 39 +++ .../button-overview.component.ts | 12 + .../button-size/button-size.component.html | 20 ++ .../button-size/button-size.component.scss | 63 +++++ .../button-size/button-size.component.ts | 15 ++ .../button-states.component.html | 30 +++ .../button-states.component.scss | 16 ++ .../button-states/button-states.component.ts | 11 + .../button-styling.component.html | 14 + .../button-styling.component.scss | 39 +++ .../button-styling.component.ts | 12 + .../button/button-styling/layout.scss | 41 +++ .../button-tailwind-styling.component.html | 14 + .../button-tailwind-styling.component.scss | 6 + .../button-tailwind-styling.component.ts | 12 + .../button-tailwind-styling/layout.scss | 56 ++++ .../buttons-disabled-sample.html | 1 - .../buttons-disabled-sample.scss | 3 - .../buttons-disabled-sample.ts | 10 - .../buttons-display-density.component.html | 27 -- .../buttons-display-density.component.scss | 15 -- .../buttons-display-density.component.ts | 32 --- .../buttons-roundness-sample.html | 22 -- .../buttons-roundness-sample.scss | 44 ---- .../buttons-roundness-sample.ts | 11 - .../buttons-sample-1.component.html | 11 - .../buttons-sample-1.component.scss | 13 - .../buttons-sample-1.component.ts | 11 - .../buttons-sample-2.component.html | 1 - .../buttons-sample-2.component.scss | 3 - .../buttons-sample-2.component.ts | 10 - .../buttons-sample-3.component.html | 1 - .../buttons-sample-3.component.scss | 3 - .../buttons-sample-3.component.ts | 10 - .../buttons-sample-4.component.html | 1 - .../buttons-sample-4.component.scss | 3 - .../buttons-sample-4.component.ts | 10 - .../buttons-sample-5.component.html | 1 - .../buttons-sample-5.component.scss | 3 - .../buttons-sample-5.component.ts | 10 - .../buttons-sample-6.component.html | 8 - .../buttons-sample-6.component.scss | 3 - .../buttons-sample-7.component.html | 3 - .../buttons-sample-7.component.scss | 3 - .../buttons-sample-7.component.ts | 11 - .../buttons-sample-8.component.html | 1 - .../buttons-sample-8.component.scss | 3 - .../buttons-sample-8.component.ts | 10 - .../buttons-style.component.html | 22 -- .../buttons-style.component.scss | 241 ------------------ .../buttons-style/buttons-style.component.ts | 14 - .../buttons/buttons-style/layout.scss | 47 ---- .../buttons-tailwind-style.component.html | 14 - .../buttons-tailwind-style.component.scss | 1 - .../buttons-tailwind-style.component.ts | 10 - .../buttons-tailwind-style/layout.scss | 9 - .../data-entries/data-entries-routes-data.ts | 24 +- src/app/data-entries/data-entries.routes.ts | 102 ++++---- 82 files changed, 859 insertions(+), 747 deletions(-) create mode 100644 src/app/data-entries/button/_bootstrap-button-theme.scss create mode 100644 src/app/data-entries/button/button-contained/button-contained.component.html create mode 100644 src/app/data-entries/button/button-contained/button-contained.component.scss create mode 100644 src/app/data-entries/button/button-contained/button-contained.component.ts create mode 100644 src/app/data-entries/button/button-download/button-download.component.html create mode 100644 src/app/data-entries/button/button-download/button-download.component.scss create mode 100644 src/app/data-entries/button/button-download/button-download.component.ts create mode 100644 src/app/data-entries/button/button-fab/button-fab.component.html create mode 100644 src/app/data-entries/button/button-fab/button-fab.component.scss rename src/app/data-entries/{buttons/buttons-sample-6/buttons-sample-6.component.ts => button/button-fab/button-fab.component.ts} (55%) create mode 100644 src/app/data-entries/button/button-flat/button-flat.component.html create mode 100644 src/app/data-entries/button/button-flat/button-flat.component.scss create mode 100644 src/app/data-entries/button/button-flat/button-flat.component.ts create mode 100644 src/app/data-entries/button/button-interaction-states/button-interaction-states.component.html create mode 100644 src/app/data-entries/button/button-interaction-states/button-interaction-states.component.scss create mode 100644 src/app/data-entries/button/button-interaction-states/button-interaction-states.component.ts create mode 100644 src/app/data-entries/button/button-layout/button-layout.component.html create mode 100644 src/app/data-entries/button/button-layout/button-layout.component.scss create mode 100644 src/app/data-entries/button/button-layout/button-layout.component.ts create mode 100644 src/app/data-entries/button/button-outlined/button-outlined.component.html create mode 100644 src/app/data-entries/button/button-outlined/button-outlined.component.scss create mode 100644 src/app/data-entries/button/button-outlined/button-outlined.component.ts create mode 100644 src/app/data-entries/button/button-overview/button-overview.component.html create mode 100644 src/app/data-entries/button/button-overview/button-overview.component.scss create mode 100644 src/app/data-entries/button/button-overview/button-overview.component.ts create mode 100644 src/app/data-entries/button/button-size/button-size.component.html create mode 100644 src/app/data-entries/button/button-size/button-size.component.scss create mode 100644 src/app/data-entries/button/button-size/button-size.component.ts create mode 100644 src/app/data-entries/button/button-states/button-states.component.html create mode 100644 src/app/data-entries/button/button-states/button-states.component.scss create mode 100644 src/app/data-entries/button/button-states/button-states.component.ts create mode 100644 src/app/data-entries/button/button-styling/button-styling.component.html create mode 100644 src/app/data-entries/button/button-styling/button-styling.component.scss create mode 100644 src/app/data-entries/button/button-styling/button-styling.component.ts create mode 100644 src/app/data-entries/button/button-styling/layout.scss create mode 100644 src/app/data-entries/button/button-tailwind-styling/button-tailwind-styling.component.html create mode 100644 src/app/data-entries/button/button-tailwind-styling/button-tailwind-styling.component.scss create mode 100644 src/app/data-entries/button/button-tailwind-styling/button-tailwind-styling.component.ts create mode 100644 src/app/data-entries/button/button-tailwind-styling/layout.scss delete mode 100644 src/app/data-entries/buttons/buttons-disabled-sample/buttons-disabled-sample.html delete mode 100644 src/app/data-entries/buttons/buttons-disabled-sample/buttons-disabled-sample.scss delete mode 100644 src/app/data-entries/buttons/buttons-disabled-sample/buttons-disabled-sample.ts delete mode 100644 src/app/data-entries/buttons/buttons-display-density/buttons-display-density.component.html delete mode 100644 src/app/data-entries/buttons/buttons-display-density/buttons-display-density.component.scss delete mode 100644 src/app/data-entries/buttons/buttons-display-density/buttons-display-density.component.ts delete mode 100644 src/app/data-entries/buttons/buttons-roundness-sample/buttons-roundness-sample.html delete mode 100644 src/app/data-entries/buttons/buttons-roundness-sample/buttons-roundness-sample.scss delete mode 100644 src/app/data-entries/buttons/buttons-roundness-sample/buttons-roundness-sample.ts delete mode 100644 src/app/data-entries/buttons/buttons-sample-1/buttons-sample-1.component.html delete mode 100644 src/app/data-entries/buttons/buttons-sample-1/buttons-sample-1.component.scss delete mode 100644 src/app/data-entries/buttons/buttons-sample-1/buttons-sample-1.component.ts delete mode 100644 src/app/data-entries/buttons/buttons-sample-2/buttons-sample-2.component.html delete mode 100644 src/app/data-entries/buttons/buttons-sample-2/buttons-sample-2.component.scss delete mode 100644 src/app/data-entries/buttons/buttons-sample-2/buttons-sample-2.component.ts delete mode 100644 src/app/data-entries/buttons/buttons-sample-3/buttons-sample-3.component.html delete mode 100644 src/app/data-entries/buttons/buttons-sample-3/buttons-sample-3.component.scss delete mode 100644 src/app/data-entries/buttons/buttons-sample-3/buttons-sample-3.component.ts delete mode 100644 src/app/data-entries/buttons/buttons-sample-4/buttons-sample-4.component.html delete mode 100644 src/app/data-entries/buttons/buttons-sample-4/buttons-sample-4.component.scss delete mode 100644 src/app/data-entries/buttons/buttons-sample-4/buttons-sample-4.component.ts delete mode 100644 src/app/data-entries/buttons/buttons-sample-5/buttons-sample-5.component.html delete mode 100644 src/app/data-entries/buttons/buttons-sample-5/buttons-sample-5.component.scss delete mode 100644 src/app/data-entries/buttons/buttons-sample-5/buttons-sample-5.component.ts delete mode 100644 src/app/data-entries/buttons/buttons-sample-6/buttons-sample-6.component.html delete mode 100644 src/app/data-entries/buttons/buttons-sample-6/buttons-sample-6.component.scss delete mode 100644 src/app/data-entries/buttons/buttons-sample-7/buttons-sample-7.component.html delete mode 100644 src/app/data-entries/buttons/buttons-sample-7/buttons-sample-7.component.scss delete mode 100644 src/app/data-entries/buttons/buttons-sample-7/buttons-sample-7.component.ts delete mode 100644 src/app/data-entries/buttons/buttons-sample-8/buttons-sample-8.component.html delete mode 100644 src/app/data-entries/buttons/buttons-sample-8/buttons-sample-8.component.scss delete mode 100644 src/app/data-entries/buttons/buttons-sample-8/buttons-sample-8.component.ts delete mode 100644 src/app/data-entries/buttons/buttons-style/buttons-style.component.html delete mode 100644 src/app/data-entries/buttons/buttons-style/buttons-style.component.scss delete mode 100644 src/app/data-entries/buttons/buttons-style/buttons-style.component.ts delete mode 100644 src/app/data-entries/buttons/buttons-style/layout.scss delete mode 100644 src/app/data-entries/buttons/buttons-tailwind-style/buttons-tailwind-style.component.html delete mode 100644 src/app/data-entries/buttons/buttons-tailwind-style/buttons-tailwind-style.component.scss delete mode 100644 src/app/data-entries/buttons/buttons-tailwind-style/buttons-tailwind-style.component.ts delete mode 100644 src/app/data-entries/buttons/buttons-tailwind-style/layout.scss diff --git a/live-editing/configs/ButtonConfigGenerator.ts b/live-editing/configs/ButtonConfigGenerator.ts index 5dc013ef22..fbdecc8022 100644 --- a/live-editing/configs/ButtonConfigGenerator.ts +++ b/live-editing/configs/ButtonConfigGenerator.ts @@ -1,48 +1,95 @@ -import { IgxButtonGroupModule } from 'igniteui-angular/button-group'; -import { IgxButtonModule, IgxRippleModule } from 'igniteui-angular/directives'; -import { IgxIconModule } from 'igniteui-angular/icon'; -import { AppModuleConfig, Config, IConfigGenerator } from 'igniteui-live-editing' +import { Config, IConfigGenerator } from 'igniteui-live-editing' import { BaseAppConfig } from './BaseConfig'; -import { ButtonsRoundnessComponent } from '../../src/app/data-entries/buttons/buttons-roundness-sample/buttons-roundness-sample'; export class ButtonConfigGenerator implements IConfigGenerator { public generateConfigs(): Config[] { const configs = new Array(); - // buttons sample 1 + // button overview configs.push(new Config({ - component: 'ButtonsSample1Component', + component: 'ButtonOverviewComponent', appConfig: BaseAppConfig, - shortenComponentPathBy: "/data-entries/buttons/" + shortenComponentPathBy: "/data-entries/button/" })); - // buttons roundness + // flat button configs.push(new Config({ - component: 'ButtonsDisabledComponent', + component: 'ButtonFlatComponent', appConfig: BaseAppConfig, - shortenComponentPathBy: "/data-entries/buttons/" + shortenComponentPathBy: "/data-entries/button/" })); - // buttons display density + // button interaction states configs.push(new Config({ - component: 'ButtonsDisplayDensityComponent', + component: 'ButtonInteractionStatesComponent', appConfig: BaseAppConfig, - shortenComponentPathBy: "/data-entries/buttons/" + shortenComponentPathBy: "/data-entries/button/" })); + // button layout configs.push(new Config({ - component: 'ButtonsRoundnessComponent', + component: 'ButtonLayoutComponent', appConfig: BaseAppConfig, - shortenComponentPathBy: "/data-entries/buttons/" + shortenComponentPathBy: "/data-entries/button/" })); - // button style + // contained button configs.push(new Config({ - component: 'ButtonsStyleComponent', - additionalFiles: ["/src/app/data-entries/buttons/buttons-style/layout.scss"], + component: 'ButtonContainedComponent', appConfig: BaseAppConfig, - shortenComponentPathBy: "/data-entries/buttons/" + shortenComponentPathBy: "/data-entries/button/" + })); + + // floating action button + configs.push(new Config({ + component: 'ButtonFabComponent', + appConfig: BaseAppConfig, + shortenComponentPathBy: "/data-entries/button/" + })); + + // outlined button + configs.push(new Config({ + component: 'ButtonOutlinedComponent', + appConfig: BaseAppConfig, + shortenComponentPathBy: "/data-entries/button/" + })); + + // button states + configs.push(new Config({ + component: 'ButtonStatesComponent', + appConfig: BaseAppConfig, + shortenComponentPathBy: "/data-entries/button/" + })); + + // button size + configs.push(new Config({ + component: 'ButtonSizeComponent', + appConfig: BaseAppConfig, + shortenComponentPathBy: "/data-entries/button/" + })); + + // download button + configs.push(new Config({ + component: 'ButtonDownloadComponent', + appConfig: BaseAppConfig, + shortenComponentPathBy: "/data-entries/button/" + })); + + // button styling + configs.push(new Config({ + component: 'ButtonStylingComponent', + additionalFiles: ["/src/app/data-entries/button/button-styling/layout.scss"], + appConfig: BaseAppConfig, + shortenComponentPathBy: "/data-entries/button/" + })); + + // button tailwind styling + configs.push(new Config({ + component: 'ButtonTailwindStylingComponent', + additionalFiles: ["/src/app/data-entries/button/button-tailwind-styling/layout.scss"], + appConfig: BaseAppConfig, + shortenComponentPathBy: "/data-entries/button/" })); return configs; diff --git a/src/app/data-entries/button/_bootstrap-button-theme.scss b/src/app/data-entries/button/_bootstrap-button-theme.scss new file mode 100644 index 0000000000..6ce81fd333 --- /dev/null +++ b/src/app/data-entries/button/_bootstrap-button-theme.scss @@ -0,0 +1,61 @@ +@use 'igniteui-angular/theming' as *; +@use 'igniteui-angular/lib/core/styles/components/button/button-component' as button; +@use 'igniteui-angular/lib/core/styles/themes/presets/igniteui-bootstrap-light'; +@use 'igniteui-theming/sass/typography/presets' as typography-presets; + +:host ::ng-deep { + @include typography( + $font-family: typography-presets.$bootstrap-typeface, + $type-scale: typography-presets.$bootstrap-type-scale + ); + + @include button( + $flat: flat-button-theme( + $schema: $light-bootstrap-schema, + $foreground: color($light-bootstrap-palette, 'primary'), + $hover-foreground: color($light-bootstrap-palette, 'primary'), + $disabled-foreground: color($light-bootstrap-palette, 'primary', 200) + ), + $contained: contained-button-theme( + $schema: $light-bootstrap-schema, + $background: color($light-bootstrap-palette, 'primary'), + $foreground: var(--ig-gray-50), + $hover-background: color($light-bootstrap-palette, 'primary', 600), + $hover-foreground: var(--ig-gray-50), + $focus-background: color($light-bootstrap-palette, 'primary', 800), + $focus-foreground: var(--ig-gray-50), + $focus-hover-background: color($light-bootstrap-palette, 'primary', 600), + $focus-hover-foreground: var(--ig-gray-50), + $disabled-background: color($light-bootstrap-palette, 'primary', 50), + $disabled-foreground: color($light-bootstrap-palette, 'primary', 200) + ), + $outlined: outlined-button-theme( + $schema: $light-bootstrap-schema, + $foreground: color($light-bootstrap-palette, 'primary'), + $hover-background: color($light-bootstrap-palette, 'primary'), + $hover-foreground: var(--ig-gray-50), + $disabled-foreground: color($light-bootstrap-palette, 'primary', 200), + $disabled-border-color: color($light-bootstrap-palette, 'primary', 50) + ), + $fab: fab-button-theme( + $schema: $light-bootstrap-schema, + $background: color($light-bootstrap-palette, 'secondary'), + $foreground: var(--ig-gray-50), + $hover-background: color($light-bootstrap-palette, 'primary'), + $hover-foreground: var(--ig-gray-50), + $disabled-background: color($light-bootstrap-palette, 'gray', 300), + $disabled-foreground: color($light-bootstrap-palette, 'gray', 500), + $resting-shadow: none, + $hover-shadow: none + ) + ); + @include button.component(); + + [igxButton] { + --ig-size: var(--ig-size-medium); + } + + button[igxButton='fab'] { + --ig-size: var(--ig-size-large); + } +} diff --git a/src/app/data-entries/button/button-contained/button-contained.component.html b/src/app/data-entries/button/button-contained/button-contained.component.html new file mode 100644 index 0000000000..48a7b7ad3d --- /dev/null +++ b/src/app/data-entries/button/button-contained/button-contained.component.html @@ -0,0 +1,7 @@ +
+ +
diff --git a/src/app/data-entries/button/button-contained/button-contained.component.scss b/src/app/data-entries/button/button-contained/button-contained.component.scss new file mode 100644 index 0000000000..2bfc8c5087 --- /dev/null +++ b/src/app/data-entries/button/button-contained/button-contained.component.scss @@ -0,0 +1,11 @@ +@use '../_bootstrap-button-theme'; + +.button-sample { + display: flex; + padding: 2.5rem; +} + +.button-sample button { + width: 46%; + margin: auto; +} diff --git a/src/app/data-entries/button/button-contained/button-contained.component.ts b/src/app/data-entries/button/button-contained/button-contained.component.ts new file mode 100644 index 0000000000..7caea5fad4 --- /dev/null +++ b/src/app/data-entries/button/button-contained/button-contained.component.ts @@ -0,0 +1,11 @@ +import { Component } from '@angular/core'; +import { IgxButtonDirective } from 'igniteui-angular/directives'; +import { IgxIconComponent } from 'igniteui-angular/icon'; + +@Component({ + selector: 'app-button-contained', + styleUrls: ['./button-contained.component.scss'], + templateUrl: './button-contained.component.html', + imports: [IgxButtonDirective, IgxIconComponent] +}) +export class ButtonContainedComponent { } diff --git a/src/app/data-entries/button/button-download/button-download.component.html b/src/app/data-entries/button/button-download/button-download.component.html new file mode 100644 index 0000000000..165292aa2e --- /dev/null +++ b/src/app/data-entries/button/button-download/button-download.component.html @@ -0,0 +1,3 @@ + diff --git a/src/app/data-entries/button/button-download/button-download.component.scss b/src/app/data-entries/button/button-download/button-download.component.scss new file mode 100644 index 0000000000..54492fe328 --- /dev/null +++ b/src/app/data-entries/button/button-download/button-download.component.scss @@ -0,0 +1,11 @@ +@use '../_bootstrap-button-theme'; + +.button-sample { + display: flex; + padding: 2.5rem; +} + +.button-sample a { + width: 46%; + margin: auto; +} diff --git a/src/app/data-entries/button/button-download/button-download.component.ts b/src/app/data-entries/button/button-download/button-download.component.ts new file mode 100644 index 0000000000..f382891209 --- /dev/null +++ b/src/app/data-entries/button/button-download/button-download.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; +import { IgxButtonDirective } from 'igniteui-angular/directives'; + +@Component({ + selector: 'app-button-download', + styleUrls: ['./button-download.component.scss'], + templateUrl: './button-download.component.html', + imports: [IgxButtonDirective] +}) +export class ButtonDownloadComponent { } diff --git a/src/app/data-entries/button/button-fab/button-fab.component.html b/src/app/data-entries/button/button-fab/button-fab.component.html new file mode 100644 index 0000000000..8eaaad311b --- /dev/null +++ b/src/app/data-entries/button/button-fab/button-fab.component.html @@ -0,0 +1,7 @@ +
+ +
diff --git a/src/app/data-entries/button/button-fab/button-fab.component.scss b/src/app/data-entries/button/button-fab/button-fab.component.scss new file mode 100644 index 0000000000..8bb51245de --- /dev/null +++ b/src/app/data-entries/button/button-fab/button-fab.component.scss @@ -0,0 +1,11 @@ +@use '../_bootstrap-button-theme'; + +.button-sample { + display: flex; + padding: 2rem; +} + +.button-sample button { + width: 45%; + margin: auto; +} diff --git a/src/app/data-entries/buttons/buttons-sample-6/buttons-sample-6.component.ts b/src/app/data-entries/button/button-fab/button-fab.component.ts similarity index 55% rename from src/app/data-entries/buttons/buttons-sample-6/buttons-sample-6.component.ts rename to src/app/data-entries/button/button-fab/button-fab.component.ts index 6d07452311..d611bb25ea 100644 --- a/src/app/data-entries/buttons/buttons-sample-6/buttons-sample-6.component.ts +++ b/src/app/data-entries/button/button-fab/button-fab.component.ts @@ -3,9 +3,9 @@ import { IgxButtonDirective } from 'igniteui-angular/directives'; import { IgxIconComponent } from 'igniteui-angular/icon'; @Component({ - selector: 'app-buttons-sample-6', - styleUrls: ['./buttons-sample-6.component.scss'], - templateUrl: './buttons-sample-6.component.html', + selector: 'app-button-fab', + styleUrls: ['./button-fab.component.scss'], + templateUrl: './button-fab.component.html', imports: [IgxButtonDirective, IgxIconComponent] }) -export class ButtonsSample6Component { } +export class ButtonFabComponent { } diff --git a/src/app/data-entries/button/button-flat/button-flat.component.html b/src/app/data-entries/button/button-flat/button-flat.component.html new file mode 100644 index 0000000000..c5c68089a8 --- /dev/null +++ b/src/app/data-entries/button/button-flat/button-flat.component.html @@ -0,0 +1,7 @@ +
+ +
diff --git a/src/app/data-entries/button/button-flat/button-flat.component.scss b/src/app/data-entries/button/button-flat/button-flat.component.scss new file mode 100644 index 0000000000..2bfc8c5087 --- /dev/null +++ b/src/app/data-entries/button/button-flat/button-flat.component.scss @@ -0,0 +1,11 @@ +@use '../_bootstrap-button-theme'; + +.button-sample { + display: flex; + padding: 2.5rem; +} + +.button-sample button { + width: 46%; + margin: auto; +} diff --git a/src/app/data-entries/button/button-flat/button-flat.component.ts b/src/app/data-entries/button/button-flat/button-flat.component.ts new file mode 100644 index 0000000000..ab6dcb1229 --- /dev/null +++ b/src/app/data-entries/button/button-flat/button-flat.component.ts @@ -0,0 +1,11 @@ +import { Component } from '@angular/core'; +import { IgxButtonDirective } from 'igniteui-angular/directives'; +import { IgxIconComponent } from 'igniteui-angular/icon'; + +@Component({ + selector: 'app-button-flat', + styleUrls: ['./button-flat.component.scss'], + templateUrl: './button-flat.component.html', + imports: [IgxButtonDirective, IgxIconComponent] +}) +export class ButtonFlatComponent { } diff --git a/src/app/data-entries/button/button-interaction-states/button-interaction-states.component.html b/src/app/data-entries/button/button-interaction-states/button-interaction-states.component.html new file mode 100644 index 0000000000..fca47f84e6 --- /dev/null +++ b/src/app/data-entries/button/button-interaction-states/button-interaction-states.component.html @@ -0,0 +1,12 @@ +
+ @for (state of states; track state.value) { +
+ {{ state.label }} + +
+ } +
diff --git a/src/app/data-entries/button/button-interaction-states/button-interaction-states.component.scss b/src/app/data-entries/button/button-interaction-states/button-interaction-states.component.scss new file mode 100644 index 0000000000..bb5a34685d --- /dev/null +++ b/src/app/data-entries/button/button-interaction-states/button-interaction-states.component.scss @@ -0,0 +1,48 @@ +@use '../_bootstrap-button-theme'; +@use "igniteui-angular/theming" as *; + +.button-container { + display: flex; + justify-content: center; + align-items: center; + gap: 2rem; + padding: 1rem; +} + +.button-item { + display: flex; + flex-direction: column; + align-items: center; + gap: 0.75rem; + --hover-background: var(--ig-contained-button-hover-background); + --hover-foreground: var(--ig-contained-button-hover-foreground); + --focus-background: var(--ig-contained-button-focus-background); + --focus-foreground: var(--ig-contained-button-focus-foreground); + --focus-hover-background: var(--ig-contained-button-focus-hover-background); + --focus-hover-foreground: var(--ig-contained-button-focus-hover-foreground); +} + +.button-label { + color: var(--ig-gray-600); + font-family: "Aktiv Grotesk", sans-serif; + font-size: 13px; + font-weight: 400; + font-style: normal; + line-height: 20px; + letter-spacing: 0.3px; +} + +.button-item button.state-hover { + background: var(--hover-background); + color: var(--hover-foreground); +} + +.button-item button.state-focused { + background: var(--focus-background); + color: var(--focus-foreground); +} + +.button-item button.state-focused-hover { + background: var(--focus-hover-background); + color: var(--focus-hover-foreground); +} diff --git a/src/app/data-entries/button/button-interaction-states/button-interaction-states.component.ts b/src/app/data-entries/button/button-interaction-states/button-interaction-states.component.ts new file mode 100644 index 0000000000..0e2ddee7da --- /dev/null +++ b/src/app/data-entries/button/button-interaction-states/button-interaction-states.component.ts @@ -0,0 +1,18 @@ +import { Component } from '@angular/core'; +import { IgxButtonDirective } from 'igniteui-angular/directives'; +import { IgxIconComponent } from 'igniteui-angular/icon'; + +@Component({ + selector: 'app-button-interaction-states', + styleUrls: ['./button-interaction-states.component.scss'], + templateUrl: './button-interaction-states.component.html', + imports: [IgxButtonDirective, IgxIconComponent] +}) +export class ButtonInteractionStatesComponent { + public states = [ + { label: 'Idle', value: 'idle' }, + { label: 'Hover', value: 'state-hover' }, + { label: 'Focused', value: 'state-focused' }, + { label: 'Focused & Hover', value: 'state-focused-hover' } + ]; +} diff --git a/src/app/data-entries/button/button-layout/button-layout.component.html b/src/app/data-entries/button/button-layout/button-layout.component.html new file mode 100644 index 0000000000..ac8ca6e9f2 --- /dev/null +++ b/src/app/data-entries/button/button-layout/button-layout.component.html @@ -0,0 +1,8 @@ +
+
+
+
+
+
+
+
diff --git a/src/app/data-entries/button/button-layout/button-layout.component.scss b/src/app/data-entries/button/button-layout/button-layout.component.scss new file mode 100644 index 0000000000..770c65f296 --- /dev/null +++ b/src/app/data-entries/button/button-layout/button-layout.component.scss @@ -0,0 +1,26 @@ +@use '../_bootstrap-button-theme'; + +.button-container { + display: flex; + align-items: center; + justify-content: center; + gap: 1rem; + width: 100%; + box-sizing: border-box; + padding: 2.5rem; +} + +.button-item { + display: flex; + flex-direction: column; + align-items: center; + gap: 0.75rem; +} + +.button-container button { + --ig-font-family: 'Titillium Web', sans-serif; + --ig-button-text-transform: uppercase; + + font-size: 0.85rem; + letter-spacing: 1px; +} diff --git a/src/app/data-entries/button/button-layout/button-layout.component.ts b/src/app/data-entries/button/button-layout/button-layout.component.ts new file mode 100644 index 0000000000..f7c82fea63 --- /dev/null +++ b/src/app/data-entries/button/button-layout/button-layout.component.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core'; +import { IgxButtonDirective } from 'igniteui-angular/directives'; +import { IgxIconComponent } from 'igniteui-angular/icon'; + +@Component({ + selector: 'app-button-layout', + styleUrls: ['./button-layout.component.scss'], + templateUrl: './button-layout.component.html', + imports: [IgxButtonDirective, IgxIconComponent] +}) +export class ButtonLayoutComponent { +} diff --git a/src/app/data-entries/button/button-outlined/button-outlined.component.html b/src/app/data-entries/button/button-outlined/button-outlined.component.html new file mode 100644 index 0000000000..b5f35da49f --- /dev/null +++ b/src/app/data-entries/button/button-outlined/button-outlined.component.html @@ -0,0 +1,7 @@ +
+ +
diff --git a/src/app/data-entries/button/button-outlined/button-outlined.component.scss b/src/app/data-entries/button/button-outlined/button-outlined.component.scss new file mode 100644 index 0000000000..2bfc8c5087 --- /dev/null +++ b/src/app/data-entries/button/button-outlined/button-outlined.component.scss @@ -0,0 +1,11 @@ +@use '../_bootstrap-button-theme'; + +.button-sample { + display: flex; + padding: 2.5rem; +} + +.button-sample button { + width: 46%; + margin: auto; +} diff --git a/src/app/data-entries/button/button-outlined/button-outlined.component.ts b/src/app/data-entries/button/button-outlined/button-outlined.component.ts new file mode 100644 index 0000000000..41cff29372 --- /dev/null +++ b/src/app/data-entries/button/button-outlined/button-outlined.component.ts @@ -0,0 +1,11 @@ +import { Component } from '@angular/core'; +import { IgxButtonDirective } from 'igniteui-angular/directives'; +import { IgxIconComponent } from 'igniteui-angular/icon'; + +@Component({ + selector: 'app-button-outlined', + styleUrls: ['./button-outlined.component.scss'], + templateUrl: './button-outlined.component.html', + imports: [IgxButtonDirective, IgxIconComponent] +}) +export class ButtonOutlinedComponent { } diff --git a/src/app/data-entries/button/button-overview/button-overview.component.html b/src/app/data-entries/button/button-overview/button-overview.component.html new file mode 100644 index 0000000000..b4963b3145 --- /dev/null +++ b/src/app/data-entries/button/button-overview/button-overview.component.html @@ -0,0 +1,15 @@ +
+ +
+ + + + + + +
+ + +
+
+
diff --git a/src/app/data-entries/button/button-overview/button-overview.component.scss b/src/app/data-entries/button/button-overview/button-overview.component.scss new file mode 100644 index 0000000000..e464378d47 --- /dev/null +++ b/src/app/data-entries/button/button-overview/button-overview.component.scss @@ -0,0 +1,39 @@ +@use '../_bootstrap-button-theme'; + +.form { + display: flex; + justify-content: center; + gap: 1.25rem; + padding: 2.5rem; +} + +.form igx-avatar { + --ig-size: var(--ig-size-large); +} + +.fields { + display: flex; + flex-direction: column; + gap: 1rem; + max-width: 260px; + width: 100%; +} + +:host ::ng-deep .fields .igx-input-group__bundle { + background-color: var(--ig-gray-50); +} + +:host ::ng-deep .fields igx-input-group, +:host ::ng-deep .fields igx-input-group .igx-input-group__input { + --ig-size: var(--ig-size-medium); +} + +:host ::ng-deep .fields .igx-input-group__input { + margin: 0; +} +.actions { + display: flex; + justify-content: flex-end; + gap: 1rem; + margin-top: 0.5rem; +} diff --git a/src/app/data-entries/button/button-overview/button-overview.component.ts b/src/app/data-entries/button/button-overview/button-overview.component.ts new file mode 100644 index 0000000000..48c8c8b098 --- /dev/null +++ b/src/app/data-entries/button/button-overview/button-overview.component.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core'; +import { IgxAvatarComponent } from 'igniteui-angular/avatar'; +import { IgxButtonDirective } from 'igniteui-angular/directives'; +import { IgxInputDirective, IgxInputGroupComponent } from 'igniteui-angular/input-group'; + +@Component({ + selector: 'app-button-overview', + styleUrls: ['./button-overview.component.scss'], + templateUrl: './button-overview.component.html', + imports: [IgxAvatarComponent, IgxButtonDirective, IgxInputGroupComponent, IgxInputDirective] +}) +export class ButtonOverviewComponent { } diff --git a/src/app/data-entries/button/button-size/button-size.component.html b/src/app/data-entries/button/button-size/button-size.component.html new file mode 100644 index 0000000000..9f0156c2ed --- /dev/null +++ b/src/app/data-entries/button/button-size/button-size.component.html @@ -0,0 +1,20 @@ +
+
ContainedOutlinedFlatFab
+ @for (size of sizes; track size) { +
+ {{ size | titlecase }} + @for (variant of variants; track variant) { + + } + +
+ } +
diff --git a/src/app/data-entries/button/button-size/button-size.component.scss b/src/app/data-entries/button/button-size/button-size.component.scss new file mode 100644 index 0000000000..2b0a6afd17 --- /dev/null +++ b/src/app/data-entries/button/button-size/button-size.component.scss @@ -0,0 +1,63 @@ +@use '../_bootstrap-button-theme'; + +:host { + display: flex; + justify-content: center; + align-items: center; +} + +.size-grid { + display: flex; + flex-direction: column; + gap: 1.25rem; + padding: 1rem; + width: 100%; + box-sizing: border-box; + overflow: hidden; +} + +.size-row { + display: grid; + grid-template-columns: 70px repeat(4, minmax(0, 1fr)); + align-items: center; + justify-items: center; + column-gap: 1rem; + row-gap: 0.5rem; + width: 100%; +} + +.size-header { + display: grid; + grid-template-columns: 70px repeat(4, minmax(0, 1fr)); + align-items: center; + justify-items: center; + column-gap: 1rem; + width: 100%; + color: var(--ig-gray-600); + font: 13px/20px "Aktiv Grotesk", sans-serif; + letter-spacing: .3px; +} + +.size-label { + justify-self: start; + color: var(--ig-gray-600); + font: 400 13px/20px "Aktiv Grotesk", sans-serif; + letter-spacing: .3px; +} + +.size-row button { + width: auto; + transform: scale(.9); +} + +.size-small { + --ig-size: var(--ig-size-small) !important; +} + +.size-medium { + --ig-size: var(--ig-size-medium) !important; +} + +.size-large { + --ig-size: var(--ig-size-large) !important; +} diff --git a/src/app/data-entries/button/button-size/button-size.component.ts b/src/app/data-entries/button/button-size/button-size.component.ts new file mode 100644 index 0000000000..916c5da122 --- /dev/null +++ b/src/app/data-entries/button/button-size/button-size.component.ts @@ -0,0 +1,15 @@ +import { Component } from '@angular/core'; +import { TitleCasePipe } from '@angular/common'; +import { IgxButtonDirective } from 'igniteui-angular/directives'; +import { IgxIconComponent } from 'igniteui-angular/icon'; + +@Component({ + selector: 'app-button-size', + styleUrls: ['./button-size.component.scss'], + templateUrl: './button-size.component.html', + imports: [IgxButtonDirective, IgxIconComponent, TitleCasePipe] +}) +export class ButtonSizeComponent { + public sizes = ['large', 'medium', 'small']; + public variants = ['contained', 'outlined', 'flat']; +} diff --git a/src/app/data-entries/button/button-states/button-states.component.html b/src/app/data-entries/button/button-states/button-states.component.html new file mode 100644 index 0000000000..cd4424548e --- /dev/null +++ b/src/app/data-entries/button/button-states/button-states.component.html @@ -0,0 +1,30 @@ +
+
+ +
+
+ +
+
+ +
+
+ +
+
diff --git a/src/app/data-entries/button/button-states/button-states.component.scss b/src/app/data-entries/button/button-states/button-states.component.scss new file mode 100644 index 0000000000..ac098876d8 --- /dev/null +++ b/src/app/data-entries/button/button-states/button-states.component.scss @@ -0,0 +1,16 @@ +@use '../_bootstrap-button-theme'; + +.button-container { + display: flex; + justify-content: center; + align-items: center; + gap: 2rem; + padding: 2rem; +} + +.button-item { + display: flex; + flex-direction: column; + align-items: center; + gap: 1.5rem; +} diff --git a/src/app/data-entries/button/button-states/button-states.component.ts b/src/app/data-entries/button/button-states/button-states.component.ts new file mode 100644 index 0000000000..398a2c54d5 --- /dev/null +++ b/src/app/data-entries/button/button-states/button-states.component.ts @@ -0,0 +1,11 @@ +import { Component } from '@angular/core'; +import { IgxButtonDirective } from 'igniteui-angular/directives'; +import { IgxIconComponent } from 'igniteui-angular/icon'; + +@Component({ + selector: 'app-button-states', + styleUrls: ['./button-states.component.scss'], + templateUrl: './button-states.component.html', + imports: [IgxButtonDirective, IgxIconComponent] +}) +export class ButtonStatesComponent { } diff --git a/src/app/data-entries/button/button-styling/button-styling.component.html b/src/app/data-entries/button/button-styling/button-styling.component.html new file mode 100644 index 0000000000..6954e7df30 --- /dev/null +++ b/src/app/data-entries/button/button-styling/button-styling.component.html @@ -0,0 +1,14 @@ +
+
+ + + + +
+
diff --git a/src/app/data-entries/button/button-styling/button-styling.component.scss b/src/app/data-entries/button/button-styling/button-styling.component.scss new file mode 100644 index 0000000000..4637a2ccee --- /dev/null +++ b/src/app/data-entries/button/button-styling/button-styling.component.scss @@ -0,0 +1,39 @@ +@use "layout.scss"; + +// CSS variables approach + +.confirm-button { + --background: #1275c4; + --foreground: #fff; + --hover-background: #1275c4; + --hover-foreground: #fff; + &:hover { --hover-background: #0b4f8a; } +} + +.send-button { + --background: transparent; + --border-color: #8a2be2; + --foreground: #8a2be2; + --hover-border-color: #8a2be2; + --hover-foreground: #8a2be2; + --icon-color: #8a2be2; + --icon-color-hover: #8a2be2; + &:hover { --hover-background: #8a2be2; --hover-border-color: #6a1bb1; --hover-foreground: #fff; --icon-color-hover: #fff; } +} + +.cancel-button { + --foreground: #1275c4; + --hover-foreground: #1275c4; + &:hover { --hover-background: #dbeeff; --hover-foreground: #063b68; } +} + +.add-button { + --background: #4caf50; + --foreground: #000; + --hover-background: #4caf50; + --hover-foreground: #000; + --icon-color: #000; + --icon-color-hover: #000; + --border-radius: 999px; + &:hover { --hover-background: #257a2b; --hover-foreground: #fff; --icon-color-hover: #fff; } +} diff --git a/src/app/data-entries/button/button-styling/button-styling.component.ts b/src/app/data-entries/button/button-styling/button-styling.component.ts new file mode 100644 index 0000000000..eb66365452 --- /dev/null +++ b/src/app/data-entries/button/button-styling/button-styling.component.ts @@ -0,0 +1,12 @@ +import { Component, ViewEncapsulation } from '@angular/core'; +import { IgxButtonDirective } from 'igniteui-angular/directives'; +import { IgxIconComponent } from 'igniteui-angular/icon'; + +@Component({ + selector: 'app-button-styling', + encapsulation: ViewEncapsulation.None, + styleUrls: ['./button-styling.component.scss'], + templateUrl: './button-styling.component.html', + imports: [IgxButtonDirective, IgxIconComponent] +}) +export class ButtonStylingComponent { } diff --git a/src/app/data-entries/button/button-styling/layout.scss b/src/app/data-entries/button/button-styling/layout.scss new file mode 100644 index 0000000000..a77566283c --- /dev/null +++ b/src/app/data-entries/button/button-styling/layout.scss @@ -0,0 +1,41 @@ +@use "igniteui-angular/theming" as *; +@use "igniteui-angular/lib/core/styles/components/button/button-component" as button; +@use "igniteui-angular/lib/core/styles/themes/presets/igniteui-bootstrap-light"; + +.bootstrap-theme { + ::ng-deep { + @include button( + $flat: flat-button-theme($schema: $light-bootstrap-schema), + $contained: contained-button-theme($schema: $light-bootstrap-schema), + $outlined: outlined-button-theme($schema: $light-bootstrap-schema), + $fab: fab-button-theme($schema: $light-bootstrap-schema) + ); + @include button.component(); + } +} + +.button-row button.confirm-button, +.button-row button.send-button, +.button-row button.cancel-button { + height: 40px; + min-height: 40px; + width: 90%; +} + +.button-grid { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 100%; + gap: 1.5rem; + padding: 1rem; +} + +.button-row { + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + align-items: center; + justify-items: center; + gap: 3rem; +} diff --git a/src/app/data-entries/button/button-tailwind-styling/button-tailwind-styling.component.html b/src/app/data-entries/button/button-tailwind-styling/button-tailwind-styling.component.html new file mode 100644 index 0000000000..0a6427ed84 --- /dev/null +++ b/src/app/data-entries/button/button-tailwind-styling/button-tailwind-styling.component.html @@ -0,0 +1,14 @@ +
+
+ + + + +
+
diff --git a/src/app/data-entries/button/button-tailwind-styling/button-tailwind-styling.component.scss b/src/app/data-entries/button/button-tailwind-styling/button-tailwind-styling.component.scss new file mode 100644 index 0000000000..f0ca253bc3 --- /dev/null +++ b/src/app/data-entries/button/button-tailwind-styling/button-tailwind-styling.component.scss @@ -0,0 +1,6 @@ +@use "layout.scss"; + +.confirm-button { --hover-background: #3730a3; --hover-foreground: #fff; } +.send-button { --hover-background: #db2777; --hover-border-color: #be185d; --hover-foreground: #fff; --icon-color-hover: #fff; } +.cancel-button { --hover-background: #fef3c7; --hover-foreground: #78350f; } +.add-button { --hover-background: #0f766e; --hover-foreground: #fff; --icon-color-hover: #fff; } diff --git a/src/app/data-entries/button/button-tailwind-styling/button-tailwind-styling.component.ts b/src/app/data-entries/button/button-tailwind-styling/button-tailwind-styling.component.ts new file mode 100644 index 0000000000..70ea8e811c --- /dev/null +++ b/src/app/data-entries/button/button-tailwind-styling/button-tailwind-styling.component.ts @@ -0,0 +1,12 @@ +import { Component, ViewEncapsulation } from '@angular/core'; +import { IgxButtonDirective } from 'igniteui-angular/directives'; +import { IgxIconComponent } from 'igniteui-angular/icon'; + +@Component({ + selector: 'app-button-tailwind-styling', + encapsulation: ViewEncapsulation.None, + styleUrls: ['./button-tailwind-styling.component.scss'], + templateUrl: './button-tailwind-styling.component.html', + imports: [IgxButtonDirective, IgxIconComponent] +}) +export class ButtonTailwindStylingComponent { } diff --git a/src/app/data-entries/button/button-tailwind-styling/layout.scss b/src/app/data-entries/button/button-tailwind-styling/layout.scss new file mode 100644 index 0000000000..df3c97ac6d --- /dev/null +++ b/src/app/data-entries/button/button-tailwind-styling/layout.scss @@ -0,0 +1,56 @@ +@use "igniteui-angular/theming" as *; +@use "igniteui-angular/lib/core/styles/components/button/button-component" as button; +@use "igniteui-angular/lib/core/styles/themes/presets/igniteui-bootstrap-light"; + +:host { + ::ng-deep { + @include button( + $flat: flat-button-theme($schema: $light-bootstrap-schema), + $contained: contained-button-theme($schema: $light-bootstrap-schema), + $outlined: outlined-button-theme($schema: $light-bootstrap-schema), + $fab: fab-button-theme($schema: $light-bootstrap-schema) + ); + @include button.component(); + } +} + +.button-row button.confirm-button, +.button-row button.send-button, +.button-row button.cancel-button { + height: 40px; + min-height: 40px; + width: 90%; +} + +.confirm-button { + --background: #4338ca; + --foreground: #fff; + --hover-background: #4338ca; + --hover-foreground: #fff; +} + +.send-button { + --background: transparent; + --border-color: #db2777; + --foreground: #db2777; + --hover-border-color: #db2777; + --hover-foreground: #db2777; + --icon-color: #db2777; + --icon-color-hover: #db2777; +} + +.cancel-button { + --foreground: #b45309; + --hover-foreground: #b45309; +} + +.add-button { + --background: #14b8a6; + --foreground: #000; + --hover-background: #14b8a6; + --hover-foreground: #000; + --icon-color: #fff; + --icon-color-hover: #fff; + --border-radius: 9999px; + background-color: #14b8a6; +} diff --git a/src/app/data-entries/buttons/buttons-disabled-sample/buttons-disabled-sample.html b/src/app/data-entries/buttons/buttons-disabled-sample/buttons-disabled-sample.html deleted file mode 100644 index 34d38c8158..0000000000 --- a/src/app/data-entries/buttons/buttons-disabled-sample/buttons-disabled-sample.html +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/app/data-entries/buttons/buttons-disabled-sample/buttons-disabled-sample.scss b/src/app/data-entries/buttons/buttons-disabled-sample/buttons-disabled-sample.scss deleted file mode 100644 index 932b31c68c..0000000000 --- a/src/app/data-entries/buttons/buttons-disabled-sample/buttons-disabled-sample.scss +++ /dev/null @@ -1,3 +0,0 @@ -.btn { - margin: 8px; -} diff --git a/src/app/data-entries/buttons/buttons-disabled-sample/buttons-disabled-sample.ts b/src/app/data-entries/buttons/buttons-disabled-sample/buttons-disabled-sample.ts deleted file mode 100644 index c3542a0796..0000000000 --- a/src/app/data-entries/buttons/buttons-disabled-sample/buttons-disabled-sample.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Component } from '@angular/core'; -import { IgxButtonDirective } from 'igniteui-angular/directives'; - -@Component({ - selector: 'app-buttons-disabled-sample', - styleUrls: ['./buttons-disabled-sample.scss'], - templateUrl: './buttons-disabled-sample.html', - imports: [IgxButtonDirective] -}) -export class ButtonsDisabledComponent { } diff --git a/src/app/data-entries/buttons/buttons-display-density/buttons-display-density.component.html b/src/app/data-entries/buttons/buttons-display-density/buttons-display-density.component.html deleted file mode 100644 index 853533d488..0000000000 --- a/src/app/data-entries/buttons/buttons-display-density/buttons-display-density.component.html +++ /dev/null @@ -1,27 +0,0 @@ -
-
- -
-
-
- -
-
- -
-
- -
-
- -
-
- -
-
-
diff --git a/src/app/data-entries/buttons/buttons-display-density/buttons-display-density.component.scss b/src/app/data-entries/buttons/buttons-display-density/buttons-display-density.component.scss deleted file mode 100644 index 38b1bb22b2..0000000000 --- a/src/app/data-entries/buttons/buttons-display-density/buttons-display-density.component.scss +++ /dev/null @@ -1,15 +0,0 @@ -.buttons-sample { - display: flex; - flex-flow: row wrap; -} - -.button-sample { - display: flex; - flex: 1 0 20%; - align-items: center; - justify-content: space-evenly; -} - -.density-chooser { - margin-bottom: 24px; -} diff --git a/src/app/data-entries/buttons/buttons-display-density/buttons-display-density.component.ts b/src/app/data-entries/buttons/buttons-display-density/buttons-display-density.component.ts deleted file mode 100644 index 841a908270..0000000000 --- a/src/app/data-entries/buttons/buttons-display-density/buttons-display-density.component.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Component, HostBinding, OnInit } from '@angular/core'; -import { IgxButtonGroupComponent } from 'igniteui-angular/button-group'; -import { IgxButtonDirective, IgxRippleDirective } from 'igniteui-angular/directives'; -import { IgxIconComponent } from 'igniteui-angular/icon'; - -@Component({ - selector: 'app-buttons-display-density', - styleUrls: ['./buttons-display-density.component.scss'], - templateUrl: './buttons-display-density.component.html', - imports: [IgxButtonGroupComponent, IgxButtonDirective, IgxRippleDirective, IgxIconComponent] -}) -export class ButtonsDisplayDensityComponent implements OnInit { - public size = 'large'; - public sizes; - - public ngOnInit(): void { - this.sizes = [ - { label: 'large', selected: this.size === 'large', togglable: true }, - { label: 'medium', selected: this.size === 'medium', togglable: true }, - { label: 'small', selected: this.size === 'small', togglable: true } - ]; - } - - @HostBinding('style.--ig-size') - protected get sizeStyle() { - return `var(--ig-size-${this.size})`; - } - - public selectSize(event) { - this.size = this.sizes[event.index].label; - } -} diff --git a/src/app/data-entries/buttons/buttons-roundness-sample/buttons-roundness-sample.html b/src/app/data-entries/buttons/buttons-roundness-sample/buttons-roundness-sample.html deleted file mode 100644 index 0c93305128..0000000000 --- a/src/app/data-entries/buttons/buttons-roundness-sample/buttons-roundness-sample.html +++ /dev/null @@ -1,22 +0,0 @@ -
-
-
-
- -
-
- -
-
- -
-
- -
-
-
-
diff --git a/src/app/data-entries/buttons/buttons-roundness-sample/buttons-roundness-sample.scss b/src/app/data-entries/buttons/buttons-roundness-sample/buttons-roundness-sample.scss deleted file mode 100644 index 81efc9eb5e..0000000000 --- a/src/app/data-entries/buttons/buttons-roundness-sample/buttons-roundness-sample.scss +++ /dev/null @@ -1,44 +0,0 @@ -@use '../../../../variables' as *; - -$flatBtn: flat-button-theme( - $border-radius: .5 -); - -$containedBtn: contained-button-theme( - $border-radius: 30px -); - -$fabBtn: fab-button-theme( - $border-radius: 10% -); - -$iconBtn: flat-icon-button-theme( - $border-radius: 12px -); - -.flat { - @include tokens($flatBtn); -} - -.contained { - @include tokens($containedBtn); -} - -.fab { - @include tokens($fabBtn); -} - -.icon { - @include tokens($iconBtn); -} - -.buttons-sample { - display: flex; -} - -.buttons-sample_item { - display: flex; - align-items: center; - justify-content: center; - flex: 1; -} diff --git a/src/app/data-entries/buttons/buttons-roundness-sample/buttons-roundness-sample.ts b/src/app/data-entries/buttons/buttons-roundness-sample/buttons-roundness-sample.ts deleted file mode 100644 index c791699b35..0000000000 --- a/src/app/data-entries/buttons/buttons-roundness-sample/buttons-roundness-sample.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Component } from '@angular/core'; -import { IgxButtonDirective, IgxIconButtonDirective, IgxRippleDirective } from 'igniteui-angular/directives'; -import { IgxIconComponent } from 'igniteui-angular/icon'; - -@Component({ - selector: 'app-buttons-roundness-sample', - styleUrls: ['./buttons-roundness-sample.scss'], - templateUrl: './buttons-roundness-sample.html', - imports: [IgxButtonDirective, IgxRippleDirective, IgxIconComponent, IgxIconButtonDirective] -}) -export class ButtonsRoundnessComponent {} diff --git a/src/app/data-entries/buttons/buttons-sample-1/buttons-sample-1.component.html b/src/app/data-entries/buttons/buttons-sample-1/buttons-sample-1.component.html deleted file mode 100644 index 2a08fc960d..0000000000 --- a/src/app/data-entries/buttons/buttons-sample-1/buttons-sample-1.component.html +++ /dev/null @@ -1,11 +0,0 @@ -
-
- -
-
- -
-
- -
-
diff --git a/src/app/data-entries/buttons/buttons-sample-1/buttons-sample-1.component.scss b/src/app/data-entries/buttons/buttons-sample-1/buttons-sample-1.component.scss deleted file mode 100644 index 9d1157d397..0000000000 --- a/src/app/data-entries/buttons/buttons-sample-1/buttons-sample-1.component.scss +++ /dev/null @@ -1,13 +0,0 @@ -.wrapper { - display: flex; - flex-flow: row wrap; -} - -.button-sample { - display: flex; - flex-flow: row wrap; - justify-content: center; - align-items: center; - flex: 1 0 30%; - margin: 16px 0; -} diff --git a/src/app/data-entries/buttons/buttons-sample-1/buttons-sample-1.component.ts b/src/app/data-entries/buttons/buttons-sample-1/buttons-sample-1.component.ts deleted file mode 100644 index 6e81376588..0000000000 --- a/src/app/data-entries/buttons/buttons-sample-1/buttons-sample-1.component.ts +++ /dev/null @@ -1,11 +0,0 @@ - -import { Component, OnInit } from '@angular/core'; -import { IgxButtonDirective, IgxRippleDirective } from 'igniteui-angular/directives'; - -@Component({ - selector: 'app-buttons-sample-1', - styleUrls: ['./buttons-sample-1.component.scss'], - templateUrl: './buttons-sample-1.component.html', - imports: [IgxButtonDirective, IgxRippleDirective] -}) -export class ButtonsSample1Component { } diff --git a/src/app/data-entries/buttons/buttons-sample-2/buttons-sample-2.component.html b/src/app/data-entries/buttons/buttons-sample-2/buttons-sample-2.component.html deleted file mode 100644 index a0a5a22826..0000000000 --- a/src/app/data-entries/buttons/buttons-sample-2/buttons-sample-2.component.html +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/app/data-entries/buttons/buttons-sample-2/buttons-sample-2.component.scss b/src/app/data-entries/buttons/buttons-sample-2/buttons-sample-2.component.scss deleted file mode 100644 index 932b31c68c..0000000000 --- a/src/app/data-entries/buttons/buttons-sample-2/buttons-sample-2.component.scss +++ /dev/null @@ -1,3 +0,0 @@ -.btn { - margin: 8px; -} diff --git a/src/app/data-entries/buttons/buttons-sample-2/buttons-sample-2.component.ts b/src/app/data-entries/buttons/buttons-sample-2/buttons-sample-2.component.ts deleted file mode 100644 index 048e47f634..0000000000 --- a/src/app/data-entries/buttons/buttons-sample-2/buttons-sample-2.component.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Component } from '@angular/core'; -import { IgxButtonDirective } from 'igniteui-angular/directives'; - -@Component({ - selector: 'app-buttons-sample-2', - styleUrls: ['./buttons-sample-2.component.scss'], - templateUrl: './buttons-sample-2.component.html', - imports: [IgxButtonDirective] -}) -export class ButtonsSample2Component { } diff --git a/src/app/data-entries/buttons/buttons-sample-3/buttons-sample-3.component.html b/src/app/data-entries/buttons/buttons-sample-3/buttons-sample-3.component.html deleted file mode 100644 index dbd51e8aa4..0000000000 --- a/src/app/data-entries/buttons/buttons-sample-3/buttons-sample-3.component.html +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/app/data-entries/buttons/buttons-sample-3/buttons-sample-3.component.scss b/src/app/data-entries/buttons/buttons-sample-3/buttons-sample-3.component.scss deleted file mode 100644 index 932b31c68c..0000000000 --- a/src/app/data-entries/buttons/buttons-sample-3/buttons-sample-3.component.scss +++ /dev/null @@ -1,3 +0,0 @@ -.btn { - margin: 8px; -} diff --git a/src/app/data-entries/buttons/buttons-sample-3/buttons-sample-3.component.ts b/src/app/data-entries/buttons/buttons-sample-3/buttons-sample-3.component.ts deleted file mode 100644 index 95c52d74d6..0000000000 --- a/src/app/data-entries/buttons/buttons-sample-3/buttons-sample-3.component.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Component } from '@angular/core'; -import { IgxButtonDirective, IgxRippleDirective } from 'igniteui-angular/directives'; - -@Component({ - selector: 'app-buttons-sample-3', - styleUrls: ['./buttons-sample-3.component.scss'], - templateUrl: './buttons-sample-3.component.html', - imports: [IgxButtonDirective, IgxRippleDirective] -}) -export class ButtonsSample3Component { } diff --git a/src/app/data-entries/buttons/buttons-sample-4/buttons-sample-4.component.html b/src/app/data-entries/buttons/buttons-sample-4/buttons-sample-4.component.html deleted file mode 100644 index ea82ea38fe..0000000000 --- a/src/app/data-entries/buttons/buttons-sample-4/buttons-sample-4.component.html +++ /dev/null @@ -1 +0,0 @@ -Span diff --git a/src/app/data-entries/buttons/buttons-sample-4/buttons-sample-4.component.scss b/src/app/data-entries/buttons/buttons-sample-4/buttons-sample-4.component.scss deleted file mode 100644 index 932b31c68c..0000000000 --- a/src/app/data-entries/buttons/buttons-sample-4/buttons-sample-4.component.scss +++ /dev/null @@ -1,3 +0,0 @@ -.btn { - margin: 8px; -} diff --git a/src/app/data-entries/buttons/buttons-sample-4/buttons-sample-4.component.ts b/src/app/data-entries/buttons/buttons-sample-4/buttons-sample-4.component.ts deleted file mode 100644 index e0aa368980..0000000000 --- a/src/app/data-entries/buttons/buttons-sample-4/buttons-sample-4.component.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Component } from '@angular/core'; -import { IgxButtonDirective, IgxRippleDirective } from 'igniteui-angular/directives'; - -@Component({ - selector: 'app-buttons-sample-4', - styleUrls: ['./buttons-sample-4.component.scss'], - templateUrl: './buttons-sample-4.component.html', - imports: [IgxButtonDirective, IgxRippleDirective] -}) -export class ButtonsSample4Component { } diff --git a/src/app/data-entries/buttons/buttons-sample-5/buttons-sample-5.component.html b/src/app/data-entries/buttons/buttons-sample-5/buttons-sample-5.component.html deleted file mode 100644 index a05ed23958..0000000000 --- a/src/app/data-entries/buttons/buttons-sample-5/buttons-sample-5.component.html +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/app/data-entries/buttons/buttons-sample-5/buttons-sample-5.component.scss b/src/app/data-entries/buttons/buttons-sample-5/buttons-sample-5.component.scss deleted file mode 100644 index 932b31c68c..0000000000 --- a/src/app/data-entries/buttons/buttons-sample-5/buttons-sample-5.component.scss +++ /dev/null @@ -1,3 +0,0 @@ -.btn { - margin: 8px; -} diff --git a/src/app/data-entries/buttons/buttons-sample-5/buttons-sample-5.component.ts b/src/app/data-entries/buttons/buttons-sample-5/buttons-sample-5.component.ts deleted file mode 100644 index ea471e6e36..0000000000 --- a/src/app/data-entries/buttons/buttons-sample-5/buttons-sample-5.component.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Component } from '@angular/core'; -import { IgxButtonDirective } from 'igniteui-angular/directives'; - -@Component({ - selector: 'app-buttons-sample-5', - styleUrls: ['./buttons-sample-5.component.scss'], - templateUrl: './buttons-sample-5.component.html', - imports: [IgxButtonDirective] -}) -export class ButtonsSample5Component { } diff --git a/src/app/data-entries/buttons/buttons-sample-6/buttons-sample-6.component.html b/src/app/data-entries/buttons/buttons-sample-6/buttons-sample-6.component.html deleted file mode 100644 index 8c8f119053..0000000000 --- a/src/app/data-entries/buttons/buttons-sample-6/buttons-sample-6.component.html +++ /dev/null @@ -1,8 +0,0 @@ - - - diff --git a/src/app/data-entries/buttons/buttons-sample-6/buttons-sample-6.component.scss b/src/app/data-entries/buttons/buttons-sample-6/buttons-sample-6.component.scss deleted file mode 100644 index 03448c1a67..0000000000 --- a/src/app/data-entries/buttons/buttons-sample-6/buttons-sample-6.component.scss +++ /dev/null @@ -1,3 +0,0 @@ -.btn { - margin: 1rem; -} diff --git a/src/app/data-entries/buttons/buttons-sample-7/buttons-sample-7.component.html b/src/app/data-entries/buttons/buttons-sample-7/buttons-sample-7.component.html deleted file mode 100644 index 39863f9e05..0000000000 --- a/src/app/data-entries/buttons/buttons-sample-7/buttons-sample-7.component.html +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/src/app/data-entries/buttons/buttons-sample-7/buttons-sample-7.component.scss b/src/app/data-entries/buttons/buttons-sample-7/buttons-sample-7.component.scss deleted file mode 100644 index 932b31c68c..0000000000 --- a/src/app/data-entries/buttons/buttons-sample-7/buttons-sample-7.component.scss +++ /dev/null @@ -1,3 +0,0 @@ -.btn { - margin: 8px; -} diff --git a/src/app/data-entries/buttons/buttons-sample-7/buttons-sample-7.component.ts b/src/app/data-entries/buttons/buttons-sample-7/buttons-sample-7.component.ts deleted file mode 100644 index 532edeff95..0000000000 --- a/src/app/data-entries/buttons/buttons-sample-7/buttons-sample-7.component.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Component } from '@angular/core'; -import { IgxIconButtonDirective } from 'igniteui-angular/directives'; -import { IgxIconComponent } from 'igniteui-angular/icon'; - -@Component({ - selector: 'app-buttons-sample-7', - styleUrls: ['./buttons-sample-7.component.scss'], - templateUrl: './buttons-sample-7.component.html', - imports: [IgxIconButtonDirective, IgxIconComponent] -}) -export class ButtonsSample7Component { } diff --git a/src/app/data-entries/buttons/buttons-sample-8/buttons-sample-8.component.html b/src/app/data-entries/buttons/buttons-sample-8/buttons-sample-8.component.html deleted file mode 100644 index ec9a161264..0000000000 --- a/src/app/data-entries/buttons/buttons-sample-8/buttons-sample-8.component.html +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/app/data-entries/buttons/buttons-sample-8/buttons-sample-8.component.scss b/src/app/data-entries/buttons/buttons-sample-8/buttons-sample-8.component.scss deleted file mode 100644 index 932b31c68c..0000000000 --- a/src/app/data-entries/buttons/buttons-sample-8/buttons-sample-8.component.scss +++ /dev/null @@ -1,3 +0,0 @@ -.btn { - margin: 8px; -} diff --git a/src/app/data-entries/buttons/buttons-sample-8/buttons-sample-8.component.ts b/src/app/data-entries/buttons/buttons-sample-8/buttons-sample-8.component.ts deleted file mode 100644 index 77b080c3a4..0000000000 --- a/src/app/data-entries/buttons/buttons-sample-8/buttons-sample-8.component.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Component } from '@angular/core'; -import { IgxButtonDirective } from 'igniteui-angular/directives'; - -@Component({ - selector: 'app-buttons-sample-8', - styleUrls: ['./buttons-sample-8.component.scss'], - templateUrl: './buttons-sample-8.component.html', - imports: [IgxButtonDirective] -}) -export class ButtonsSample8Component { } diff --git a/src/app/data-entries/buttons/buttons-style/buttons-style.component.html b/src/app/data-entries/buttons/buttons-style/buttons-style.component.html deleted file mode 100644 index 8eee79e1d3..0000000000 --- a/src/app/data-entries/buttons/buttons-style/buttons-style.component.html +++ /dev/null @@ -1,22 +0,0 @@ -@for (item of range; let i = $index; track i) { -
-
- -
-
- -
-
- -
-
- -
-
- -
- -
-} \ No newline at end of file diff --git a/src/app/data-entries/buttons/buttons-style/buttons-style.component.scss b/src/app/data-entries/buttons/buttons-style/buttons-style.component.scss deleted file mode 100644 index 67df53853d..0000000000 --- a/src/app/data-entries/buttons/buttons-style/buttons-style.component.scss +++ /dev/null @@ -1,241 +0,0 @@ -@use "layout.scss"; -@use "igniteui-angular/theming" as *; -@use "sass:map"; - -// CSS variables approach - -$list: ( - "sample-1": ( - "primary": #000, - "secondary": rgba(0, 0, 0, 0.75), - "active": rgba(0, 0, 0, 0.95), - "focus": #fff, - "hover": #4096ff, - "foreground": rgba(0, 0, 0, 0.88), - "border": #d9d9d9, - "active-foreground": #0958d9, - "flat-foreground": #69b1ff, - "flat-background": rgba(0, 0, 0, 0.04), - "flat-active": rgba(0, 0, 0, 0.15), - "flat-hover": rgba(0, 0, 0, 0.06), - ), - "sample-2": ( - "primary": #1677ff, - "secondary": #4096ff, - "active": #0958d9, - "focus": #fff, - "flat-background": #e6f4ff, - "flat-hover": #bae0ff, - "flat-active": #91caff, - ), - "sample-3": ( - "primary": #ff4d4f, - "secondary": #ff7875, - "active": #d9363e, - "focus": #fff, - "flat-background": #fff2f0, - "flat-hover": #ffdfdc, - "flat-active": #ffccc7, - ), - "sample-4": ( - "primary": #eb2f96, - "secondary": #f759ab, - "active": #c41d7f, - "focus": #fff, - "flat-background": #fff0f6, - "flat-hover": #ffd6e7, - "flat-active": #ffadd2, - ), - "sample-5": ( - "primary": #722ed1, - "secondary": #9254de, - "active": #531dab, - "focus": #fff, - "flat-background": #f9f0ff, - "flat-hover": #efdbff, - "flat-active": #d3adf7, - ), - "sample-6": ( - "primary": #13c2c2, - "secondary": #36cfc9, - "active": #08979c, - "focus": #fff, - "flat-background": #e6fffb, - "flat-hover": #b5f5ec, - "flat-active": #b5f5ec, - ), -); - -@each $variant, $style in $list { - .buttons-#{$variant} [igxbutton="contained"] { - --background: #{map-get($style, "primary")}; - --hover-background: #{map-get($style, "secondary")}; - --active-background: #{map-get($style, "active")}; - --focus-visible-background: #{map-get($style, "primary")}; - --focus-visible-foreground: #{map-get($style, "focus")}; - --focus-hover-background: #{map-get($style, "secondary")}; - --focus-hover-foreground: #{map-get($style, "focus")}; - --focus-background: #{map-get($style, "active")}; - } - - @if $variant == "sample-1" { - .buttons-#{$variant} [igxbutton="outlined"] { - --foreground: #{map-get($style, "foreground")}; - --border-color: #{map-get($style, "border")}; - --hover-foreground: #{map-get($style, "hover")}; - --hover-border-color: #{map-get($style, "hover")}; - --active-foreground: #{map-get($style, "active-foreground")}; - --active-border-color: #{map-get($style, "active-foreground")}; - --focus-hover-background: #{map-get($style, "focus")}; - --focus-hover-foreground: #{map-get($style, "hover")}; - --focus-background: #{map-get($style, "focus")}; - --focus-foreground: #{map-get($style, "active-foreground")}; - --focus-visible-border-color: #{map-get($style, "border")}; - } - - .buttons-#{$variant} [igxbutton="flat"] { - --foreground: #{map-get($style, "foreground")}; - --active-foreground: #{map-get($style, "foreground")}; - } - - .buttons-#{$variant} .filled [igxbutton="flat"] { - --background: #{map-get($style, "flat-background")}; - --hover-background: #{map-get($style, "flat-hover")}; - --focus-visible-background: #{map-get($style, "flat-background")}; - } - - .buttons-#{$variant} .filled [igxbutton="flat"], - .buttons-#{$variant} .text [igxbutton="flat"] { - --hover-foreground: #{map-get($style, "foreground")}; - --focus-hover-background: #{map-get($style, "flat-hover")}; - --focus-background: #{map-get($style, "flat-active")}; - --focus-foreground: #{map-get($style, "foreground")}; - --focus-hover-foreground: #{map-get($style, "foreground")}; - --active-background: #{map-get($style, "flat-active")}; - } - - .buttons-#{$variant} .text [igxbutton="flat"] { - --hover-background: #{map-get($style, "flat-background")}; - } - - .buttons-#{$variant} .link [igxbutton="flat"] { - --hover-foreground: #{map-get($style, "flat-foreground")}; - --active-foreground: #{map-get($style, "active-foreground")}; - } - } - - @else { - .buttons-#{$variant} [igxbutton="outlined"] { - --foreground: #{map-get($style, "primary")}; - --border-color: #{map-get($style, "primary")}; - --hover-foreground: #{map-get($style, "secondary")}; - --hover-border-color: #{map-get($style, "secondary")}; - --active-foreground: #{map-get($style, "active")}; - --active-border-color: #{map-get($style, "active")}; - --focus-hover-background: #{map-get($style, "focus")}; - --focus-hover-foreground: #{map-get($style, "secondary")}; - --focus-background: #{map-get($style, "focus")}; - --focus-foreground: #{map-get($style, "active")}; - --focus-visible-border-color: #{map-get($style, "primary")}; - } - - .buttons-#{$variant} .filled [igxbutton="flat"] { - --background: #{map-get($style, "flat-background")}; - --hover-background: #{map-get($style, "flat-hover")}; - --hover-foreground: #{map-get($style, "primary")}; - --active-foreground: #{map-get($style, "primary")}; - --focus-visible-background: #{map-get($style, "flat-background")}; - --focus-hover-foreground: #{map-get($style, "primary")}; - --focus-foreground: #{map-get($style, "primary")}; - } - - .buttons-#{$variant} .filled [igxbutton="flat"], - .buttons-#{$variant} .text [igxbutton="flat"] { - --active-background: #{map-get($style, "flat-active")}; - } - - .buttons-#{$variant} .text [igxbutton="flat"], - .buttons-#{$variant} .link [igxbutton="flat"] { - --hover-foreground: #{map-get($style, "secondary")}; - --active-foreground: #{map-get($style, "active")}; - --focus-hover-foreground: #{map-get($style, "secondary")}; - --focus-foreground: #{map-get($style, "active")}; - } - - .buttons-#{$variant} [igxbutton="flat"] { - --foreground: #{map-get($style, "primary")}; - --focus-hover-background: #{map-get($style, "flat-hover")}; - --focus-background: #{map-get($style, "flat-active")}; - } - - .buttons-#{$variant} .text [igxbutton="flat"] { - --hover-background: #{map-get($style, "flat-background")}; - } - } - - .buttons-#{$variant} [igxbutton="flat"], - .buttons-#{$variant} [igxbutton="outlined"] { - --focus-visible-foreground: #{map-get($style, "primary")}; - } - - .buttons-#{$variant} [igxbutton="outlined"], - .buttons-#{$variant} .text [igxbutton="flat"], - .buttons-#{$variant} .link [igxbutton="flat"] { - --focus-visible-background: transparent; - } -} - -.button-sample [igxbutton="contained"] { - --foreground: #fff; - --hover-foreground: #fff; - --active-foreground: #fff; -} - -.button-sample [igxbutton="outlined"] { - --background: transparent; - --hover-background: transparent; - --active-background: transparent; -} - -// Sass theme approach - -// $custom-contained-theme: contained-button-theme( -// $background: #f9f0ff, -// $foreground: #722ed1, -// $hover-background: #efdbff, -// $hover-foreground: #9254de, -// $active-foreground: #531dab, -// $active-background: #dfc2fa, -// $focus-visible-background: #d3adf7 -// ); - -// $custom-outlined-theme: outlined-button-theme( -// $background: #fff2f0, -// $foreground: #ff4d4f, -// $border-color: #ff4d4f, -// $hover-background: #ffdfdc, -// $hover-foreground: #ff7875, -// $hover-border-color: #ff7875, -// $focus-visible-background: #ffccc7, -// $focus-visible-foreground: #d9363e, -// $focus-border-color: #d9363e -// ); - -// $custom-flat-theme: flat-button-theme( -// $background: #e6fffb, -// $foreground: #13c2c2, -// $hover-background: #b5f5ec, -// $hover-foreground: #36cfc9, -// $active-foreground: #08979c, -// $focus-visible-background: #b5f5ec, -// $focus-visible-foreground: #08979c -// ); - -// .button-sample { -// @include tokens($custom-contained-theme); -// @include tokens($custom-outlined-theme); -// } - -// .button-sample.filled { -// @include tokens($custom-flat-theme); -// } diff --git a/src/app/data-entries/buttons/buttons-style/buttons-style.component.ts b/src/app/data-entries/buttons/buttons-style/buttons-style.component.ts deleted file mode 100644 index ce5d497395..0000000000 --- a/src/app/data-entries/buttons/buttons-style/buttons-style.component.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Component } from '@angular/core'; -import { IgxButtonDirective } from 'igniteui-angular/directives'; -import { THEME_TOKEN, ThemeToken } from 'igniteui-angular/core'; - -@Component({ - selector: 'app-buttons-style', - styleUrls: ['./buttons-style.component.scss'], - templateUrl: './buttons-style.component.html', - imports: [IgxButtonDirective], - providers: [{provide: THEME_TOKEN, useFactory: () => new ThemeToken('bootstrap')}] -}) -export class ButtonsStyleComponent { - range = Array(6); -} diff --git a/src/app/data-entries/buttons/buttons-style/layout.scss b/src/app/data-entries/buttons/buttons-style/layout.scss deleted file mode 100644 index 43cf337fa2..0000000000 --- a/src/app/data-entries/buttons/buttons-style/layout.scss +++ /dev/null @@ -1,47 +0,0 @@ -@use "igniteui-angular/theming" as *; -@use "igniteui-angular/lib/core/styles/components/button/button-component" as button; -@use 'sass:map'; - -:host { - ::ng-deep { - @include button($flat: flat-button-theme($schema: $light-bootstrap-schema), - $contained: contained-button-theme($schema: $light-bootstrap-schema), - $outlined: outlined-button-theme($schema: $light-bootstrap-schema), - $fab: fab-button-theme($schema: $light-bootstrap-schema)); - @include button.component(); - } -} - -[class^=buttons-sample] { - display: flex; - margin: 1rem rem(8px) rem(8px) 1rem; -} - -.button-sample { - margin-right: 1rem; -} - -.dashed button{ - border-style: dashed; -} - -[class^="buttons-sample"]:hover .link button { - background: none; -} - -[igxbutton] { - --ig-button-font-weight: 400; - --ig-button-text-transform: capitalize; - min-height: rem(24px); - outline: rem(1px) solid #fff; -} - -.button-sample button { - --ig-size: var(--ig-size-medium); - padding: 0px rem(7px); - min-width: unset; -} - -.button-sample .igx-button { - --ig-font-family: 'alibaba-sans', sans-serif; -} \ No newline at end of file diff --git a/src/app/data-entries/buttons/buttons-tailwind-style/buttons-tailwind-style.component.html b/src/app/data-entries/buttons/buttons-tailwind-style/buttons-tailwind-style.component.html deleted file mode 100644 index 51cc42daa2..0000000000 --- a/src/app/data-entries/buttons/buttons-tailwind-style/buttons-tailwind-style.component.html +++ /dev/null @@ -1,14 +0,0 @@ -
-
- -
-
- -
-
- -
-
- -
-
diff --git a/src/app/data-entries/buttons/buttons-tailwind-style/buttons-tailwind-style.component.scss b/src/app/data-entries/buttons/buttons-tailwind-style/buttons-tailwind-style.component.scss deleted file mode 100644 index a60d456faa..0000000000 --- a/src/app/data-entries/buttons/buttons-tailwind-style/buttons-tailwind-style.component.scss +++ /dev/null @@ -1 +0,0 @@ -@use "layout.scss"; diff --git a/src/app/data-entries/buttons/buttons-tailwind-style/buttons-tailwind-style.component.ts b/src/app/data-entries/buttons/buttons-tailwind-style/buttons-tailwind-style.component.ts deleted file mode 100644 index 2bbd669b48..0000000000 --- a/src/app/data-entries/buttons/buttons-tailwind-style/buttons-tailwind-style.component.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Component } from '@angular/core'; -import { IgxButtonDirective } from 'igniteui-angular/directives'; - -@Component({ - selector: 'app-buttons-tailwind-style', - styleUrls: ['./buttons-tailwind-style.component.scss'], - templateUrl: './buttons-tailwind-style.component.html', - imports: [IgxButtonDirective] -}) -export class ButtonsTailwindStyleComponent {} diff --git a/src/app/data-entries/buttons/buttons-tailwind-style/layout.scss b/src/app/data-entries/buttons/buttons-tailwind-style/layout.scss deleted file mode 100644 index 36396d2d00..0000000000 --- a/src/app/data-entries/buttons/buttons-tailwind-style/layout.scss +++ /dev/null @@ -1,9 +0,0 @@ -.buttons-sample { - display: flex; - margin: 8px; -} - -.button-sample { - display: flex; - margin-right: 16px; -} \ No newline at end of file diff --git a/src/app/data-entries/data-entries-routes-data.ts b/src/app/data-entries/data-entries-routes-data.ts index 5e710a28e7..f3ae82348a 100644 --- a/src/app/data-entries/data-entries-routes-data.ts +++ b/src/app/data-entries/data-entries-routes-data.ts @@ -13,19 +13,17 @@ export const dataEntriesRoutesData = { "button-group-size": { displayName: "Button Group Size", parentName: "Button Group" }, "button-group-styling": { displayName: "Button Group Styling", parentName: "Button Group" }, "button-group-tailwind-styling": { displayName: "Button Group Tailwind Styling", parentName: "Button Group" }, - "buttons-sample-1": { displayName: "Overview", parentName: "Buttons" }, - "buttons-sample-2": { displayName: "Flat Button", parentName: "Buttons" }, - "buttons-sample-3": { displayName: "Button Ripple", parentName: "Buttons" }, - "buttons-sample-4": { displayName: "Span Button", parentName: "Buttons" }, - "buttons-sample-5": { displayName: "Contained Button", parentName: "Buttons" }, - "buttons-sample-6": { displayName: "Floating Action Button", parentName: "Buttons" }, - "buttons-sample-7": { displayName: "Icon Button", parentName: "Buttons" }, - "buttons-sample-8": { displayName: "Outlined Button", parentName: "Buttons" }, - "buttons-disabled-sample": { displayName: "Disabled Button", parentName: "Buttons" }, - "buttons-display-density": { displayName: "Display Density", parentName: "Buttons" }, - "buttons-roundness-sample": { displayName: "Components Roundness", parentName: "Buttons" }, - "buttons-style": { displayName: "Button Style", parentName: "Buttons" }, - "buttons-tailwind-style": { displayName: "Button Tailwind Style", parentName: "Buttons" }, + "button-overview": { displayName: "Overview", parentName: "Button" }, + "button-flat": { displayName: "Flat Button", parentName: "Button" }, + "button-interaction-states": { displayName: "Button Interaction States", parentName: "Button" }, + "button-layout": { displayName: "Button Layout", parentName: "Button" }, + "button-contained": { displayName: "Contained Button", parentName: "Button" }, + "button-fab": { displayName: "Floating Action Button", parentName: "Button" }, + "button-states": { displayName: "Button States", parentName: "Button" }, + "button-size": { displayName: "Button Size", parentName: "Button" }, + "button-download": { displayName: "Download Button", parentName: "Button" }, + "button-styling": { displayName: "Button Style", parentName: "Button" }, + "button-tailwind-styling": { displayName: "Button Tailwind Style", parentName: "Button" }, "checkbox-sample-1": { displayName: "Simple Checkbox", parentName: "Checkbox" }, "checkbox-sample-2": { displayName: "Multiple Checkboxes", parentName: "Checkbox" }, "checkbox-sample-3": { displayName: "Indeterminate Checkbox", parentName: "Checkbox" }, diff --git a/src/app/data-entries/data-entries.routes.ts b/src/app/data-entries/data-entries.routes.ts index 8bc329cfcc..cfed6215e8 100644 --- a/src/app/data-entries/data-entries.routes.ts +++ b/src/app/data-entries/data-entries.routes.ts @@ -11,19 +11,18 @@ import { ButtonGroupSelectionComponent } from './buttonGroup/button-group-select import { ButtonGroupSizeComponent } from './buttonGroup/button-group-size/button-group-size.component'; import { ButtonGroupStylingComponent } from './buttonGroup/button-group-styling/button-group-styling.component'; import { ButtonGroupTailwindStylingComponent } from './buttonGroup/button-group-tailwind-styling/button-group-tailwind-styling.component'; -import { ButtonsDisabledComponent } from './buttons/buttons-disabled-sample/buttons-disabled-sample'; -import { ButtonsDisplayDensityComponent } from './buttons/buttons-display-density/buttons-display-density.component'; -import { ButtonsRoundnessComponent } from './buttons/buttons-roundness-sample/buttons-roundness-sample'; -import { ButtonsSample1Component } from './buttons/buttons-sample-1/buttons-sample-1.component'; -import { ButtonsSample2Component } from './buttons/buttons-sample-2/buttons-sample-2.component'; -import { ButtonsSample3Component } from './buttons/buttons-sample-3/buttons-sample-3.component'; -import { ButtonsSample4Component } from './buttons/buttons-sample-4/buttons-sample-4.component'; -import { ButtonsSample5Component } from './buttons/buttons-sample-5/buttons-sample-5.component'; -import { ButtonsSample6Component } from './buttons/buttons-sample-6/buttons-sample-6.component'; -import { ButtonsSample7Component } from './buttons/buttons-sample-7/buttons-sample-7.component'; -import { ButtonsSample8Component } from './buttons/buttons-sample-8/buttons-sample-8.component'; -import { ButtonsStyleComponent } from './buttons/buttons-style/buttons-style.component'; -import { ButtonsTailwindStyleComponent } from './buttons/buttons-tailwind-style/buttons-tailwind-style.component'; +import { ButtonStatesComponent } from './button/button-states/button-states.component'; +import { ButtonSizeComponent } from './button/button-size/button-size.component'; +import { ButtonDownloadComponent } from './button/button-download/button-download.component'; +import { ButtonOverviewComponent } from './button/button-overview/button-overview.component'; +import { ButtonFlatComponent } from './button/button-flat/button-flat.component'; +import { ButtonInteractionStatesComponent } from './button/button-interaction-states/button-interaction-states.component'; +import { ButtonLayoutComponent } from './button/button-layout/button-layout.component'; +import { ButtonContainedComponent } from './button/button-contained/button-contained.component'; +import { ButtonFabComponent } from './button/button-fab/button-fab.component'; +import { ButtonOutlinedComponent } from './button/button-outlined/button-outlined.component'; +import { ButtonStylingComponent } from './button/button-styling/button-styling.component'; +import { ButtonTailwindStylingComponent } from './button/button-tailwind-styling/button-tailwind-styling.component'; import { CheckboxSample1Component } from './checkbox/checkbox-sample-1/checkbox-sample-1.component'; import { CheckboxSample2Component } from './checkbox/checkbox-sample-2/checkbox-sample-2.component'; import { CheckboxSample3Component } from './checkbox/checkbox-sample-3/checkbox-sample-3.component'; @@ -97,9 +96,9 @@ export const DataEntriesRoutes: Routes = [ path: 'movie' }, { - component: ButtonsDisplayDensityComponent, - data: dataEntriesRoutesData['buttons-display-density'], - path: 'buttons-display-density' + component: ButtonSizeComponent, + data: dataEntriesRoutesData['button-size'], + path: 'button-size' }, { component: ButtonGroupOverviewComponent, @@ -152,64 +151,59 @@ export const DataEntriesRoutes: Routes = [ path: 'button-group-tailwind-styling' }, { - component: ButtonsRoundnessComponent, - data: dataEntriesRoutesData['buttons-roundness-sample'], - path: 'buttons-roundness-sample' + component: ButtonOverviewComponent, + data: dataEntriesRoutesData['button-overview'], + path: 'button-overview' }, { - component: ButtonsSample1Component, - data: dataEntriesRoutesData['buttons-sample-1'], - path: 'buttons-sample-1' + component: ButtonFlatComponent, + data: dataEntriesRoutesData['button-flat'], + path: 'button-flat' }, { - component: ButtonsSample2Component, - data: dataEntriesRoutesData['buttons-sample-2'], - path: 'buttons-sample-2' + component: ButtonInteractionStatesComponent, + data: dataEntriesRoutesData['button-interaction-states'], + path: 'button-interaction-states' }, { - component: ButtonsSample3Component, - data: dataEntriesRoutesData['buttons-sample-3'], - path: 'buttons-sample-3' + component: ButtonLayoutComponent, + data: dataEntriesRoutesData['button-layout'], + path: 'button-layout' }, { - component: ButtonsSample4Component, - data: dataEntriesRoutesData['buttons-sample-4'], - path: 'buttons-sample-4' + component: ButtonContainedComponent, + data: dataEntriesRoutesData['button-contained'], + path: 'button-contained' }, { - component: ButtonsSample5Component, - data: dataEntriesRoutesData['buttons-sample-5'], - path: 'buttons-sample-5' + component: ButtonFabComponent, + data: dataEntriesRoutesData['button-fab'], + path: 'button-fab' }, { - component: ButtonsSample6Component, - data: dataEntriesRoutesData['buttons-sample-6'], - path: 'buttons-sample-6' + component: ButtonOutlinedComponent, + data: dataEntriesRoutesData['button-outlined'], + path: 'button-outlined' }, { - component: ButtonsSample7Component, - data: dataEntriesRoutesData['buttons-sample-7'], - path: 'buttons-sample-7' + component: ButtonStatesComponent, + data: dataEntriesRoutesData['button-states'], + path: 'button-states' }, { - component: ButtonsSample8Component, - data: dataEntriesRoutesData['buttons-sample-8'], - path: 'buttons-sample-8' + component: ButtonDownloadComponent, + data: dataEntriesRoutesData['button-download'], + path: 'button-download' }, { - component: ButtonsDisabledComponent, - data: dataEntriesRoutesData['buttons-disabled-sample'], - path: 'buttons-disabled-sample' + component: ButtonStylingComponent, + data: dataEntriesRoutesData['button-styling'], + path: 'button-styling' }, { - component: ButtonsStyleComponent, - data: dataEntriesRoutesData['buttons-style'], - path: 'buttons-style' - }, - { - component: ButtonsTailwindStyleComponent, - data: dataEntriesRoutesData['buttons-tailwind-style'], - path: 'buttons-tailwind-style' + component: ButtonTailwindStylingComponent, + data: dataEntriesRoutesData['button-tailwind-styling'], + path: 'button-tailwind-styling' }, { component: CheckboxSample1Component, From 721ee8489286eb73d127b5f06dc4a386878188e0 Mon Sep 17 00:00:00 2001 From: Hristo Hristov <57346540+Hristo313@users.noreply.github.com> Date: Tue, 15 Sep 2026 17:07:00 +0300 Subject: [PATCH 06/22] feat(switch): update samples content (#4025) * feat(switch): update samples content * fix(switch): update styling sample css * fix(switch): update theme to bootstrap --------- Co-authored-by: Stamen Stoychev --- live-editing/configs/SwitchConfigGenerator.ts | 30 ++- .../data-entries/data-entries-routes-data.ts | 7 +- src/app/data-entries/data-entries.routes.ts | 34 +++- .../data-entries/switch/switch-bootstrap.scss | 65 +++++++ .../switch-disabled.component.html | 14 ++ .../switch-disabled.component.scss | 38 ++++ .../switch-disabled.component.ts | 10 + .../switch-enabled.component.html | 28 +++ .../switch-enabled.component.scss | 40 ++++ .../switch-enabled.component.ts | 10 + .../switch-layout.component.html | 14 ++ .../switch-layout.component.scss | 39 ++++ .../switch-layout/switch-layout.component.ts | 10 + .../switch-overview.component.html | 27 +++ .../switch-overview.component.scss | 65 +++++++ .../switch-overview.component.ts | 10 + .../switch-sample-1.component.html | 3 - .../switch-sample-1.component.scss | 4 - .../switch-sample-1.component.ts | 10 - .../switch-sample-2.component.html | 6 - .../switch-sample-2.component.scss | 9 - .../switch-sample-2.component.ts | 17 -- .../switch-selected.component.html | 17 ++ .../switch-selected.component.scss | 33 ++++ .../switch-selected.component.ts | 10 + .../switch/switch-styling/layout.scss | 59 ------ .../switch-styling.component.html | 28 ++- .../switch-styling.component.scss | 173 ++++++++++++++---- .../switch-styling.component.ts | 28 ++- .../switch-tailwind-styling/layout.scss | 9 - .../switch-tailwind-styling.component.html | 24 ++- .../switch-tailwind-styling.component.scss | 19 +- .../switch-tailwind-styling.component.ts | 19 +- 33 files changed, 711 insertions(+), 198 deletions(-) create mode 100644 src/app/data-entries/switch/switch-bootstrap.scss create mode 100644 src/app/data-entries/switch/switch-disabled/switch-disabled.component.html create mode 100644 src/app/data-entries/switch/switch-disabled/switch-disabled.component.scss create mode 100644 src/app/data-entries/switch/switch-disabled/switch-disabled.component.ts create mode 100644 src/app/data-entries/switch/switch-enabled/switch-enabled.component.html create mode 100644 src/app/data-entries/switch/switch-enabled/switch-enabled.component.scss create mode 100644 src/app/data-entries/switch/switch-enabled/switch-enabled.component.ts create mode 100644 src/app/data-entries/switch/switch-layout/switch-layout.component.html create mode 100644 src/app/data-entries/switch/switch-layout/switch-layout.component.scss create mode 100644 src/app/data-entries/switch/switch-layout/switch-layout.component.ts create mode 100644 src/app/data-entries/switch/switch-overview/switch-overview.component.html create mode 100644 src/app/data-entries/switch/switch-overview/switch-overview.component.scss create mode 100644 src/app/data-entries/switch/switch-overview/switch-overview.component.ts delete mode 100644 src/app/data-entries/switch/switch-sample-1/switch-sample-1.component.html delete mode 100644 src/app/data-entries/switch/switch-sample-1/switch-sample-1.component.scss delete mode 100644 src/app/data-entries/switch/switch-sample-1/switch-sample-1.component.ts delete mode 100644 src/app/data-entries/switch/switch-sample-2/switch-sample-2.component.html delete mode 100644 src/app/data-entries/switch/switch-sample-2/switch-sample-2.component.scss delete mode 100644 src/app/data-entries/switch/switch-sample-2/switch-sample-2.component.ts create mode 100644 src/app/data-entries/switch/switch-selected/switch-selected.component.html create mode 100644 src/app/data-entries/switch/switch-selected/switch-selected.component.scss create mode 100644 src/app/data-entries/switch/switch-selected/switch-selected.component.ts delete mode 100644 src/app/data-entries/switch/switch-styling/layout.scss delete mode 100644 src/app/data-entries/switch/switch-tailwind-styling/layout.scss diff --git a/live-editing/configs/SwitchConfigGenerator.ts b/live-editing/configs/SwitchConfigGenerator.ts index 3e92e34182..6000f24dbe 100644 --- a/live-editing/configs/SwitchConfigGenerator.ts +++ b/live-editing/configs/SwitchConfigGenerator.ts @@ -7,16 +7,37 @@ export class SwitchConfigGenerator implements IConfigGenerator { public generateConfigs(): Config[] { const configs = new Array(); - // switch sample 1 + // switch overview configs.push(new Config({ - component: 'SwitchSample1Component', + component: 'SwitchOverviewComponent', appConfig: BaseAppConfig, shortenComponentPathBy: "/data-entries/switch/" })); - // switch sample 2 + // switch enabled configs.push(new Config({ - component: 'SwitchSample2Component', + component: 'SwitchEnabledComponent', + appConfig: BaseAppConfig, + shortenComponentPathBy: "/data-entries/switch/" + })); + + // switch disabled + configs.push(new Config({ + component: 'SwitchDisabledComponent', + appConfig: BaseAppConfig, + shortenComponentPathBy: "/data-entries/switch/" + })); + + // switch selected + configs.push(new Config({ + component: 'SwitchSelectedComponent', + appConfig: BaseAppConfig, + shortenComponentPathBy: "/data-entries/switch/" + })); + + // switch layout + configs.push(new Config({ + component: 'SwitchLayoutComponent', appConfig: BaseAppConfig, shortenComponentPathBy: "/data-entries/switch/" })); @@ -24,7 +45,6 @@ export class SwitchConfigGenerator implements IConfigGenerator { // switch styling configs.push(new Config({ component: 'SwitchStylingComponent', - additionalFiles: ["/src/app/data-entries/switch/switch-styling/layout.scss"], appConfig: BaseAppConfig, shortenComponentPathBy: "/data-entries/switch/" })); diff --git a/src/app/data-entries/data-entries-routes-data.ts b/src/app/data-entries/data-entries-routes-data.ts index f3ae82348a..c12dffbf41 100644 --- a/src/app/data-entries/data-entries-routes-data.ts +++ b/src/app/data-entries/data-entries-routes-data.ts @@ -67,8 +67,11 @@ export const dataEntriesRoutesData = { "radio-styling-sample": { displayName: "Styling Radio Buttons", parentName: "Radio" }, "radio-tailwind-styling-sample": { displayName: "Tailwind Styling Radio Buttons", parentName: "Radio" }, "rating-form": { displayName: "Rating in Form", parentName: "Rating" }, - "switch-sample-1": { displayName: "Switch Overview", parentName: "Switch" }, - "switch-sample-2": { displayName: "Multiple Switches", parentName: "Switch" }, + "switch-overview": { displayName: "Switch Overview", parentName: "Switch" }, + "switch-enabled": { displayName: "Enabled Switches", parentName: "Switch" }, + "switch-disabled": { displayName: "Disabled Switches", parentName: "Switch" }, + "switch-selected": { displayName: "Selected Switches", parentName: "Switch" }, + "switch-layout": { displayName: "Switch Label Position", parentName: "Switch" }, "switch-styling": { displayName: "Styled Switches", parentName: "Switch" }, "switch-tailwind-styling": { displayName: "Tailwind Styled Switches", parentName: "Switch" }, "select-sample-1": { displayName: "Simple Select", parentName: "Select" }, diff --git a/src/app/data-entries/data-entries.routes.ts b/src/app/data-entries/data-entries.routes.ts index cfed6215e8..8132650c35 100644 --- a/src/app/data-entries/data-entries.routes.ts +++ b/src/app/data-entries/data-entries.routes.ts @@ -66,8 +66,11 @@ import { SelectSample2Component } from './select/select-sample-2/select-sample-2 import { SelectSample4Component } from './select/select-sample-4/select-sample-4.component'; import { SelectStylingComponent } from './select/select-styling/select-styling.component'; import { SelectTailwindStylingComponent } from './select/select-tailwind-styling/select-tailwind-styling.component'; -import { SwitchSample1Component } from './switch/switch-sample-1/switch-sample-1.component'; -import { SwitchSample2Component } from './switch/switch-sample-2/switch-sample-2.component'; +import { SwitchOverviewComponent } from './switch/switch-overview/switch-overview.component'; +import { SwitchEnabledComponent } from './switch/switch-enabled/switch-enabled.component'; +import { SwitchDisabledComponent } from './switch/switch-disabled/switch-disabled.component'; +import { SwitchSelectedComponent } from './switch/switch-selected/switch-selected.component'; +import { SwitchLayoutComponent } from './switch/switch-layout/switch-layout.component'; import { SwitchStylingComponent } from './switch/switch-styling/switch-styling.component'; import { SwitchTailwindStylingComponent } from './switch/switch-tailwind-styling/switch-tailwind-styling.component'; import { RatingInFormComponent } from './rating/rating-form/rating-form.component'; @@ -421,14 +424,29 @@ export const DataEntriesRoutes: Routes = [ path: 'rating-form' }, { - component: SwitchSample1Component, - data: dataEntriesRoutesData['switch-sample-1'], - path: 'switch-sample-1' + component: SwitchOverviewComponent, + data: dataEntriesRoutesData['switch-overview'], + path: 'switch-overview' }, { - component: SwitchSample2Component, - data: dataEntriesRoutesData['switch-sample-2'], - path: 'switch-sample-2' + component: SwitchEnabledComponent, + data: dataEntriesRoutesData['switch-enabled'], + path: 'switch-enabled' + }, + { + component: SwitchDisabledComponent, + data: dataEntriesRoutesData['switch-disabled'], + path: 'switch-disabled' + }, + { + component: SwitchSelectedComponent, + data: dataEntriesRoutesData['switch-selected'], + path: 'switch-selected' + }, + { + component: SwitchLayoutComponent, + data: dataEntriesRoutesData['switch-layout'], + path: 'switch-layout' }, { component: SwitchStylingComponent, diff --git a/src/app/data-entries/switch/switch-bootstrap.scss b/src/app/data-entries/switch/switch-bootstrap.scss new file mode 100644 index 0000000000..3212de8336 --- /dev/null +++ b/src/app/data-entries/switch/switch-bootstrap.scss @@ -0,0 +1,65 @@ +@use "igniteui-angular/theming" as *; + +// Bootstrap switch geometry, aligned with the Bootstrap form-switch proportions. +@mixin bootstrap-switch { + :host ::ng-deep igx-switch { + --switch-width: #{rem(32px)}; + --switch-height: #{rem(16px)}; + --switch-thumb-size: #{rem(9px)}; + --switch-on-offset: #{rem(3px)}; + --switch-off-offset: #{rem(3px)}; + + ::ng-deep { + .igx-switch__composite { + box-sizing: border-box; + } + + .igx-switch__composite-thumb { + width: #{rem(9px)}; + height: #{rem(9px)}; + min-width: #{rem(9px)}; + box-shadow: none; + } + + .igx-switch__thumb { + width: #{rem(9px)}; + height: #{rem(9px)}; + min-width: #{rem(9px)}; + } + + .igx-switch__composite-thumb, + .igx-switch__thumb { + inline-size: #{rem(9px)}; + block-size: #{rem(9px)}; + min-inline-size: #{rem(9px)}; + max-inline-size: #{rem(9px)}; + min-block-size: #{rem(9px)}; + max-block-size: #{rem(9px)}; + } + } + + &.igx-switch--checked:not(.igx-switch--disabled) ::ng-deep .igx-switch__composite-thumb { + transform: translateX(#{rem(18px)}); + } + + &.igx-switch--checked:not(.igx-switch--disabled) ::ng-deep .igx-switch__composite { + background: var(--ig-primary-500); + } + + &.igx-switch--disabled ::ng-deep .igx-switch__composite-thumb { + transform: translateX(#{rem(3px)}) translateY(-1px); + } + + &.igx-switch--disabled.igx-switch--checked ::ng-deep .igx-switch__composite-thumb { + transform: translateX(#{rem(18px)}) translateY(0); + } + } + + :host ::ng-deep igx-switch.igx-switch--disabled.igx-switch--checked .igx-switch__composite-thumb { + transform: translateX(#{rem(18px)}) translateY(0); + } + + :host ::ng-deep igx-switch:not(.igx-switch--disabled) { + --track-on-color: var(--ig-primary-500); + } +} diff --git a/src/app/data-entries/switch/switch-disabled/switch-disabled.component.html b/src/app/data-entries/switch/switch-disabled/switch-disabled.component.html new file mode 100644 index 0000000000..280874ac2c --- /dev/null +++ b/src/app/data-entries/switch/switch-disabled/switch-disabled.component.html @@ -0,0 +1,14 @@ +
+
+ Disabled Checked + + Power + +
+
+ Disabled Unchecked + + Power + +
+
diff --git a/src/app/data-entries/switch/switch-disabled/switch-disabled.component.scss b/src/app/data-entries/switch/switch-disabled/switch-disabled.component.scss new file mode 100644 index 0000000000..7adeb2efb1 --- /dev/null +++ b/src/app/data-entries/switch/switch-disabled/switch-disabled.component.scss @@ -0,0 +1,38 @@ +@use "igniteui-angular/theming" as *; +@use "sass:map"; +@use "../switch-bootstrap" as switch-bootstrap; + +@include switch-bootstrap.bootstrap-switch; + +:host { + display: flex; + min-block-size: 100%; + box-sizing: border-box; + place-content: center; + place-items: center; + padding: 16px; + + @include tokens(switch-theme($schema: map.get($light-bootstrap-schema, switch))); +} + +.states { + --variant-gap: 60px; + --label-gap: 30px; + + display: flex; + align-items: center; + justify-content: center; + gap: var(--variant-gap); + + .states__variant { + display: flex; + align-items: center; + gap: var(--label-gap); + } + + .states__label { + font: 500 14px / 24px "Aktiv Grotesk", sans-serif; + letter-spacing: 0.1px; + color: var(--ig-gray-600); + } +} diff --git a/src/app/data-entries/switch/switch-disabled/switch-disabled.component.ts b/src/app/data-entries/switch/switch-disabled/switch-disabled.component.ts new file mode 100644 index 0000000000..0dba8b971d --- /dev/null +++ b/src/app/data-entries/switch/switch-disabled/switch-disabled.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; +import { IgxSwitchComponent } from 'igniteui-angular/switch'; + +@Component({ + selector: 'app-switch-disabled', + styleUrls: ['./switch-disabled.component.scss'], + templateUrl: './switch-disabled.component.html', + imports: [IgxSwitchComponent] +}) +export class SwitchDisabledComponent { } diff --git a/src/app/data-entries/switch/switch-enabled/switch-enabled.component.html b/src/app/data-entries/switch/switch-enabled/switch-enabled.component.html new file mode 100644 index 0000000000..4ca5c510c4 --- /dev/null +++ b/src/app/data-entries/switch/switch-enabled/switch-enabled.component.html @@ -0,0 +1,28 @@ +
+ + Hover + Focused + Focused & Hover + + Enabled / On + + Power + + + Power + + + Power + + + Enabled / Off + + Power + + + Power + + + Power + +
diff --git a/src/app/data-entries/switch/switch-enabled/switch-enabled.component.scss b/src/app/data-entries/switch/switch-enabled/switch-enabled.component.scss new file mode 100644 index 0000000000..331ca49c32 --- /dev/null +++ b/src/app/data-entries/switch/switch-enabled/switch-enabled.component.scss @@ -0,0 +1,40 @@ +@use "igniteui-angular/theming" as *; +@use "sass:map"; +@use "../switch-bootstrap" as switch-bootstrap; + +@include switch-bootstrap.bootstrap-switch; + +:host { + display: flex; + place-content: center; + place-items: center; + padding: 16px; + + @include tokens(switch-theme($schema: map.get($light-bootstrap-schema, switch))); +} + +.states { + display: grid; + grid-template-columns: repeat(4, auto); + align-items: center; + gap: 32px 24px; + + .states__column, + .states__row { + font: 500 14px / 24px "Aktiv Grotesk", sans-serif; + letter-spacing: 0.1px; + color: var(--ig-gray-600); + } + + .states__column { + text-align: center; + } + + .states__row { + text-align: end; + } + + igx-switch { + justify-self: center; + } +} diff --git a/src/app/data-entries/switch/switch-enabled/switch-enabled.component.ts b/src/app/data-entries/switch/switch-enabled/switch-enabled.component.ts new file mode 100644 index 0000000000..8eaf65933b --- /dev/null +++ b/src/app/data-entries/switch/switch-enabled/switch-enabled.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; +import { IgxSwitchComponent } from 'igniteui-angular/switch'; + +@Component({ + selector: 'app-switch-enabled', + styleUrls: ['./switch-enabled.component.scss'], + templateUrl: './switch-enabled.component.html', + imports: [IgxSwitchComponent] +}) +export class SwitchEnabledComponent { } diff --git a/src/app/data-entries/switch/switch-layout/switch-layout.component.html b/src/app/data-entries/switch/switch-layout/switch-layout.component.html new file mode 100644 index 0000000000..0458faa19e --- /dev/null +++ b/src/app/data-entries/switch/switch-layout/switch-layout.component.html @@ -0,0 +1,14 @@ +
+
+ Label Before + + Power + +
+
+ Label After + + Power + +
+
diff --git a/src/app/data-entries/switch/switch-layout/switch-layout.component.scss b/src/app/data-entries/switch/switch-layout/switch-layout.component.scss new file mode 100644 index 0000000000..c281c73024 --- /dev/null +++ b/src/app/data-entries/switch/switch-layout/switch-layout.component.scss @@ -0,0 +1,39 @@ +@use "igniteui-angular/theming" as *; +@use "sass:map"; +@use "../switch-bootstrap" as switch-bootstrap; + +@include switch-bootstrap.bootstrap-switch; + +:host { + display: flex; + min-block-size: 100%; + box-sizing: border-box; + place-content: center; + place-items: center; + padding: 16px; + + @include tokens(switch-theme($schema: map.get($light-bootstrap-schema, switch))); +} + +.variants { + --variant-gap: 60px; + --label-gap: 30px; + + display: flex; + inline-size: 100%; + align-items: center; + justify-content: center; + gap: var(--variant-gap); + + .variants__item { + display: flex; + align-items: center; + gap: var(--label-gap); + } + + .variants__label { + font: 500 14px / 24px "Aktiv Grotesk", sans-serif; + letter-spacing: 0.1px; + color: var(--ig-gray-600); + } +} diff --git a/src/app/data-entries/switch/switch-layout/switch-layout.component.ts b/src/app/data-entries/switch/switch-layout/switch-layout.component.ts new file mode 100644 index 0000000000..d9bef05a86 --- /dev/null +++ b/src/app/data-entries/switch/switch-layout/switch-layout.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; +import { IgxSwitchComponent } from 'igniteui-angular/switch'; + +@Component({ + selector: 'app-switch-layout', + styleUrls: ['./switch-layout.component.scss'], + templateUrl: './switch-layout.component.html', + imports: [IgxSwitchComponent] +}) +export class SwitchLayoutComponent { } diff --git a/src/app/data-entries/switch/switch-overview/switch-overview.component.html b/src/app/data-entries/switch/switch-overview/switch-overview.component.html new file mode 100644 index 0000000000..2d0fe64c1b --- /dev/null +++ b/src/app/data-entries/switch/switch-overview/switch-overview.component.html @@ -0,0 +1,27 @@ +
+
Notifications
+
+ + + Push notifications + Deliver alerts to this device + + +
+
+ + + Weekly digest + Summary email every Monday + + +
+
+ + + SMS alerts + Unavailable on your plan + + +
+
diff --git a/src/app/data-entries/switch/switch-overview/switch-overview.component.scss b/src/app/data-entries/switch/switch-overview/switch-overview.component.scss new file mode 100644 index 0000000000..289bdc2420 --- /dev/null +++ b/src/app/data-entries/switch/switch-overview/switch-overview.component.scss @@ -0,0 +1,65 @@ +@use "igniteui-angular/theming" as *; +@use "sass:map"; +@use "../switch-bootstrap" as switch-bootstrap; + +@include switch-bootstrap.bootstrap-switch; + +:host { + display: flex; + place-content: center; + place-items: center; + padding: 16px; + + @include tokens(switch-theme($schema: map.get($light-bootstrap-schema, switch))); +} + +.notifications { + inline-size: 100%; + max-inline-size: 384px; + background: var(--ig-surface-500); + border-radius: 4px; + overflow: hidden; + + .notifications__title { + margin: 0; + padding: 16px; + font: 400 10px / 16px "Titillium Web", sans-serif; + letter-spacing: 1.5px; + text-transform: uppercase; + color: var(--ig-primary-500); + } + + .notifications__row { + padding-block: 12px; + padding-inline: 16px; + + igx-switch { + inline-size: 100%; + justify-content: space-between; + gap: 16px; + transform: translateX(-10px); + + ::ng-deep .igx-switch__composite { + transform: translateX(8px); + } + } + } +} + +.option { + display: flex; + flex-direction: column; + gap: 2px; + text-align: start; + white-space: normal; + + .option__label { + font-size: 16px; + color: var(--ig-gray-900); + } + + .option__hint { + font-size: 13px; + color: var(--ig-gray-700); + } +} diff --git a/src/app/data-entries/switch/switch-overview/switch-overview.component.ts b/src/app/data-entries/switch/switch-overview/switch-overview.component.ts new file mode 100644 index 0000000000..88946f53fe --- /dev/null +++ b/src/app/data-entries/switch/switch-overview/switch-overview.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; +import { IgxSwitchComponent } from 'igniteui-angular/switch'; + +@Component({ + selector: 'app-switch-overview', + styleUrls: ['./switch-overview.component.scss'], + templateUrl: './switch-overview.component.html', + imports: [IgxSwitchComponent] +}) +export class SwitchOverviewComponent { } diff --git a/src/app/data-entries/switch/switch-sample-1/switch-sample-1.component.html b/src/app/data-entries/switch/switch-sample-1/switch-sample-1.component.html deleted file mode 100644 index f6c2ce336f..0000000000 --- a/src/app/data-entries/switch/switch-sample-1/switch-sample-1.component.html +++ /dev/null @@ -1,3 +0,0 @@ - - Simple switch - diff --git a/src/app/data-entries/switch/switch-sample-1/switch-sample-1.component.scss b/src/app/data-entries/switch/switch-sample-1/switch-sample-1.component.scss deleted file mode 100644 index 5bc4862429..0000000000 --- a/src/app/data-entries/switch/switch-sample-1/switch-sample-1.component.scss +++ /dev/null @@ -1,4 +0,0 @@ -:host { - display: block; - padding: 16px; -} diff --git a/src/app/data-entries/switch/switch-sample-1/switch-sample-1.component.ts b/src/app/data-entries/switch/switch-sample-1/switch-sample-1.component.ts deleted file mode 100644 index 906229df20..0000000000 --- a/src/app/data-entries/switch/switch-sample-1/switch-sample-1.component.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Component } from '@angular/core'; -import { IgxSwitchComponent } from 'igniteui-angular/switch'; - -@Component({ - selector: 'app-switch-sample-1', - styleUrls: ['./switch-sample-1.component.scss'], - templateUrl: './switch-sample-1.component.html', - imports: [IgxSwitchComponent] -}) -export class SwitchSample1Component { } diff --git a/src/app/data-entries/switch/switch-sample-2/switch-sample-2.component.html b/src/app/data-entries/switch/switch-sample-2/switch-sample-2.component.html deleted file mode 100644 index 82bb5ae9f7..0000000000 --- a/src/app/data-entries/switch/switch-sample-2/switch-sample-2.component.html +++ /dev/null @@ -1,6 +0,0 @@ -@for (setting of settings; track setting) { - - {{ setting.name }} - -} - diff --git a/src/app/data-entries/switch/switch-sample-2/switch-sample-2.component.scss b/src/app/data-entries/switch/switch-sample-2/switch-sample-2.component.scss deleted file mode 100644 index 7ccd0c810c..0000000000 --- a/src/app/data-entries/switch/switch-sample-2/switch-sample-2.component.scss +++ /dev/null @@ -1,9 +0,0 @@ -:host { - display: flex; - flex-flow: column nowrap; - padding: 16px; -} - -igx-switch { - margin-top: 24px; -} diff --git a/src/app/data-entries/switch/switch-sample-2/switch-sample-2.component.ts b/src/app/data-entries/switch/switch-sample-2/switch-sample-2.component.ts deleted file mode 100644 index 54c4e0d49a..0000000000 --- a/src/app/data-entries/switch/switch-sample-2/switch-sample-2.component.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Component } from '@angular/core'; - -import { IgxSwitchComponent } from 'igniteui-angular/switch'; - -@Component({ - selector: 'app-switch-sample-2', - styleUrls: ['./switch-sample-2.component.scss'], - templateUrl: './switch-sample-2.component.html', - imports: [IgxSwitchComponent] -}) -export class SwitchSample2Component { - public settings = [ - { name: 'WiFi', state: false}, - { name: 'Bluetooth', state: true}, - { name: 'Device visibility', state: false} - ]; -} diff --git a/src/app/data-entries/switch/switch-selected/switch-selected.component.html b/src/app/data-entries/switch/switch-selected/switch-selected.component.html new file mode 100644 index 0000000000..223f269045 --- /dev/null +++ b/src/app/data-entries/switch/switch-selected/switch-selected.component.html @@ -0,0 +1,17 @@ +
+ On + + Power + + + Power + + + Off + + Power + + + Power + +
diff --git a/src/app/data-entries/switch/switch-selected/switch-selected.component.scss b/src/app/data-entries/switch/switch-selected/switch-selected.component.scss new file mode 100644 index 0000000000..58683f9b6e --- /dev/null +++ b/src/app/data-entries/switch/switch-selected/switch-selected.component.scss @@ -0,0 +1,33 @@ +@use "igniteui-angular/theming" as *; +@use "sass:map"; +@use "../switch-bootstrap" as switch-bootstrap; + +@include switch-bootstrap.bootstrap-switch; + +:host { + display: flex; + place-content: center; + place-items: center; + padding: 16px; + + @include tokens(switch-theme($schema: map.get($light-bootstrap-schema, switch))); +} + +.states { + display: grid; + grid-template-columns: repeat(3, auto); + align-items: center; + gap: 32px; + transform: translateY(16px); + + .states__row { + text-align: end; + font: 500 14px / 24px "Aktiv Grotesk", sans-serif; + letter-spacing: 0.1px; + color: var(--ig-gray-600); + } + + .states__disabled { + margin-inline-start: 16px; + } +} diff --git a/src/app/data-entries/switch/switch-selected/switch-selected.component.ts b/src/app/data-entries/switch/switch-selected/switch-selected.component.ts new file mode 100644 index 0000000000..706b5c9295 --- /dev/null +++ b/src/app/data-entries/switch/switch-selected/switch-selected.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; +import { IgxSwitchComponent } from 'igniteui-angular/switch'; + +@Component({ + selector: 'app-switch-selected', + styleUrls: ['./switch-selected.component.scss'], + templateUrl: './switch-selected.component.html', + imports: [IgxSwitchComponent] +}) +export class SwitchSelectedComponent { } diff --git a/src/app/data-entries/switch/switch-styling/layout.scss b/src/app/data-entries/switch/switch-styling/layout.scss deleted file mode 100644 index 6e92f5d995..0000000000 --- a/src/app/data-entries/switch/switch-styling/layout.scss +++ /dev/null @@ -1,59 +0,0 @@ -@use "igniteui-angular/theming" as *; -@use 'sass:map'; - -:host { - ::ng-deep { - $_switch-schema: map.get($light-fluent-schema, switch); - @include tokens(switch-theme($schema: $_switch-schema)); - - // Note: This is not the standard approach for styling the component. - // We're using it here solely to mirror the UI5 sample. - - igx-switch:hover .igx-switch__thumb { - --border-hover-color: #fff; - } - - .igx-switch__composite { - width: rem(44px); - height: rem(20px); - padding-left: rem(2px); - } - - .igx-switch__composite-thumb { - width: rem(25px); - height: 1rem; - min-width: rem(25px); - transform: translateX(-0.5px); - } - - .igx-switch__thumb { - width: rem(25px); - height: 1rem; - min-width: rem(25px); - } - - .igx-switch--checked .igx-switch__composite .igx-switch__composite-thumb { - transform: translateX(0.85rem); - } - - .igx-switch--focused .igx-switch__composite::after { - border-radius: 1rem; - box-shadow: 0 0 0 rem(2px) var(--focus-outline-color); - } - } -} - -igx-switch { - margin-top: rem(24px); - width: max-content; -} - -igx-switch:hover { - --track-off-color: #637d97; -} - -.switch-wrapper { - display: flex; - flex-flow: column nowrap; - padding: 2rem; -} \ No newline at end of file diff --git a/src/app/data-entries/switch/switch-styling/switch-styling.component.html b/src/app/data-entries/switch/switch-styling/switch-styling.component.html index db4efd584c..9904fecca5 100644 --- a/src/app/data-entries/switch/switch-styling/switch-styling.component.html +++ b/src/app/data-entries/switch/switch-styling/switch-styling.component.html @@ -1,8 +1,22 @@ -
- @for (setting of settings; track setting) { - - {{ setting.name }} - - } -
+ + + + + Two-factor authentication + Extra sign-in verification + + + + + + + + + + Authenticator app + Security key + Backup codes + + + diff --git a/src/app/data-entries/switch/switch-styling/switch-styling.component.scss b/src/app/data-entries/switch/switch-styling/switch-styling.component.scss index 656327aab1..49bbd9abd2 100644 --- a/src/app/data-entries/switch/switch-styling/switch-styling.component.scss +++ b/src/app/data-entries/switch/switch-styling/switch-styling.component.scss @@ -1,40 +1,137 @@ -@use "layout.scss"; @use "igniteui-angular/theming" as *; +@use "sass:map"; +@use "../switch-bootstrap" as switch-bootstrap; -// CSS variables approach - -igx-switch { - --thumb-on-color: #e3f0ff; - --thumb-off-color: #fff; - --thumb-off-hover-color: #ededed; - --track-on-color: #0064d9; - --track-off-color: #788fa6; - --track-on-hover-color: #0058bf; - --border-radius-track: 1rem; - --focus-outline-color: #0032a5; - --border-on-color: transparent; - --border-color: transparent; - --border-on-hover-color: transparent; - --border-hover-color: transparent; -} - -// Sass theme approach - -// $custom-switch-theme: switch-theme( -// $thumb-on-color: #e3f0ff, -// $track-on-color: #0064d9, -// $track-on-hover-color: #0058bf, -// $thumb-off-color: #fff, -// $thumb-off-hover-color: #ededed, -// $track-off-color: #788fa6, -// $border-radius-track: 1rem, -// $focus-outline-color: #0032a5, -// $border-on-color: transparent, -// $border-on-hover-color: transparent, -// $border-color: transparent, -// $border-hover-color: transparent, -// ); - -// :host { -// @include tokens($custom-switch-theme); -// } +@include switch-bootstrap.bootstrap-switch; + +:host ::ng-deep igx-switch .igx-switch__thumb { + min-width: 10px; + transform: translateY(-1px); +} + +:host ::ng-deep igx-switch .igx-switch__ripple { + display: none; +} + +:host { + display: flex; + place-content: center; + place-items: center; + min-block-size: 100%; + padding: 1rem; + + @include tokens(switch-theme($schema: map.get($light-bootstrap-schema, switch))); + @include tokens(radio-theme($schema: map.get($light-bootstrap-schema, radio))); +} + +.security { + display: block; + inline-size: 100%; + max-inline-size: 348px; + background: var(--ig-surface-500); + border: rem(1px) solid var(--ig-gray-300); + border-radius: rem(16px); + box-shadow: 0 rem(1px) rem(3px) rgb(0 0 0 / 12%); + overflow: hidden; + + igx-expansion-panel-header { + display: block !important; + } + + ::ng-deep igx-expansion-panel-header > div { + padding: rem(12px) rem(16px) !important; + gap: rem(16px) !important; + } + + igx-expansion-panel-title { + flex: 1 1 auto; + min-inline-size: 0; + } + + igx-expansion-panel-icon { + flex: 0 0 auto; + transform: none; + margin-inline-start: 0; + } + + igx-expansion-panel-body { + display: block; + padding-inline-start: rem(5px); + border-block-start: rem(1px) solid var(--ig-gray-300); + } + + igx-switch { + inline-size: rem(43px); + block-size: rem(24px); + transform: translateX(rem(2px)); + } + + igx-radio-group { + display: flex; + flex-direction: column; + gap: rem(8px); + margin-inline-start: rem(10px); + } +} + +.option { + display: flex; + flex-direction: column; + gap: rem(2px); + text-align: start; + white-space: normal; + min-inline-size: 0; + + .option__label { + font: 600 #{rem(16px)} / #{rem(24px)} "Aktiv Grotesk", sans-serif; + letter-spacing: #{rem(0.15px)}; + color: var(--ig-gray-700); + } + + .option__hint { + font: 500 #{rem(14px)} / #{rem(24px)} "Aktiv Grotesk", sans-serif; + letter-spacing: #{rem(0.1px)}; + color: var(--ig-gray-600); + } +} + +igx-radio { + font: 600 #{rem(12px)} / #{rem(16px)} "Aktiv Grotesk", sans-serif; + letter-spacing: #{rem(0.15px)}; + color: var(--ig-primary-900); + + --fill-color: var(--ig-primary-500); + --fill-color-hover: var(--ig-primary-500); + --fill-hover-border-color: var(--ig-primary-500); +} + +:host ::ng-deep igx-radio.igx-radio--checked .igx-radio__composite::after { + background: transparent; + border-color: transparent; +} + +:host ::ng-deep igx-radio.igx-radio--checked .igx-radio__composite::before { + transform: none !important; +} + +:host ::ng-deep igx-radio .igx-radio__composite::before, +:host ::ng-deep igx-radio .igx-radio__composite::after { + width: 16px; + height: 16px; +} + +:host ::ng-deep igx-radio .igx-radio__label { + transform: translateY(-2px); +} + +:host ::ng-deep igx-radio .igx-radio__composite, +:host ::ng-deep igx-radio .igx-radio__composite::before, +:host ::ng-deep igx-radio .igx-radio__composite::after { + animation: none !important; + transition: none !important; +} + +:host ::ng-deep igx-radio .igx-radio__ripple { + opacity: 0; + pointer-events: none; +} diff --git a/src/app/data-entries/switch/switch-styling/switch-styling.component.ts b/src/app/data-entries/switch/switch-styling/switch-styling.component.ts index 31793317e2..a2ddb55ffb 100644 --- a/src/app/data-entries/switch/switch-styling/switch-styling.component.ts +++ b/src/app/data-entries/switch/switch-styling/switch-styling.component.ts @@ -1,16 +1,32 @@ import { Component } from '@angular/core'; +import { FormsModule } from '@angular/forms'; import { IgxSwitchComponent } from 'igniteui-angular/switch'; +import { IgxRadioComponent, IgxRadioGroupDirective, RadioGroupAlignment } from 'igniteui-angular/radio'; +import { + IgxExpansionPanelBodyComponent, + IgxExpansionPanelComponent, + IgxExpansionPanelHeaderComponent, + IgxExpansionPanelIconDirective, + IgxExpansionPanelTitleDirective +} from 'igniteui-angular/expansion-panel'; @Component({ selector: 'app-switch-styling', styleUrls: ['./switch-styling.component.scss'], templateUrl: './switch-styling.component.html', - imports: [IgxSwitchComponent] + imports: [ + IgxSwitchComponent, + IgxRadioComponent, + IgxRadioGroupDirective, + IgxExpansionPanelComponent, + IgxExpansionPanelHeaderComponent, + IgxExpansionPanelTitleDirective, + IgxExpansionPanelIconDirective, + IgxExpansionPanelBodyComponent, + FormsModule + ] }) export class SwitchStylingComponent { - public settings = [ - { name: 'WiFi', state: false }, - { name: 'Bluetooth', state: true }, - { name: 'Device visibility', state: false } - ]; + public alignment = RadioGroupAlignment.vertical; + public method = 'app'; } diff --git a/src/app/data-entries/switch/switch-tailwind-styling/layout.scss b/src/app/data-entries/switch/switch-tailwind-styling/layout.scss deleted file mode 100644 index 0988ab89bd..0000000000 --- a/src/app/data-entries/switch/switch-tailwind-styling/layout.scss +++ /dev/null @@ -1,9 +0,0 @@ -igx-switch { - margin-bottom: 24px; -} - -.switch-wrapper { - display: flex; - flex-flow: column nowrap; - padding: 16px; -} diff --git a/src/app/data-entries/switch/switch-tailwind-styling/switch-tailwind-styling.component.html b/src/app/data-entries/switch/switch-tailwind-styling/switch-tailwind-styling.component.html index 1a54d792c9..955b3e531b 100644 --- a/src/app/data-entries/switch/switch-tailwind-styling/switch-tailwind-styling.component.html +++ b/src/app/data-entries/switch/switch-tailwind-styling/switch-tailwind-styling.component.html @@ -1,7 +1,19 @@ -
- @for (setting of settings; track setting) { - - {{ setting.name }} - - } +
+
+ Dashboard + + + + Dark mode + + +
+
+
Revenue overview
+

+ $84,290 this month, up 12% from July.
+ Your top-performing channel is Direct, driving 41% of total revenue. +

+
diff --git a/src/app/data-entries/switch/switch-tailwind-styling/switch-tailwind-styling.component.scss b/src/app/data-entries/switch/switch-tailwind-styling/switch-tailwind-styling.component.scss index a60d456faa..e5b4f5cd37 100644 --- a/src/app/data-entries/switch/switch-tailwind-styling/switch-tailwind-styling.component.scss +++ b/src/app/data-entries/switch/switch-tailwind-styling/switch-tailwind-styling.component.scss @@ -1 +1,18 @@ -@use "layout.scss"; +@use "../switch-bootstrap" as switch-bootstrap; + +@include switch-bootstrap.bootstrap-switch; + +:host ::ng-deep igx-switch .igx-switch__thumb { + min-width: 10px; +} + +:host ::ng-deep igx-switch .igx-switch__ripple { + display: none; +} + +:host { + display: flex; + place-content: center; + place-items: center; + padding: 40px; +} diff --git a/src/app/data-entries/switch/switch-tailwind-styling/switch-tailwind-styling.component.ts b/src/app/data-entries/switch/switch-tailwind-styling/switch-tailwind-styling.component.ts index e49904ee31..f758af0066 100644 --- a/src/app/data-entries/switch/switch-tailwind-styling/switch-tailwind-styling.component.ts +++ b/src/app/data-entries/switch/switch-tailwind-styling/switch-tailwind-styling.component.ts @@ -1,17 +1,20 @@ -import { Component } from '@angular/core'; - +import { Component, inject } from '@angular/core'; import { IgxSwitchComponent } from 'igniteui-angular/switch'; +import { IgxIconComponent, IgxIconService } from 'igniteui-angular/icon'; + +const darkModeIcon = + ''; @Component({ selector: 'app-switch-tailwind-styling', styleUrls: ['./switch-tailwind-styling.component.scss'], templateUrl: './switch-tailwind-styling.component.html', - imports: [IgxSwitchComponent] + imports: [IgxSwitchComponent, IgxIconComponent] }) export class SwitchTailwindStylingComponent { - public settings = [ - { name: 'WiFi', state: false}, - { name: 'Bluetooth', state: true}, - { name: 'Device visibility', state: false} - ]; + public isDarkMode = true; + + constructor() { + inject(IgxIconService).addSvgIconFromText('dark_mode', darkModeIcon, 'material'); + } } From 4ea38cb4e1048652f5a876eb7002fb835fb32aa0 Mon Sep 17 00:00:00 2001 From: Adrian Petrov Date: Wed, 16 Sep 2026 02:05:27 +0300 Subject: [PATCH 07/22] feat(qr-code): add samples --- .../data-display/data-display-routes-data.ts | 5 ++- src/app/data-display/data-display.routes.ts | 18 ++++++++ .../qr-code-overview.component.html | 26 +++++++++++ .../qr-code-overview.component.scss | 31 +++++++++++++ .../qr-code-overview.component.ts | 23 ++++++++++ .../qr-code-styling.component.html | 8 ++++ .../qr-code-styling.component.scss | 36 +++++++++++++++ .../qr-code-styling.component.ts | 14 ++++++ .../qr-code-tailwind-styling.component.html | 44 +++++++++++++++++++ .../qr-code-tailwind-styling.component.scss | 16 +++++++ .../qr-code-tailwind-styling.component.ts | 13 ++++++ 11 files changed, 233 insertions(+), 1 deletion(-) create mode 100644 src/app/data-display/qr-code/qr-code-overview/qr-code-overview.component.html create mode 100644 src/app/data-display/qr-code/qr-code-overview/qr-code-overview.component.scss create mode 100644 src/app/data-display/qr-code/qr-code-overview/qr-code-overview.component.ts create mode 100644 src/app/data-display/qr-code/qr-code-styling/qr-code-styling.component.html create mode 100644 src/app/data-display/qr-code/qr-code-styling/qr-code-styling.component.scss create mode 100644 src/app/data-display/qr-code/qr-code-styling/qr-code-styling.component.ts create mode 100644 src/app/data-display/qr-code/qr-code-tailwind-styling/qr-code-tailwind-styling.component.html create mode 100644 src/app/data-display/qr-code/qr-code-tailwind-styling/qr-code-tailwind-styling.component.scss create mode 100644 src/app/data-display/qr-code/qr-code-tailwind-styling/qr-code-tailwind-styling.component.ts diff --git a/src/app/data-display/data-display-routes-data.ts b/src/app/data-display/data-display-routes-data.ts index 39ceef1ea1..f87d7bf808 100644 --- a/src/app/data-display/data-display-routes-data.ts +++ b/src/app/data-display/data-display-routes-data.ts @@ -43,5 +43,8 @@ export const dataDisplayRoutesData = { "mask-sample-5": { displayName: "Placeholder", parentName: "Mask" }, "text-highlight-1": { displayName: "Search within a single container", parentName: "Text Highlight" }, "text-highlight-2": { displayName: "Search within multiple containers", parentName: "Text Highlight" }, - "text-highlight-style": { displayName: "Text Highlight Style", parentName: "Text Highlight" } + "text-highlight-style": { displayName: "Text Highlight Style", parentName: "Text Highlight" }, + "qr-code-overview": { displayName: "Overview", parentName: "QR Code" }, + "qr-code-styling": { displayName: "QR Code Styling", parentName: "QR Code" }, + "qr-code-tailwind-styling": { displayName: "QR Code Tailwind Styling", parentName: "QR Code" } }; diff --git a/src/app/data-display/data-display.routes.ts b/src/app/data-display/data-display.routes.ts index de1538d481..4416a7e950 100644 --- a/src/app/data-display/data-display.routes.ts +++ b/src/app/data-display/data-display.routes.ts @@ -49,6 +49,9 @@ import { TextHighlightStyleComponent } from './text-highlight/text-highlight-sty import { MaterialIconsExtendedComponent} from './icon/material-icons-extended/material-icons-extended.component'; import { MaterialSymbolsComponent } from './icon/material-symbols/material-symbols.component'; +import { QrCodeOverviewComponent } from './qr-code/qr-code-overview/qr-code-overview.component'; +import { QrCodeStylingComponent } from './qr-code/qr-code-styling/qr-code-styling.component'; +import { QrCodeTailwindStylingComponent } from './qr-code/qr-code-tailwind-styling/qr-code-tailwind-styling.component'; import { dataDisplayRoutesData } from './data-display-routes-data'; import { Routes } from '@angular/router'; @@ -282,5 +285,20 @@ export const DataDisplayRoutes: Routes = [ component: MaterialIconsExtendedComponent, data: dataDisplayRoutesData['material-icons-extended'], path: 'material-icons-extended' + }, + { + component: QrCodeOverviewComponent, + data: dataDisplayRoutesData['qr-code-overview'], + path: 'qr-code-overview' + }, + { + component: QrCodeStylingComponent, + data: dataDisplayRoutesData['qr-code-styling'], + path: 'qr-code-styling' + }, + { + component: QrCodeTailwindStylingComponent, + data: dataDisplayRoutesData['qr-code-tailwind-styling'], + path: 'qr-code-tailwind-styling' } ]; diff --git a/src/app/data-display/qr-code/qr-code-overview/qr-code-overview.component.html b/src/app/data-display/qr-code/qr-code-overview/qr-code-overview.component.html new file mode 100644 index 0000000000..dafeba766d --- /dev/null +++ b/src/app/data-display/qr-code/qr-code-overview/qr-code-overview.component.html @@ -0,0 +1,26 @@ +
+ + Square + Circle + Rounded + + + + Small + Medium + Large + Extra large + + + Logo +
+ + diff --git a/src/app/data-display/qr-code/qr-code-overview/qr-code-overview.component.scss b/src/app/data-display/qr-code/qr-code-overview/qr-code-overview.component.scss new file mode 100644 index 0000000000..5794a7e78b --- /dev/null +++ b/src/app/data-display/qr-code/qr-code-overview/qr-code-overview.component.scss @@ -0,0 +1,31 @@ +@use 'igniteui-angular/theming' as *; + +@include core(); + +:host::ng-deep { + @include theme($palette: $light-bootstrap-palette, + $schema: $light-bootstrap-schema); +} + +:host { + display: flex; + flex-direction: column; + align-items: center; + gap: 2.5rem; + overflow-y: auto; +} + +.qr-controls { + display: flex; + align-items: center; + justify-content: center; + flex-wrap: wrap; + gap: 2.5rem; +} + +igx-radio-group { + display: flex; + align-items: center; + flex-wrap: wrap; + gap: 0.25rem; +} \ No newline at end of file diff --git a/src/app/data-display/qr-code/qr-code-overview/qr-code-overview.component.ts b/src/app/data-display/qr-code/qr-code-overview/qr-code-overview.component.ts new file mode 100644 index 0000000000..c5f3729bde --- /dev/null +++ b/src/app/data-display/qr-code/qr-code-overview/qr-code-overview.component.ts @@ -0,0 +1,23 @@ +import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { defineComponents, IgcQrCodeComponent } from 'igniteui-webcomponents'; +import { IgxRadioGroupDirective, IgxRadioComponent } from 'igniteui-angular/radio'; +import { IgxSwitchComponent } from 'igniteui-angular/switch'; + +defineComponents(IgcQrCodeComponent); + +@Component({ + selector: 'app-qr-code-overview', + templateUrl: './qr-code-overview.component.html', + styleUrls: ['./qr-code-overview.component.scss'], + schemas: [CUSTOM_ELEMENTS_SCHEMA], + imports: [FormsModule, IgxRadioGroupDirective, IgxRadioComponent, IgxSwitchComponent], +}) +export class QrCodeOverviewComponent { + public shape: 'square' | 'circle' | 'rounded' = 'square'; + public size = 120; + public showLogo = true; + + public readonly value = 'https://www.infragistics.com/products/ignite-ui-web-components'; + public readonly logoSrc = 'https://static.infragistics.com/marketing/Website/products/ignite-ui/shared/ignite-ui-logo-light-background-horizontal.svg'; +} diff --git a/src/app/data-display/qr-code/qr-code-styling/qr-code-styling.component.html b/src/app/data-display/qr-code/qr-code-styling/qr-code-styling.component.html new file mode 100644 index 0000000000..6b00fc2b65 --- /dev/null +++ b/src/app/data-display/qr-code/qr-code-styling/qr-code-styling.component.html @@ -0,0 +1,8 @@ + + + + diff --git a/src/app/data-display/qr-code/qr-code-styling/qr-code-styling.component.scss b/src/app/data-display/qr-code/qr-code-styling/qr-code-styling.component.scss new file mode 100644 index 0000000000..8db4d59102 --- /dev/null +++ b/src/app/data-display/qr-code/qr-code-styling/qr-code-styling.component.scss @@ -0,0 +1,36 @@ +:host { + display: flex; + align-items: flex-start; + gap: 3.75rem; + justify-content: center; + flex-direction: row; + flex-wrap: wrap; +} + +.qr-blue { + --ig-qr-code-background: #e3edfb; + --ig-qr-code-dark-color: #1361e0; +} + +.qr-orange { + --ig-qr-code-background: #fbe6e1; + --ig-qr-code-dark-color: #f0562b; +} + +.qr-green { + --ig-qr-code-background: #e5f7e6; + --ig-qr-code-dark-color: #3fa845; +} + +.qr-dark { + --ig-qr-code-background: #0b1b3a; + --ig-qr-code-dark-color: #ffffff; +} + +@media (width < 850px) { + :host { + flex-direction: column; + align-items: center; + justify-content: flex-start; + } +} \ No newline at end of file diff --git a/src/app/data-display/qr-code/qr-code-styling/qr-code-styling.component.ts b/src/app/data-display/qr-code/qr-code-styling/qr-code-styling.component.ts new file mode 100644 index 0000000000..c2165eaee4 --- /dev/null +++ b/src/app/data-display/qr-code/qr-code-styling/qr-code-styling.component.ts @@ -0,0 +1,14 @@ +import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { defineComponents, IgcQrCodeComponent } from 'igniteui-webcomponents'; + +defineComponents(IgcQrCodeComponent); + +@Component({ + selector: 'app-qr-code-styling', + templateUrl: './qr-code-styling.component.html', + styleUrls: ['./qr-code-styling.component.scss'], + schemas: [CUSTOM_ELEMENTS_SCHEMA], +}) +export class QrCodeStylingComponent { + public readonly value = 'https://www.infragistics.com/products/ignite-ui-web-components'; +} diff --git a/src/app/data-display/qr-code/qr-code-tailwind-styling/qr-code-tailwind-styling.component.html b/src/app/data-display/qr-code/qr-code-tailwind-styling/qr-code-tailwind-styling.component.html new file mode 100644 index 0000000000..64d2c32736 --- /dev/null +++ b/src/app/data-display/qr-code/qr-code-tailwind-styling/qr-code-tailwind-styling.component.html @@ -0,0 +1,44 @@ + + + + diff --git a/src/app/data-display/qr-code/qr-code-tailwind-styling/qr-code-tailwind-styling.component.scss b/src/app/data-display/qr-code/qr-code-tailwind-styling/qr-code-tailwind-styling.component.scss new file mode 100644 index 0000000000..a1cde3ae48 --- /dev/null +++ b/src/app/data-display/qr-code/qr-code-tailwind-styling/qr-code-tailwind-styling.component.scss @@ -0,0 +1,16 @@ +:host { + display: flex; + gap: 1.5rem; + padding: 1rem; + background: #111; + width: fit-content; + flex-direction: row; + flex-wrap: wrap; + margin-inline: auto; +} + +@media (width < 800px) { + :host { + flex-direction: column; + } +} \ No newline at end of file diff --git a/src/app/data-display/qr-code/qr-code-tailwind-styling/qr-code-tailwind-styling.component.ts b/src/app/data-display/qr-code/qr-code-tailwind-styling/qr-code-tailwind-styling.component.ts new file mode 100644 index 0000000000..171cb8654f --- /dev/null +++ b/src/app/data-display/qr-code/qr-code-tailwind-styling/qr-code-tailwind-styling.component.ts @@ -0,0 +1,13 @@ +import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { defineComponents, IgcQrCodeComponent } from 'igniteui-webcomponents'; + +defineComponents(IgcQrCodeComponent); + +@Component({ + selector: 'app-qr-code-tailwind-styling', + templateUrl: './qr-code-tailwind-styling.component.html', + styleUrls: ['./qr-code-tailwind-styling.component.scss'], + schemas: [CUSTOM_ELEMENTS_SCHEMA], + imports: [] +}) +export class QrCodeTailwindStylingComponent { } From 32329406a9826034e74539cffceed9fbada6675d Mon Sep 17 00:00:00 2001 From: Adrian Petrov Date: Thu, 17 Sep 2026 19:11:42 +0300 Subject: [PATCH 08/22] feat(qr-code): additional samples and fixes --- .../data-display/data-display-routes-data.ts | 4 ++ src/app/data-display/data-display.routes.ts | 25 ++++++++ .../qr-code-error-correction.component.html | 12 ++++ .../qr-code-error-correction.component.scss | 23 +++++++ .../qr-code-error-correction.component.ts | 13 ++++ .../qr-code-logo/qr-code-logo.component.html | 1 + .../qr-code-logo/qr-code-logo.component.scss | 4 ++ .../qr-code-logo/qr-code-logo.component.ts | 14 +++++ .../qr-code-overview.component.scss | 2 + .../qr-code-shapes.component.html | 12 ++++ .../qr-code-shapes.component.scss | 23 +++++++ .../qr-code-shapes.component.ts | 13 ++++ .../qr-code-size/qr-code-size.component.html | 12 ++++ .../qr-code-size/qr-code-size.component.scss | 23 +++++++ .../qr-code-size/qr-code-size.component.ts | 14 +++++ .../qr-code-styling.component.scss | 3 +- .../qr-code-tailwind-styling.component.html | 63 ++++++------------- .../qr-code-tailwind-styling.component.scss | 8 ++- 18 files changed, 223 insertions(+), 46 deletions(-) create mode 100644 src/app/data-display/qr-code/qr-code-error-correction/qr-code-error-correction.component.html create mode 100644 src/app/data-display/qr-code/qr-code-error-correction/qr-code-error-correction.component.scss create mode 100644 src/app/data-display/qr-code/qr-code-error-correction/qr-code-error-correction.component.ts create mode 100644 src/app/data-display/qr-code/qr-code-logo/qr-code-logo.component.html create mode 100644 src/app/data-display/qr-code/qr-code-logo/qr-code-logo.component.scss create mode 100644 src/app/data-display/qr-code/qr-code-logo/qr-code-logo.component.ts create mode 100644 src/app/data-display/qr-code/qr-code-shapes/qr-code-shapes.component.html create mode 100644 src/app/data-display/qr-code/qr-code-shapes/qr-code-shapes.component.scss create mode 100644 src/app/data-display/qr-code/qr-code-shapes/qr-code-shapes.component.ts create mode 100644 src/app/data-display/qr-code/qr-code-size/qr-code-size.component.html create mode 100644 src/app/data-display/qr-code/qr-code-size/qr-code-size.component.scss create mode 100644 src/app/data-display/qr-code/qr-code-size/qr-code-size.component.ts diff --git a/src/app/data-display/data-display-routes-data.ts b/src/app/data-display/data-display-routes-data.ts index f87d7bf808..6dce452ba3 100644 --- a/src/app/data-display/data-display-routes-data.ts +++ b/src/app/data-display/data-display-routes-data.ts @@ -45,6 +45,10 @@ export const dataDisplayRoutesData = { "text-highlight-2": { displayName: "Search within multiple containers", parentName: "Text Highlight" }, "text-highlight-style": { displayName: "Text Highlight Style", parentName: "Text Highlight" }, "qr-code-overview": { displayName: "Overview", parentName: "QR Code" }, + "qr-code-error-correction": { displayName: "QR Code Error Correction", parentName: "QR Code" }, + "qr-code-size": { displayName: "QR Code Size", parentName: "QR Code" }, + "qr-code-shapes": { displayName: "QR Code Shapes", parentName: "QR Code" }, + "qr-code-logo": { displayName: "QR Code Logo", parentName: "QR Code" }, "qr-code-styling": { displayName: "QR Code Styling", parentName: "QR Code" }, "qr-code-tailwind-styling": { displayName: "QR Code Tailwind Styling", parentName: "QR Code" } }; diff --git a/src/app/data-display/data-display.routes.ts b/src/app/data-display/data-display.routes.ts index 4416a7e950..16ede57200 100644 --- a/src/app/data-display/data-display.routes.ts +++ b/src/app/data-display/data-display.routes.ts @@ -54,6 +54,10 @@ import { QrCodeStylingComponent } from './qr-code/qr-code-styling/qr-code-stylin import { QrCodeTailwindStylingComponent } from './qr-code/qr-code-tailwind-styling/qr-code-tailwind-styling.component'; import { dataDisplayRoutesData } from './data-display-routes-data'; import { Routes } from '@angular/router'; +import { QrCodeErrorCorrectionComponent } from './qr-code/qr-code-error-correction/qr-code-error-correction.component'; +import { QrCodeSizeComponent } from './qr-code/qr-code-size/qr-code-size.component'; +import { QrCodeShapesComponent } from './qr-code/qr-code-shapes/qr-code-shapes.component'; +import { QrCodeLogoComponent } from './qr-code/qr-code-logo/qr-code-logo.component'; export const DataDisplayRoutes: Routes = [ { @@ -291,11 +295,32 @@ export const DataDisplayRoutes: Routes = [ data: dataDisplayRoutesData['qr-code-overview'], path: 'qr-code-overview' }, + { + component: QrCodeErrorCorrectionComponent, + data: dataDisplayRoutesData['qr-code-error-correction'], + path: 'qr-code-error-correction' + }, + { + component: QrCodeSizeComponent, + data: dataDisplayRoutesData['qr-code-size'], + path: 'qr-code-size' + }, { component: QrCodeStylingComponent, data: dataDisplayRoutesData['qr-code-styling'], path: 'qr-code-styling' }, + { + component: QrCodeShapesComponent, + data: dataDisplayRoutesData['qr-code-shapes'], + path: 'qr-code-shapes' + }, + { + component: QrCodeLogoComponent, + data: dataDisplayRoutesData['qr-code-logo'], + path: 'qr-code-logo' + }, + { component: QrCodeTailwindStylingComponent, data: dataDisplayRoutesData['qr-code-tailwind-styling'], diff --git a/src/app/data-display/qr-code/qr-code-error-correction/qr-code-error-correction.component.html b/src/app/data-display/qr-code/qr-code-error-correction/qr-code-error-correction.component.html new file mode 100644 index 0000000000..faa3fa0f9a --- /dev/null +++ b/src/app/data-display/qr-code/qr-code-error-correction/qr-code-error-correction.component.html @@ -0,0 +1,12 @@ +
+ > + error-level: L +
+
+ > + error-level: M +
+
+ > + error-level: Q +
diff --git a/src/app/data-display/qr-code/qr-code-error-correction/qr-code-error-correction.component.scss b/src/app/data-display/qr-code/qr-code-error-correction/qr-code-error-correction.component.scss new file mode 100644 index 0000000000..49f1e101cc --- /dev/null +++ b/src/app/data-display/qr-code/qr-code-error-correction/qr-code-error-correction.component.scss @@ -0,0 +1,23 @@ +:host { + display: flex; + align-items: flex-start; + gap: 3.75rem; + justify-content: center; + flex-direction: row; + overflow-y: auto; + height: 100%; +} + +div { + display: flex; + flex-direction: column; + align-items: center; +} + +@media (width < 850px) { + :host { + flex-direction: column; + align-items: center; + justify-content: flex-start; + } +} \ No newline at end of file diff --git a/src/app/data-display/qr-code/qr-code-error-correction/qr-code-error-correction.component.ts b/src/app/data-display/qr-code/qr-code-error-correction/qr-code-error-correction.component.ts new file mode 100644 index 0000000000..f6a9e2d59c --- /dev/null +++ b/src/app/data-display/qr-code/qr-code-error-correction/qr-code-error-correction.component.ts @@ -0,0 +1,13 @@ +import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { defineComponents, IgcQrCodeComponent } from 'igniteui-webcomponents'; + +defineComponents(IgcQrCodeComponent); + +@Component({ + selector: 'app-qr-code-error-correction', + templateUrl: './qr-code-error-correction.component.html', + styleUrls: ['./qr-code-error-correction.component.scss'], + schemas: [CUSTOM_ELEMENTS_SCHEMA], +}) +export class QrCodeErrorCorrectionComponent { +} diff --git a/src/app/data-display/qr-code/qr-code-logo/qr-code-logo.component.html b/src/app/data-display/qr-code/qr-code-logo/qr-code-logo.component.html new file mode 100644 index 0000000000..6cbe319214 --- /dev/null +++ b/src/app/data-display/qr-code/qr-code-logo/qr-code-logo.component.html @@ -0,0 +1 @@ + diff --git a/src/app/data-display/qr-code/qr-code-logo/qr-code-logo.component.scss b/src/app/data-display/qr-code/qr-code-logo/qr-code-logo.component.scss new file mode 100644 index 0000000000..f21bc9f9bb --- /dev/null +++ b/src/app/data-display/qr-code/qr-code-logo/qr-code-logo.component.scss @@ -0,0 +1,4 @@ +:host { + display: flex; + justify-content: center; +} diff --git a/src/app/data-display/qr-code/qr-code-logo/qr-code-logo.component.ts b/src/app/data-display/qr-code/qr-code-logo/qr-code-logo.component.ts new file mode 100644 index 0000000000..63ad259ef5 --- /dev/null +++ b/src/app/data-display/qr-code/qr-code-logo/qr-code-logo.component.ts @@ -0,0 +1,14 @@ +import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { defineComponents, IgcQrCodeComponent } from 'igniteui-webcomponents'; + +defineComponents(IgcQrCodeComponent); + +@Component({ + selector: 'app-qr-code-logo', + templateUrl: './qr-code-logo.component.html', + styleUrls: ['./qr-code-logo.component.scss'], + schemas: [CUSTOM_ELEMENTS_SCHEMA], +}) +export class QrCodeLogoComponent { + public readonly logoSrc = 'https://static.infragistics.com/marketing/Website/products/ignite-ui/shared/ignite-ui-logo-light-background-horizontal.svg'; +} diff --git a/src/app/data-display/qr-code/qr-code-overview/qr-code-overview.component.scss b/src/app/data-display/qr-code/qr-code-overview/qr-code-overview.component.scss index 5794a7e78b..67e4e79155 100644 --- a/src/app/data-display/qr-code/qr-code-overview/qr-code-overview.component.scss +++ b/src/app/data-display/qr-code/qr-code-overview/qr-code-overview.component.scss @@ -13,6 +13,7 @@ align-items: center; gap: 2.5rem; overflow-y: auto; + height: 100%; } .qr-controls { @@ -27,5 +28,6 @@ igx-radio-group { display: flex; align-items: center; flex-wrap: wrap; + width: fit-content; gap: 0.25rem; } \ No newline at end of file diff --git a/src/app/data-display/qr-code/qr-code-shapes/qr-code-shapes.component.html b/src/app/data-display/qr-code/qr-code-shapes/qr-code-shapes.component.html new file mode 100644 index 0000000000..bf7afd0619 --- /dev/null +++ b/src/app/data-display/qr-code/qr-code-shapes/qr-code-shapes.component.html @@ -0,0 +1,12 @@ +
+ + dot and square style: square +
+
+ > + dot and square style: circle +
+
+ > + dot and square style: rounded +
diff --git a/src/app/data-display/qr-code/qr-code-shapes/qr-code-shapes.component.scss b/src/app/data-display/qr-code/qr-code-shapes/qr-code-shapes.component.scss new file mode 100644 index 0000000000..49f1e101cc --- /dev/null +++ b/src/app/data-display/qr-code/qr-code-shapes/qr-code-shapes.component.scss @@ -0,0 +1,23 @@ +:host { + display: flex; + align-items: flex-start; + gap: 3.75rem; + justify-content: center; + flex-direction: row; + overflow-y: auto; + height: 100%; +} + +div { + display: flex; + flex-direction: column; + align-items: center; +} + +@media (width < 850px) { + :host { + flex-direction: column; + align-items: center; + justify-content: flex-start; + } +} \ No newline at end of file diff --git a/src/app/data-display/qr-code/qr-code-shapes/qr-code-shapes.component.ts b/src/app/data-display/qr-code/qr-code-shapes/qr-code-shapes.component.ts new file mode 100644 index 0000000000..42ac4674c7 --- /dev/null +++ b/src/app/data-display/qr-code/qr-code-shapes/qr-code-shapes.component.ts @@ -0,0 +1,13 @@ +import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { defineComponents, IgcQrCodeComponent } from 'igniteui-webcomponents'; + +defineComponents(IgcQrCodeComponent); + +@Component({ + selector: 'app-qr-code-shapes', + templateUrl: './qr-code-shapes.component.html', + styleUrls: ['./qr-code-shapes.component.scss'], + schemas: [CUSTOM_ELEMENTS_SCHEMA], +}) +export class QrCodeShapesComponent { +} diff --git a/src/app/data-display/qr-code/qr-code-size/qr-code-size.component.html b/src/app/data-display/qr-code/qr-code-size/qr-code-size.component.html new file mode 100644 index 0000000000..ec38f6605a --- /dev/null +++ b/src/app/data-display/qr-code/qr-code-size/qr-code-size.component.html @@ -0,0 +1,12 @@ +
+ > + size: 128px +
+
+ > + size: 192px +
+
+ > + size: 256px +
\ No newline at end of file diff --git a/src/app/data-display/qr-code/qr-code-size/qr-code-size.component.scss b/src/app/data-display/qr-code/qr-code-size/qr-code-size.component.scss new file mode 100644 index 0000000000..561d30de2e --- /dev/null +++ b/src/app/data-display/qr-code/qr-code-size/qr-code-size.component.scss @@ -0,0 +1,23 @@ +:host { + display: flex; + align-items: baseline; + gap: 3.75rem; + justify-content: center; + flex-direction: row; + overflow-y: auto; + height: 100%; +} + +div { + display: flex; + flex-direction: column; + align-items: center; +} + +@media (width < 850px) { + :host { + flex-direction: column; + align-items: center; + justify-content: flex-start; + } +} \ No newline at end of file diff --git a/src/app/data-display/qr-code/qr-code-size/qr-code-size.component.ts b/src/app/data-display/qr-code/qr-code-size/qr-code-size.component.ts new file mode 100644 index 0000000000..693fbe9693 --- /dev/null +++ b/src/app/data-display/qr-code/qr-code-size/qr-code-size.component.ts @@ -0,0 +1,14 @@ +import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { defineComponents, IgcQrCodeComponent } from 'igniteui-webcomponents'; + +defineComponents(IgcQrCodeComponent); + +@Component({ + selector: 'app-qr-code-size', + templateUrl: './qr-code-size.component.html', + styleUrls: ['./qr-code-size.component.scss'], + schemas: [CUSTOM_ELEMENTS_SCHEMA], +}) +export class QrCodeSizeComponent { + public readonly value = 'https://www.infragistics.com/products/ignite-ui-web-components'; +} diff --git a/src/app/data-display/qr-code/qr-code-styling/qr-code-styling.component.scss b/src/app/data-display/qr-code/qr-code-styling/qr-code-styling.component.scss index 8db4d59102..b748a92836 100644 --- a/src/app/data-display/qr-code/qr-code-styling/qr-code-styling.component.scss +++ b/src/app/data-display/qr-code/qr-code-styling/qr-code-styling.component.scss @@ -4,7 +4,8 @@ gap: 3.75rem; justify-content: center; flex-direction: row; - flex-wrap: wrap; + overflow-y: auto; + height: 100%; } .qr-blue { diff --git a/src/app/data-display/qr-code/qr-code-tailwind-styling/qr-code-tailwind-styling.component.html b/src/app/data-display/qr-code/qr-code-tailwind-styling/qr-code-tailwind-styling.component.html index 64d2c32736..7e10177508 100644 --- a/src/app/data-display/qr-code/qr-code-tailwind-styling/qr-code-tailwind-styling.component.html +++ b/src/app/data-display/qr-code/qr-code-tailwind-styling/qr-code-tailwind-styling.component.html @@ -1,44 +1,19 @@ - - - - +
+ + + + +
\ No newline at end of file diff --git a/src/app/data-display/qr-code/qr-code-tailwind-styling/qr-code-tailwind-styling.component.scss b/src/app/data-display/qr-code/qr-code-tailwind-styling/qr-code-tailwind-styling.component.scss index a1cde3ae48..53ba8128ab 100644 --- a/src/app/data-display/qr-code/qr-code-tailwind-styling/qr-code-tailwind-styling.component.scss +++ b/src/app/data-display/qr-code/qr-code-tailwind-styling/qr-code-tailwind-styling.component.scss @@ -1,4 +1,10 @@ :host { + display: block; + height: 100%; + overflow-y: auto; +} + +.container { display: flex; gap: 1.5rem; padding: 1rem; @@ -10,7 +16,7 @@ } @media (width < 800px) { - :host { + .container { flex-direction: column; } } \ No newline at end of file From 1fc0b09fae3500eef559eb3916a62c23a09d6b44 Mon Sep 17 00:00:00 2001 From: Viktor Kombov Date: Thu, 17 Sep 2026 21:54:33 +0300 Subject: [PATCH 09/22] feat(virtual-scroll): add virtual scroll component --- .../configs/VirtualScrollConfigGenerator.ts | 59 +++++++++++++ live-editing/generators/ConfigGenerators.ts | 2 + .../data-display/data-display-routes-data.ts | 6 ++ src/app/data-display/data-display.routes.ts | 36 ++++++++ .../data-display/virtual-scroll/employees.ts | 52 +++++++++++ .../virtual-scroll-horizontal.component.html | 21 +++++ .../virtual-scroll-horizontal.component.scss | 25 ++++++ .../virtual-scroll-horizontal.component.ts | 27 ++++++ ...tual-scroll-infinite-scroll.component.html | 22 +++++ ...tual-scroll-infinite-scroll.component.scss | 12 +++ ...irtual-scroll-infinite-scroll.component.ts | 62 +++++++++++++ .../virtual-scroll-overview.component.html | 13 +++ .../virtual-scroll-overview.component.scss | 8 ++ .../virtual-scroll-overview.component.ts | 34 ++++++++ .../virtual-scroll-paged-data.component.html | 24 ++++++ .../virtual-scroll-paged-data.component.scss | 12 +++ .../virtual-scroll-paged-data.component.ts | 86 +++++++++++++++++++ ...tual-scroll-scroll-to-index.component.html | 45 ++++++++++ ...tual-scroll-scroll-to-index.component.scss | 40 +++++++++ ...irtual-scroll-scroll-to-index.component.ts | 68 +++++++++++++++ ...irtual-scroll-variable-size.component.html | 16 ++++ ...irtual-scroll-variable-size.component.scss | 14 +++ .../virtual-scroll-variable-size.component.ts | 36 ++++++++ .../combo-remote/combo-remote.component.ts | 5 +- .../simple-combo-remote.component.ts | 5 +- 25 files changed, 726 insertions(+), 4 deletions(-) create mode 100644 live-editing/configs/VirtualScrollConfigGenerator.ts create mode 100644 src/app/data-display/virtual-scroll/employees.ts create mode 100644 src/app/data-display/virtual-scroll/virtual-scroll-horizontal/virtual-scroll-horizontal.component.html create mode 100644 src/app/data-display/virtual-scroll/virtual-scroll-horizontal/virtual-scroll-horizontal.component.scss create mode 100644 src/app/data-display/virtual-scroll/virtual-scroll-horizontal/virtual-scroll-horizontal.component.ts create mode 100644 src/app/data-display/virtual-scroll/virtual-scroll-infinite-scroll/virtual-scroll-infinite-scroll.component.html create mode 100644 src/app/data-display/virtual-scroll/virtual-scroll-infinite-scroll/virtual-scroll-infinite-scroll.component.scss create mode 100644 src/app/data-display/virtual-scroll/virtual-scroll-infinite-scroll/virtual-scroll-infinite-scroll.component.ts create mode 100644 src/app/data-display/virtual-scroll/virtual-scroll-overview/virtual-scroll-overview.component.html create mode 100644 src/app/data-display/virtual-scroll/virtual-scroll-overview/virtual-scroll-overview.component.scss create mode 100644 src/app/data-display/virtual-scroll/virtual-scroll-overview/virtual-scroll-overview.component.ts create mode 100644 src/app/data-display/virtual-scroll/virtual-scroll-paged-data/virtual-scroll-paged-data.component.html create mode 100644 src/app/data-display/virtual-scroll/virtual-scroll-paged-data/virtual-scroll-paged-data.component.scss create mode 100644 src/app/data-display/virtual-scroll/virtual-scroll-paged-data/virtual-scroll-paged-data.component.ts create mode 100644 src/app/data-display/virtual-scroll/virtual-scroll-scroll-to-index/virtual-scroll-scroll-to-index.component.html create mode 100644 src/app/data-display/virtual-scroll/virtual-scroll-scroll-to-index/virtual-scroll-scroll-to-index.component.scss create mode 100644 src/app/data-display/virtual-scroll/virtual-scroll-scroll-to-index/virtual-scroll-scroll-to-index.component.ts create mode 100644 src/app/data-display/virtual-scroll/virtual-scroll-variable-size/virtual-scroll-variable-size.component.html create mode 100644 src/app/data-display/virtual-scroll/virtual-scroll-variable-size/virtual-scroll-variable-size.component.scss create mode 100644 src/app/data-display/virtual-scroll/virtual-scroll-variable-size/virtual-scroll-variable-size.component.ts diff --git a/live-editing/configs/VirtualScrollConfigGenerator.ts b/live-editing/configs/VirtualScrollConfigGenerator.ts new file mode 100644 index 0000000000..2066fdebe7 --- /dev/null +++ b/live-editing/configs/VirtualScrollConfigGenerator.ts @@ -0,0 +1,59 @@ +import {Config, IConfigGenerator} from 'igniteui-live-editing' +import { BaseAppConfig } from './BaseConfig'; +export class VirtualScrollConfigGenerator implements IConfigGenerator { + + + public generateConfigs(): Config[] { + const configs = new Array(); + + // virtual scroll overview + configs.push(new Config({ + component: 'VirtualScrollOverviewComponent', + additionalFiles: ["/src/app/data-display/virtual-scroll/employees.ts"], + appConfig: BaseAppConfig, + shortenComponentPathBy: "/data-display/" + })); + + // virtual scroll variable item size + configs.push(new Config({ + component: 'VirtualScrollVariableSizeComponent', + additionalFiles: ["/src/app/data-display/virtual-scroll/employees.ts"], + appConfig: BaseAppConfig, + shortenComponentPathBy: "/data-display/" + })); + + // virtual scroll horizontal + configs.push(new Config({ + component: 'VirtualScrollHorizontalComponent', + additionalFiles: ["/src/app/data-display/virtual-scroll/employees.ts"], + appConfig: BaseAppConfig, + shortenComponentPathBy: "/data-display/" + })); + + // virtual scroll scroll to index + configs.push(new Config({ + component: 'VirtualScrollScrollToIndexComponent', + additionalFiles: ["/src/app/data-display/virtual-scroll/employees.ts"], + appConfig: BaseAppConfig, + shortenComponentPathBy: "/data-display/" + })); + + // virtual scroll infinite scroll + configs.push(new Config({ + component: 'VirtualScrollInfiniteScrollComponent', + additionalFiles: ["/src/app/data-display/virtual-scroll/employees.ts"], + appConfig: BaseAppConfig, + shortenComponentPathBy: "/data-display/" + })); + + // virtual scroll paged data + configs.push(new Config({ + component: 'VirtualScrollPagedDataComponent', + additionalFiles: ["/src/app/data-display/virtual-scroll/employees.ts"], + appConfig: BaseAppConfig, + shortenComponentPathBy: "/data-display/" + })); + + return configs; + } +} diff --git a/live-editing/generators/ConfigGenerators.ts b/live-editing/generators/ConfigGenerators.ts index 25c0c09525..c70e815500 100644 --- a/live-editing/generators/ConfigGenerators.ts +++ b/live-editing/generators/ConfigGenerators.ts @@ -26,6 +26,7 @@ import { ExportCsvConfigGenerator } from '../configs/ExportCsvConfigGenerator'; import { ExportExcelConfigGenerator } from '../configs/ExportExcelConfigGenerator'; import { ExportPdfConfigGenerator } from '../configs/ExportPdfConfigGenerator'; import { ForConfigGenerator } from '../configs/ForConfigGenerator'; +import { VirtualScrollConfigGenerator } from '../configs/VirtualScrollConfigGenerator'; import { GridConfigGenerator } from '../configs/GridConfigGenerator'; import { HierarchicalGridConfigGenerator } from '../configs/HierarchicalGridConfigGenerator'; import { IconConfigGenerator } from '../configs/IconConfigGenerator'; @@ -128,6 +129,7 @@ export const CONFIG_GENERATORS = CircularProgressbarConfigGenerator, DividerConfigGenerator, ForConfigGenerator, + VirtualScrollConfigGenerator, IconConfigGenerator, OverlayConfigGenerator, LinearProgressbarConfigGenerator, diff --git a/src/app/data-display/data-display-routes-data.ts b/src/app/data-display/data-display-routes-data.ts index 39ceef1ea1..d87443d0a9 100644 --- a/src/app/data-display/data-display-routes-data.ts +++ b/src/app/data-display/data-display-routes-data.ts @@ -31,6 +31,12 @@ export const dataDisplayRoutesData = { "material-icons-extended": { displayName: "Material Icons Extended", parentName: "Icon" }, "igx-for-sample-1": { displayName: "List with igxFor directive", parentName: "For" }, "igx-for-sample-2": { displayName: "IgxFor Horizontal virtualization", parentName: "For" }, + "virtual-scroll-overview": { displayName: "Virtual Scroll Overview", parentName: "Virtual Scroll" }, + "virtual-scroll-variable-size": { displayName: "Virtual Scroll Variable Item Size", parentName: "Virtual Scroll" }, + "virtual-scroll-horizontal": { displayName: "Virtual Scroll Horizontal", parentName: "Virtual Scroll" }, + "virtual-scroll-scroll-to-index": { displayName: "Virtual Scroll Scroll to Index", parentName: "Virtual Scroll" }, + "virtual-scroll-infinite-scroll": { displayName: "Virtual Scroll Infinite Scroll", parentName: "Virtual Scroll" }, + "virtual-scroll-paged-data": { displayName: "Virtual Scroll Paged Data", parentName: "Virtual Scroll" }, "linear-dynamic-sample": { displayName: "Dynamic Linear Progressbar", parentName: "Linear Progressbar" }, "linear-progressbar": { displayName: "Simple Linear Progressbar", parentName: "Linear Progressbar" }, "linear-progressbar-sample-1": { displayName: "Linear Progressbar Types", parentName: "Linear Progressbar" }, diff --git a/src/app/data-display/data-display.routes.ts b/src/app/data-display/data-display.routes.ts index de1538d481..e4acd8e72e 100644 --- a/src/app/data-display/data-display.routes.ts +++ b/src/app/data-display/data-display.routes.ts @@ -30,6 +30,12 @@ import { IconServiceSampleComponent } from './icon/icon-service-sample/icon-serv import { SvgIconSampleComponent } from './icon/svg-icon-sample/svg-icon-sample.component'; import { IgxForComponent } from './igxFor/igxFor.component'; import { IgxForHorizontalComponent } from './igxFor/igxFor-horizontal-sample/igxFor-horizontal.component'; +import { VirtualScrollOverviewComponent } from './virtual-scroll/virtual-scroll-overview/virtual-scroll-overview.component'; +import { VirtualScrollVariableSizeComponent } from './virtual-scroll/virtual-scroll-variable-size/virtual-scroll-variable-size.component'; +import { VirtualScrollHorizontalComponent } from './virtual-scroll/virtual-scroll-horizontal/virtual-scroll-horizontal.component'; +import { VirtualScrollScrollToIndexComponent } from './virtual-scroll/virtual-scroll-scroll-to-index/virtual-scroll-scroll-to-index.component'; +import { VirtualScrollInfiniteScrollComponent } from './virtual-scroll/virtual-scroll-infinite-scroll/virtual-scroll-infinite-scroll.component'; +import { VirtualScrollPagedDataComponent } from './virtual-scroll/virtual-scroll-paged-data/virtual-scroll-paged-data.component'; import { LinearDynamicSampleComponent } from './linear-progressbar/linear-dynamic-sample/linear-dynamic-sample.component'; import { LinearProgressbarSample1Component } from './linear-progressbar/linear-progressbar-sample-1/linear-progressbar-sample-1.component'; import { LinearProgressbarSample2Component } from './linear-progressbar/linear-progressbar-sample-2/linear-progressbar-sample-2.component'; @@ -183,6 +189,36 @@ export const DataDisplayRoutes: Routes = [ data: dataDisplayRoutesData['igx-for-sample-2'], path: 'igx-for-sample-2' }, + { + component: VirtualScrollOverviewComponent, + data: dataDisplayRoutesData['virtual-scroll-overview'], + path: 'virtual-scroll-overview' + }, + { + component: VirtualScrollVariableSizeComponent, + data: dataDisplayRoutesData['virtual-scroll-variable-size'], + path: 'virtual-scroll-variable-size' + }, + { + component: VirtualScrollHorizontalComponent, + data: dataDisplayRoutesData['virtual-scroll-horizontal'], + path: 'virtual-scroll-horizontal' + }, + { + component: VirtualScrollScrollToIndexComponent, + data: dataDisplayRoutesData['virtual-scroll-scroll-to-index'], + path: 'virtual-scroll-scroll-to-index' + }, + { + component: VirtualScrollInfiniteScrollComponent, + data: dataDisplayRoutesData['virtual-scroll-infinite-scroll'], + path: 'virtual-scroll-infinite-scroll' + }, + { + component: VirtualScrollPagedDataComponent, + data: dataDisplayRoutesData['virtual-scroll-paged-data'], + path: 'virtual-scroll-paged-data' + }, { component: LinearDynamicSampleComponent, data: dataDisplayRoutesData['linear-dynamic-sample'], diff --git a/src/app/data-display/virtual-scroll/employees.ts b/src/app/data-display/virtual-scroll/employees.ts new file mode 100644 index 0000000000..99d94b972f --- /dev/null +++ b/src/app/data-display/virtual-scroll/employees.ts @@ -0,0 +1,52 @@ +export type DepartmentVariant = 'primary' | 'info' | 'success' | 'warning' | 'danger'; + +export interface Employee { + id: number; + name: string; + initials: string; + email: string; + department: string; + variant: DepartmentVariant; + bio: string | null; +} + +const DEPARTMENTS = ['Engineering', 'Design', 'Marketing', 'Sales', 'HR', 'Finance', 'Legal', 'Operations']; +const VARIANTS: DepartmentVariant[] = ['primary', 'info', 'success', 'warning', 'danger']; + +const FIRST_NAMES = [ + 'Alice', 'Bob', 'Carol', 'David', 'Eve', 'Frank', 'Grace', 'Henry', + 'Iris', 'Jack', 'Karen', 'Leo', 'Mia', 'Noah', 'Olivia', 'Paul' +]; + +const LAST_NAMES = [ + 'Smith', 'Johnson', 'Williams', 'Brown', 'Jones', 'Garcia', 'Miller', + 'Davis', 'Wilson', 'Moore', 'Taylor', 'Anderson', 'Thomas', 'Jackson' +]; + +const BIOS = [ + 'Leads a cross-functional team across three time zones and owns the quarterly delivery plan.', + 'Specializes in scalable service architecture.', + 'Passionate about accessible, pixel-perfect user interfaces and design systems that scale across products.', + 'Drives product strategy and stakeholder alignment.', + 'Champions data-driven decision making, runs the weekly metrics review and mentors new analysts.' +]; + +export function createEmployee(index: number): Employee { + const first = FIRST_NAMES[index % FIRST_NAMES.length]; + const last = LAST_NAMES[Math.floor(index / FIRST_NAMES.length) % LAST_NAMES.length]; + const departmentIndex = index % DEPARTMENTS.length; + + return { + id: index + 1, + name: `${first} ${last}`, + initials: `${first[0]}${last[0]}`, + email: `${first.toLowerCase()}.${last.toLowerCase()}${index + 1}@example.com`, + department: DEPARTMENTS[departmentIndex], + variant: VARIANTS[departmentIndex % VARIANTS.length], + bio: index % 3 === 0 ? BIOS[index % BIOS.length] : null + }; +} + +export function generateEmployees(count: number, startIndex = 0): Employee[] { + return Array.from({ length: count }, (_, i) => createEmployee(startIndex + i)); +} diff --git a/src/app/data-display/virtual-scroll/virtual-scroll-horizontal/virtual-scroll-horizontal.component.html b/src/app/data-display/virtual-scroll/virtual-scroll-horizontal/virtual-scroll-horizontal.component.html new file mode 100644 index 0000000000..a0d68475e5 --- /dev/null +++ b/src/app/data-display/virtual-scroll/virtual-scroll-horizontal/virtual-scroll-horizontal.component.html @@ -0,0 +1,21 @@ + + +
+ + + +

{{ employee.name }}

+
{{ employee.bio ? employee.email : '#' + employee.id }}
+
+ + {{ employee.department }} + +
+
+
+
diff --git a/src/app/data-display/virtual-scroll/virtual-scroll-horizontal/virtual-scroll-horizontal.component.scss b/src/app/data-display/virtual-scroll/virtual-scroll-horizontal/virtual-scroll-horizontal.component.scss new file mode 100644 index 0000000000..e2df6834ef --- /dev/null +++ b/src/app/data-display/virtual-scroll/virtual-scroll-horizontal/virtual-scroll-horizontal.component.scss @@ -0,0 +1,25 @@ +:host { + display: block; + padding: 16px; +} + +.cards { + block-size: 200px; +} + +// Items are measured by their border box, so the spacing between cards is +// padding on the item wrapper rather than a margin. +.cards__item { + box-sizing: border-box; + inline-size: 220px; + block-size: 100%; + padding: 8px; + + igx-card { + block-size: 100%; + } +} + +.cards__item--wide { + inline-size: 320px; +} diff --git a/src/app/data-display/virtual-scroll/virtual-scroll-horizontal/virtual-scroll-horizontal.component.ts b/src/app/data-display/virtual-scroll/virtual-scroll-horizontal/virtual-scroll-horizontal.component.ts new file mode 100644 index 0000000000..62d3bc5101 --- /dev/null +++ b/src/app/data-display/virtual-scroll/virtual-scroll-horizontal/virtual-scroll-horizontal.component.ts @@ -0,0 +1,27 @@ +import { Component } from '@angular/core'; +import { IgxAvatarComponent } from 'igniteui-angular/avatar'; +import { IgxCardComponent, IgxCardContentDirective, IgxCardHeaderComponent, IgxCardHeaderSubtitleDirective, IgxCardHeaderTitleDirective, IgxCardThumbnailDirective } from 'igniteui-angular/card'; +import { IgxChipComponent } from 'igniteui-angular/chips'; +import { IgxVirtualItemDirective, IgxVirtualScrollComponent } from 'igniteui-angular/virtual-scroll'; +import { Employee, generateEmployees } from '../employees'; + +@Component({ + selector: 'app-virtual-scroll-horizontal', + styleUrls: ['./virtual-scroll-horizontal.component.scss'], + templateUrl: './virtual-scroll-horizontal.component.html', + imports: [ + IgxVirtualScrollComponent, + IgxVirtualItemDirective, + IgxCardComponent, + IgxCardHeaderComponent, + IgxCardThumbnailDirective, + IgxCardHeaderTitleDirective, + IgxCardHeaderSubtitleDirective, + IgxCardContentDirective, + IgxAvatarComponent, + IgxChipComponent + ] +}) +export class VirtualScrollHorizontalComponent { + public readonly employees: Employee[] = generateEmployees(10_000); +} diff --git a/src/app/data-display/virtual-scroll/virtual-scroll-infinite-scroll/virtual-scroll-infinite-scroll.component.html b/src/app/data-display/virtual-scroll/virtual-scroll-infinite-scroll/virtual-scroll-infinite-scroll.component.html new file mode 100644 index 0000000000..de5015fa56 --- /dev/null +++ b/src/app/data-display/virtual-scroll/virtual-scroll-infinite-scroll/virtual-scroll-infinite-scroll.component.html @@ -0,0 +1,22 @@ + + Loaded {{ employees().length }} of {{ totalCount }} employees + + + + + #{{ employee.id }} {{ employee.name }} + {{ employee.email }} + {{ employee.department }} + + + +
+ @if (loading()) { + + } +
+
diff --git a/src/app/data-display/virtual-scroll/virtual-scroll-infinite-scroll/virtual-scroll-infinite-scroll.component.scss b/src/app/data-display/virtual-scroll/virtual-scroll-infinite-scroll/virtual-scroll-infinite-scroll.component.scss new file mode 100644 index 0000000000..85cd472c6e --- /dev/null +++ b/src/app/data-display/virtual-scroll/virtual-scroll-infinite-scroll/virtual-scroll-infinite-scroll.component.scss @@ -0,0 +1,12 @@ +:host { + display: block; + padding: 16px; +} + +.employees__viewport { + block-size: 440px; +} + +.employees__status { + block-size: 4px; +} diff --git a/src/app/data-display/virtual-scroll/virtual-scroll-infinite-scroll/virtual-scroll-infinite-scroll.component.ts b/src/app/data-display/virtual-scroll/virtual-scroll-infinite-scroll/virtual-scroll-infinite-scroll.component.ts new file mode 100644 index 0000000000..056dd1ef17 --- /dev/null +++ b/src/app/data-display/virtual-scroll/virtual-scroll-infinite-scroll/virtual-scroll-infinite-scroll.component.ts @@ -0,0 +1,62 @@ +import { Component, signal } from '@angular/core'; +import { IgxAvatarComponent } from 'igniteui-angular/avatar'; +import { IgxChipComponent } from 'igniteui-angular/chips'; +import { + IgxListActionDirective, + IgxListComponent, + IgxListItemComponent, + IgxListLineSubTitleDirective, + IgxListLineTitleDirective, + IgxListThumbnailDirective +} from 'igniteui-angular/list'; +import { IgxLinearProgressBarComponent } from 'igniteui-angular/progressbar'; +import { IgxVirtualItemDirective, IgxVirtualScrollComponent, VirtualScrollDataRequest } from 'igniteui-angular/virtual-scroll'; +import { Employee, generateEmployees } from '../employees'; + +/** The size of the whole remote collection. */ +const TOTAL_COUNT = 1_000; +const PAGE_SIZE = 50; + +@Component({ + selector: 'app-virtual-scroll-infinite-scroll', + styleUrls: ['./virtual-scroll-infinite-scroll.component.scss'], + templateUrl: './virtual-scroll-infinite-scroll.component.html', + imports: [ + IgxVirtualScrollComponent, + IgxVirtualItemDirective, + IgxListComponent, + IgxListItemComponent, + IgxListThumbnailDirective, + IgxListLineTitleDirective, + IgxListLineSubTitleDirective, + IgxListActionDirective, + IgxAvatarComponent, + IgxChipComponent, + IgxLinearProgressBarComponent + ] +}) +export class VirtualScrollInfiniteScrollComponent { + public readonly totalCount = TOTAL_COUNT; + public readonly employees = signal(generateEmployees(PAGE_SIZE)); + public readonly loading = signal(false); + + /** + * `dataRequest` is emitted when the rendered window nears the end of `data`. + * Only one request is emitted at a time: the next one follows the next `data` change. + */ + public loadMore(request: VirtualScrollDataRequest): void { + if (this.loading() || request.startIndex >= TOTAL_COUNT) { + return; + } + + this.loading.set(true); + const count = Math.min(Math.max(request.count, PAGE_SIZE), TOTAL_COUNT - request.startIndex); + + // Simulates a request to a remote service. + setTimeout(() => { + // Assign a new array: `data` is compared by reference. + this.employees.update(current => [...current, ...generateEmployees(count, request.startIndex)]); + this.loading.set(false); + }, 800); + } +} diff --git a/src/app/data-display/virtual-scroll/virtual-scroll-overview/virtual-scroll-overview.component.html b/src/app/data-display/virtual-scroll/virtual-scroll-overview/virtual-scroll-overview.component.html new file mode 100644 index 0000000000..e7d3861d4d --- /dev/null +++ b/src/app/data-display/virtual-scroll/virtual-scroll-overview/virtual-scroll-overview.component.html @@ -0,0 +1,13 @@ + + Employees ({{ employees.length }}) + + + + + {{ employee.name }} + {{ employee.email }} + {{ employee.department }} + + + + diff --git a/src/app/data-display/virtual-scroll/virtual-scroll-overview/virtual-scroll-overview.component.scss b/src/app/data-display/virtual-scroll/virtual-scroll-overview/virtual-scroll-overview.component.scss new file mode 100644 index 0000000000..93ada4e191 --- /dev/null +++ b/src/app/data-display/virtual-scroll/virtual-scroll-overview/virtual-scroll-overview.component.scss @@ -0,0 +1,8 @@ +:host { + display: block; + padding: 16px; +} + +.employees__viewport { + block-size: 480px; +} diff --git a/src/app/data-display/virtual-scroll/virtual-scroll-overview/virtual-scroll-overview.component.ts b/src/app/data-display/virtual-scroll/virtual-scroll-overview/virtual-scroll-overview.component.ts new file mode 100644 index 0000000000..7d3d04cbac --- /dev/null +++ b/src/app/data-display/virtual-scroll/virtual-scroll-overview/virtual-scroll-overview.component.ts @@ -0,0 +1,34 @@ +import { Component } from '@angular/core'; +import { IgxAvatarComponent } from 'igniteui-angular/avatar'; +import { IgxChipComponent } from 'igniteui-angular/chips'; +import { + IgxListActionDirective, + IgxListComponent, + IgxListItemComponent, + IgxListLineSubTitleDirective, + IgxListLineTitleDirective, + IgxListThumbnailDirective +} from 'igniteui-angular/list'; +import { IgxVirtualItemDirective, IgxVirtualScrollComponent } from 'igniteui-angular/virtual-scroll'; +import { Employee, generateEmployees } from '../employees'; + +@Component({ + selector: 'app-virtual-scroll-overview', + styleUrls: ['./virtual-scroll-overview.component.scss'], + templateUrl: './virtual-scroll-overview.component.html', + imports: [ + IgxVirtualScrollComponent, + IgxVirtualItemDirective, + IgxListComponent, + IgxListItemComponent, + IgxListThumbnailDirective, + IgxListLineTitleDirective, + IgxListLineSubTitleDirective, + IgxListActionDirective, + IgxAvatarComponent, + IgxChipComponent + ] +}) +export class VirtualScrollOverviewComponent { + public readonly employees: Employee[] = generateEmployees(100_000); +} diff --git a/src/app/data-display/virtual-scroll/virtual-scroll-paged-data/virtual-scroll-paged-data.component.html b/src/app/data-display/virtual-scroll/virtual-scroll-paged-data/virtual-scroll-paged-data.component.html new file mode 100644 index 0000000000..987b68dd2c --- /dev/null +++ b/src/app/data-display/virtual-scroll/virtual-scroll-paged-data/virtual-scroll-paged-data.component.html @@ -0,0 +1,24 @@ + + + Records {{ page().startIndex + 1 }}–{{ page().startIndex + page().items.length }} of {{ page().totalCount }} in memory + + + + + + #{{ employee.id }} {{ employee.name }} + {{ employee.email }} + {{ employee.department }} + + + +
+ @if (loading()) { + + } +
+
diff --git a/src/app/data-display/virtual-scroll/virtual-scroll-paged-data/virtual-scroll-paged-data.component.scss b/src/app/data-display/virtual-scroll/virtual-scroll-paged-data/virtual-scroll-paged-data.component.scss new file mode 100644 index 0000000000..85cd472c6e --- /dev/null +++ b/src/app/data-display/virtual-scroll/virtual-scroll-paged-data/virtual-scroll-paged-data.component.scss @@ -0,0 +1,12 @@ +:host { + display: block; + padding: 16px; +} + +.employees__viewport { + block-size: 440px; +} + +.employees__status { + block-size: 4px; +} diff --git a/src/app/data-display/virtual-scroll/virtual-scroll-paged-data/virtual-scroll-paged-data.component.ts b/src/app/data-display/virtual-scroll/virtual-scroll-paged-data/virtual-scroll-paged-data.component.ts new file mode 100644 index 0000000000..cf4e7f1d47 --- /dev/null +++ b/src/app/data-display/virtual-scroll/virtual-scroll-paged-data/virtual-scroll-paged-data.component.ts @@ -0,0 +1,86 @@ +import { Component, signal } from '@angular/core'; +import { IgxAvatarComponent } from 'igniteui-angular/avatar'; +import { IgxChipComponent } from 'igniteui-angular/chips'; +import { + IgxListActionDirective, + IgxListComponent, + IgxListItemComponent, + IgxListLineSubTitleDirective, + IgxListLineTitleDirective, + IgxListThumbnailDirective +} from 'igniteui-angular/list'; +import { IgxLinearProgressBarComponent } from 'igniteui-angular/progressbar'; +import { IgxVirtualItemDirective, IgxVirtualScrollComponent, VirtualDataWindow, VirtualScrollState } from 'igniteui-angular/virtual-scroll'; +import { Employee, generateEmployees } from '../employees'; + +/** The size of the whole remote collection. */ +const TOTAL_COUNT = 100_000; +/** Extra records requested on each side of the range the viewport wants. */ +const BUFFER = 30; + +@Component({ + selector: 'app-virtual-scroll-paged-data', + styleUrls: ['./virtual-scroll-paged-data.component.scss'], + templateUrl: './virtual-scroll-paged-data.component.html', + imports: [ + IgxVirtualScrollComponent, + IgxVirtualItemDirective, + IgxListComponent, + IgxListItemComponent, + IgxListThumbnailDirective, + IgxListLineTitleDirective, + IgxListLineSubTitleDirective, + IgxListActionDirective, + IgxAvatarComponent, + IgxChipComponent, + IgxLinearProgressBarComponent + ] +}) +export class VirtualScrollPagedDataComponent { + /** Only this page is in memory, while the scrollbar spans `totalCount` records. */ + public readonly page = signal>({ + items: generateEmployees(2 * BUFFER), + startIndex: 0, + totalCount: TOTAL_COUNT + }); + public readonly loading = signal(false); + + private wantedRange: VirtualScrollState | null = null; + + /** `stateChange` reports the range the viewport wants, which the next page is loaded from. */ + public onStateChange(state: VirtualScrollState): void { + this.wantedRange = state; + this.loadPageIfNeeded(); + } + + private loadPageIfNeeded(): void { + const wanted = this.wantedRange; + if (!wanted || wanted.endIndex < wanted.startIndex || this.loading()) { + return; + } + + const page = this.page(); + const pageEnd = page.startIndex + page.items.length - 1; + if (wanted.startIndex >= page.startIndex && wanted.endIndex <= pageEnd) { + return; + } + + const startIndex = Math.max(0, wanted.startIndex - BUFFER); + const endIndex = Math.min(TOTAL_COUNT - 1, wanted.endIndex + BUFFER); + + this.loading.set(true); + this.fetchPage(startIndex, endIndex - startIndex + 1).then(({ items, totalCount }) => { + this.page.set({ items, startIndex, totalCount }); + this.loading.set(false); + // The user may have scrolled further while the request was in flight. + this.loadPageIfNeeded(); + }); + } + + /** Simulates a request to a remote service that supports skip/take paging. */ + private fetchPage(skip: number, take: number): Promise<{ items: Employee[]; totalCount: number }> { + return new Promise(resolve => { + setTimeout(() => resolve({ items: generateEmployees(take, skip), totalCount: TOTAL_COUNT }), 300); + }); + } +} diff --git a/src/app/data-display/virtual-scroll/virtual-scroll-scroll-to-index/virtual-scroll-scroll-to-index.component.html b/src/app/data-display/virtual-scroll/virtual-scroll-scroll-to-index/virtual-scroll-scroll-to-index.component.html new file mode 100644 index 0000000000..83646da7da --- /dev/null +++ b/src/app/data-display/virtual-scroll/virtual-scroll-scroll-to-index/virtual-scroll-scroll-to-index.component.html @@ -0,0 +1,45 @@ +
+ + + + + + + @for (value of alignments; track value) { + {{ value }} + } + + +
+ + + + + +
+
+ + + Employees ({{ employees.length }}) + + + + + #{{ index }} {{ employee.name }} + {{ employee.email }} + {{ employee.department }} + + + + diff --git a/src/app/data-display/virtual-scroll/virtual-scroll-scroll-to-index/virtual-scroll-scroll-to-index.component.scss b/src/app/data-display/virtual-scroll/virtual-scroll-scroll-to-index/virtual-scroll-scroll-to-index.component.scss new file mode 100644 index 0000000000..efa47683dd --- /dev/null +++ b/src/app/data-display/virtual-scroll/virtual-scroll-scroll-to-index/virtual-scroll-scroll-to-index.component.scss @@ -0,0 +1,40 @@ +:host { + display: block; + padding: 16px; +} + +.toolbar { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 16px; + margin-block-end: 16px; +} + +.toolbar__index { + inline-size: 140px; +} + +.toolbar__actions { + display: flex; + flex-wrap: wrap; + gap: 8px; +} + +.employees__viewport { + block-size: 400px; +} + +.employees__item--highlighted { + animation: highlight 1.5s ease-out; +} + +@keyframes highlight { + from { + box-shadow: inset 0 0 0 3px var(--ig-warn-500); + } + + to { + box-shadow: inset 0 0 0 3px transparent; + } +} diff --git a/src/app/data-display/virtual-scroll/virtual-scroll-scroll-to-index/virtual-scroll-scroll-to-index.component.ts b/src/app/data-display/virtual-scroll/virtual-scroll-scroll-to-index/virtual-scroll-scroll-to-index.component.ts new file mode 100644 index 0000000000..c5440eda05 --- /dev/null +++ b/src/app/data-display/virtual-scroll/virtual-scroll-scroll-to-index/virtual-scroll-scroll-to-index.component.ts @@ -0,0 +1,68 @@ +import { Component, signal, viewChild } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { IgxAvatarComponent } from 'igniteui-angular/avatar'; +import { IgxButtonDirective } from 'igniteui-angular/directives'; +import { IgxChipComponent } from 'igniteui-angular/chips'; +import { IgxInputDirective, IgxInputGroupComponent, IgxLabelDirective } from 'igniteui-angular/input-group'; +import { + IgxListActionDirective, + IgxListComponent, + IgxListItemComponent, + IgxListLineSubTitleDirective, + IgxListLineTitleDirective, + IgxListThumbnailDirective +} from 'igniteui-angular/list'; +import { IgxRadioComponent, IgxRadioGroupDirective } from 'igniteui-angular/radio'; +import { IgxVirtualItemDirective, IgxVirtualScrollComponent } from 'igniteui-angular/virtual-scroll'; +import { Employee, generateEmployees } from '../employees'; + +@Component({ + selector: 'app-virtual-scroll-scroll-to-index', + styleUrls: ['./virtual-scroll-scroll-to-index.component.scss'], + templateUrl: './virtual-scroll-scroll-to-index.component.html', + imports: [ + FormsModule, + IgxVirtualScrollComponent, + IgxVirtualItemDirective, + IgxInputGroupComponent, + IgxInputDirective, + IgxLabelDirective, + IgxRadioGroupDirective, + IgxRadioComponent, + IgxButtonDirective, + IgxListComponent, + IgxListItemComponent, + IgxListThumbnailDirective, + IgxListLineTitleDirective, + IgxListLineSubTitleDirective, + IgxListActionDirective, + IgxAvatarComponent, + IgxChipComponent + ] +}) +export class VirtualScrollScrollToIndexComponent { + public readonly employees: Employee[] = generateEmployees(100_000); + public readonly alignments: ScrollLogicalPosition[] = ['start', 'center', 'end', 'nearest']; + + public readonly targetIndex = signal(50_000); + public readonly alignment = signal('start'); + public readonly highlightedIndex = signal(null); + + private readonly virtualScroll = viewChild.required>('virtualScroll'); + + public async goTo(index: number): Promise { + const target = Math.min(Math.max(Math.trunc(index) || 0, 0), this.employees.length - 1); + this.targetIndex.set(target); + this.highlightedIndex.set(null); + + // Items that have not been rendered only have an estimated size, so the + // first jump lands near the target. The promise resolves once the + // component has measured the landing area and corrected the offset. + await this.virtualScroll().scrollToIndex(target, { block: this.alignment() }); + this.highlightedIndex.set(target); + } + + public goToRandom(): void { + this.goTo(Math.floor(Math.random() * this.employees.length)); + } +} diff --git a/src/app/data-display/virtual-scroll/virtual-scroll-variable-size/virtual-scroll-variable-size.component.html b/src/app/data-display/virtual-scroll/virtual-scroll-variable-size/virtual-scroll-variable-size.component.html new file mode 100644 index 0000000000..9ab9a5c04e --- /dev/null +++ b/src/app/data-display/virtual-scroll/virtual-scroll-variable-size/virtual-scroll-variable-size.component.html @@ -0,0 +1,16 @@ + + Team directory ({{ employees.length }}) + + + + + {{ employee.name }} + {{ employee.email }} + @if (employee.bio) { + {{ employee.bio }} + } + {{ employee.department }} + + + + diff --git a/src/app/data-display/virtual-scroll/virtual-scroll-variable-size/virtual-scroll-variable-size.component.scss b/src/app/data-display/virtual-scroll/virtual-scroll-variable-size/virtual-scroll-variable-size.component.scss new file mode 100644 index 0000000000..33088f9700 --- /dev/null +++ b/src/app/data-display/virtual-scroll/virtual-scroll-variable-size/virtual-scroll-variable-size.component.scss @@ -0,0 +1,14 @@ +:host { + display: block; + padding: 16px; +} + +.employees__viewport { + block-size: 480px; +} + +.employees__bio { + padding-block-start: 4px; + white-space: normal; + color: var(--ig-gray-700); +} diff --git a/src/app/data-display/virtual-scroll/virtual-scroll-variable-size/virtual-scroll-variable-size.component.ts b/src/app/data-display/virtual-scroll/virtual-scroll-variable-size/virtual-scroll-variable-size.component.ts new file mode 100644 index 0000000000..ce3366e283 --- /dev/null +++ b/src/app/data-display/virtual-scroll/virtual-scroll-variable-size/virtual-scroll-variable-size.component.ts @@ -0,0 +1,36 @@ +import { Component } from '@angular/core'; +import { IgxAvatarComponent } from 'igniteui-angular/avatar'; +import { IgxChipComponent } from 'igniteui-angular/chips'; +import { + IgxListActionDirective, + IgxListComponent, + IgxListItemComponent, + IgxListLineDirective, + IgxListLineSubTitleDirective, + IgxListLineTitleDirective, + IgxListThumbnailDirective +} from 'igniteui-angular/list'; +import { IgxVirtualItemDirective, IgxVirtualScrollComponent } from 'igniteui-angular/virtual-scroll'; +import { Employee, generateEmployees } from '../employees'; + +@Component({ + selector: 'app-virtual-scroll-variable-size', + styleUrls: ['./virtual-scroll-variable-size.component.scss'], + templateUrl: './virtual-scroll-variable-size.component.html', + imports: [ + IgxVirtualScrollComponent, + IgxVirtualItemDirective, + IgxListComponent, + IgxListItemComponent, + IgxListThumbnailDirective, + IgxListLineTitleDirective, + IgxListLineSubTitleDirective, + IgxListLineDirective, + IgxListActionDirective, + IgxAvatarComponent, + IgxChipComponent + ] +}) +export class VirtualScrollVariableSizeComponent { + public readonly employees: Employee[] = generateEmployees(10_000); +} diff --git a/src/app/lists/combo/combo-remote/combo-remote.component.ts b/src/app/lists/combo/combo-remote/combo-remote.component.ts index 994071a9af..febc5e093a 100644 --- a/src/app/lists/combo/combo-remote/combo-remote.component.ts +++ b/src/app/lists/combo/combo-remote/combo-remote.component.ts @@ -83,8 +83,9 @@ export class ComboRemoteComponent implements OnInit, AfterViewInit { } public onOpened() { - const scroll: number = this.remoteCombo.virtualScrollContainer.getScrollForIndex(this.itemID - 1); - this.remoteCombo.virtualScrollContainer.scrollPosition = scroll + this.additionalScroll; + // additionalScroll is one row, set when the selection is the last item. Landing a + // row further down puts that item at the bottom of the viewport. + void this.remoteCombo.virtualScrollContainer.scrollToIndex(this.itemID - 1 + (this.additionalScroll ? 1 : 0), { block: 'start' }); this.cdr.detectChanges(); } diff --git a/src/app/lists/combo/simple-combo-remote/simple-combo-remote.component.ts b/src/app/lists/combo/simple-combo-remote/simple-combo-remote.component.ts index 1a7caaad9c..6d1ebc7cff 100644 --- a/src/app/lists/combo/simple-combo-remote/simple-combo-remote.component.ts +++ b/src/app/lists/combo/simple-combo-remote/simple-combo-remote.component.ts @@ -70,8 +70,9 @@ export class SimpleComboRemoteComponent implements OnInit, AfterViewInit { } public onOpened() { - const scroll: number = this.remoteSimpleCombo.virtualScrollContainer.getScrollForIndex(this.itemID - 1); - this.remoteSimpleCombo.virtualScrollContainer.scrollPosition = scroll + this.additionalScroll; + // additionalScroll is one row, set when the selection is the last item. Landing a + // row further down puts that item at the bottom of the viewport. + void this.remoteSimpleCombo.virtualScrollContainer.scrollToIndex(this.itemID - 1 + (this.additionalScroll ? 1 : 0), { block: 'start' }); this.cdr.detectChanges(); } From 10323cf806712a049f908eafa26ad94582911792 Mon Sep 17 00:00:00 2001 From: Stamen Stoychev Date: Fri, 18 Sep 2026 16:57:38 +0300 Subject: [PATCH 10/22] Allows for the theming widget to style samples (#4015) --- .github/workflows/build-app-crm.yml | 4 + .github/workflows/build-app-lob.yml | 4 + .github/workflows/build-app.yml | 4 + angular.json | 7 +- src/app/app.component.ts | 47 ++--- src/app/services/theme.service.spec.ts | 56 ++++++ src/app/services/theme.service.ts | 231 +++++++++++++++++++++++++ src/index.html | 6 + src/styles.scss | 27 +-- 9 files changed, 338 insertions(+), 48 deletions(-) create mode 100644 src/app/services/theme.service.spec.ts create mode 100644 src/app/services/theme.service.ts diff --git a/.github/workflows/build-app-crm.yml b/.github/workflows/build-app-crm.yml index 2bfd89874a..77062edcad 100644 --- a/.github/workflows/build-app-crm.yml +++ b/.github/workflows/build-app-crm.yml @@ -46,4 +46,8 @@ jobs: - name: 'Generate live editing and build samples' run: npm run build:app-crm env: + # esbuild is a Go binary: Node heap flags do not limit it, GOMEMLIMIT/GOGC do. + # Without this the app build OOM-kills the runner ("The operation was canceled"). + GOMEMLIMIT: '6GiB' + GOGC: '50' NODE_OPTIONS: "--max_old_space_size=4096" diff --git a/.github/workflows/build-app-lob.yml b/.github/workflows/build-app-lob.yml index 699c333d3b..47fe1767ac 100644 --- a/.github/workflows/build-app-lob.yml +++ b/.github/workflows/build-app-lob.yml @@ -48,4 +48,8 @@ jobs: - name: 'Generate live editing and build samples' run: npm run build:app-lob env: + # esbuild is a Go binary: Node heap flags do not limit it, GOMEMLIMIT/GOGC do. + # Without this the app build OOM-kills the runner ("The operation was canceled"). + GOMEMLIMIT: '6GiB' + GOGC: '50' NODE_OPTIONS: "--max_old_space_size=4096" diff --git a/.github/workflows/build-app.yml b/.github/workflows/build-app.yml index 3c19b5984f..ae90b48623 100644 --- a/.github/workflows/build-app.yml +++ b/.github/workflows/build-app.yml @@ -46,4 +46,8 @@ jobs: - name: 'Generate live editing and build samples' run: npm run build env: + # esbuild is a Go binary: Node heap flags do not limit it, GOMEMLIMIT/GOGC do. + # Without this the app build OOM-kills the runner ("The operation was canceled"). + GOMEMLIMIT: '6GiB' + GOGC: '50' NODE_OPTIONS: "--max_old_space_size=4096" diff --git a/angular.json b/angular.json index 1509ba457b..f3c2b57e3c 100644 --- a/angular.json +++ b/angular.json @@ -19,7 +19,12 @@ "tsConfig": "src/tsconfig.app.json", "assets": [ "src/assets", - "src/favicon.ico" + "src/favicon.ico", + { + "glob": "igniteui-{angular,angular-dark,fluent-light,fluent-dark,bootstrap-light,bootstrap-dark,indigo-light,indigo-dark}.css", + "input": "node_modules/igniteui-angular/styles", + "output": "assets/themes" + } ], "styles": [ "src/styles.scss" diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 1046547447..10970e42e6 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,6 +1,7 @@ import { Component, HostListener, OnInit, DOCUMENT, inject } from '@angular/core'; import { RouterOutlet } from '@angular/router'; +import { ThemeService } from './services/theme.service'; @Component({ selector: 'app-root', @@ -10,50 +11,22 @@ import { RouterOutlet } from '@angular/router'; }) export class AppComponent implements OnInit { private document = inject(DOCUMENT); + private themeService = inject(ThemeService); public title = 'Samples'; - private theme = 'default-theme'; - private styleElem: HTMLStyleElement; - private typefacesLoaded = ['Titillium Web', 'Roboto']; - private typefaceUrl = 'https://fonts.googleapis.com/css?family='; public ngOnInit() { - this.createThemeStyle(); + this.document.body.classList.add('custom-body'); + this.themeService.init(); } - // eslint-disable-next-line @typescript-eslint/member-ordering + /** + * Samples are embedded in the documentation as iframes and the theming + * widget shown next to each of them posts the visitor's theme selection + * down into the sample. Anything that is not such a message is left alone. + */ @HostListener('window:message', ['$event']) protected onMessage(e: MessageEvent) { - if (e.origin === e.data.origin && typeof e.data.themeStyle === 'string') { - this.styleElem.textContent = e.data.themeStyle; - const typeface = window.getComputedStyle(this.document.body).fontFamily.replace(/[\'\"]/g, ''); - if (!(typeface.match(/,/g) || []).length && - !this.typefacesLoaded.includes(typeface)) { - this.typefacesLoaded.push(typeface); - this.createTypefaceLink(typeface); - } - } else if (e.origin === e.data.origin && typeof e.data.theme === 'string') { - this.document.body.classList.remove(this.theme); - this.document.body.classList.add(e.data.theme); - this.theme = e.data.theme; - } - } - - private createTypefaceLink(typeface: string) { - let typefaceElem = this.document.getElementById('igniteui-theme-typeface') as HTMLLinkElement; - if (!typefaceElem) { - typefaceElem = this.document.createElement('link'); - typefaceElem.rel = 'stylesheet'; - typefaceElem.id = 'igniteui-theme-typeface'; - this.document.head.appendChild(typefaceElem); - } - typefaceElem.href = this.typefaceUrl + typeface.split(' ').join('+'); - } - - private createThemeStyle() { - this.styleElem = this.document.createElement('style'); - this.styleElem.id = 'igniteui-theme'; - this.document.head.appendChild(this.styleElem); - this.document.body.classList.add('custom-body'); + this.themeService.handleMessage(e); } } diff --git a/src/app/services/theme.service.spec.ts b/src/app/services/theme.service.spec.ts new file mode 100644 index 0000000000..aa97a511dd --- /dev/null +++ b/src/app/services/theme.service.spec.ts @@ -0,0 +1,56 @@ +import { DOCUMENT, PLATFORM_ID, signal } from '@angular/core'; +import { TestBed } from '@angular/core/testing'; +import { THEME_TOKEN, type IgxTheme } from 'igniteui-angular/core'; +import { THEME_MESSAGE, ThemeService } from './theme.service'; + +describe('ThemeService theme validation', () => { + let service: ThemeService; + let document: Document; + + beforeEach(() => { + document = window.document.implementation.createHTMLDocument(); + TestBed.configureTestingModule({ + providers: [ + { provide: DOCUMENT, useValue: document }, + { provide: PLATFORM_ID, useValue: 'browser' }, + { provide: THEME_TOKEN, useValue: signal('material') } + ] + }); + service = TestBed.inject(ThemeService); + service.init(); + }); + + for (const theme of ['toString', 'constructor', '__proto__', 'hasOwnProperty']) { + it(`rejects inherited theme key ${theme}`, () => { + const link = document.getElementById('igniteui-theme'); + const href = link.getAttribute('href'); + + expect(service.handleMessage(new MessageEvent('message', { + data: { type: THEME_MESSAGE, theme } + }))).toBeFalse(); + expect(service.theme()).toBe('material'); + expect(link.getAttribute('href')).toBe(href); + + expect(service.set(theme, 'dark')).toBeTrue(); + expect(service.theme()).toBe('material'); + expect(service.mode()).toBe('dark'); + expect(link.getAttribute('href')).toBe('assets/themes/igniteui-angular-dark.css'); + }); + } + + for (const [theme, stylesheet] of [ + ['material', 'igniteui-angular.css'], + ['fluent', 'igniteui-fluent-light.css'], + ['bootstrap', 'igniteui-bootstrap-light.css'], + ['indigo', 'igniteui-indigo-light.css'] + ] as const) { + it(`accepts supported theme ${theme}`, () => { + expect(service.handleMessage(new MessageEvent('message', { + data: { type: THEME_MESSAGE, theme } + }))).toBeTrue(); + expect(service.theme()).toBe(theme); + expect(document.getElementById('igniteui-theme').getAttribute('href')) + .toBe(`assets/themes/${stylesheet}`); + }); + } +}); diff --git a/src/app/services/theme.service.ts b/src/app/services/theme.service.ts new file mode 100644 index 0000000000..bc24357df4 --- /dev/null +++ b/src/app/services/theme.service.ts @@ -0,0 +1,231 @@ +import { isPlatformBrowser } from '@angular/common'; +import { DOCUMENT, Injectable, PLATFORM_ID, inject, signal } from '@angular/core'; +import { THEME_TOKEN, type IgxTheme } from 'igniteui-angular/core'; + +/** + * Message type posted by the documentation site's theming widget into the + * sample iframe. See `ThemeService.handleMessage`. + */ +export const THEME_MESSAGE = 'igd-sample-theme'; + +/** Color modes the theming widget can request. */ +export type ThemeMode = 'light' | 'dark' | 'system'; + +/** `system` resolved against the OS preference. */ +export type ColorScheme = 'light' | 'dark'; + +/** + * Prebuilt Ignite UI stylesheets, one per theme/scheme pair. They are copied + * out of `igniteui-angular/styles` into `assets/themes` at build time - see the + * `assets` section of angular.json. + */ +const THEME_STYLESHEETS: Record> = { + material: { light: 'igniteui-angular.css', dark: 'igniteui-angular-dark.css' }, + fluent: { light: 'igniteui-fluent-light.css', dark: 'igniteui-fluent-dark.css' }, + bootstrap: { light: 'igniteui-bootstrap-light.css', dark: 'igniteui-bootstrap-dark.css' }, + indigo: { light: 'igniteui-indigo-light.css', dark: 'igniteui-indigo-dark.css' } +}; + +const THEMES_PATH = 'assets/themes/'; + +/** Id of the `` in index.html that carries the active theme. */ +const THEME_LINK_ID = 'igniteui-theme'; + +const TYPEFACE_URL = 'https://fonts.googleapis.com/css?family='; +const TYPEFACE_WEIGHTS = ':300,400,600,700'; + +/** + * Font families that never need to be fetched: generic CSS keywords and the + * system fonts the Bootstrap theme is built on. + */ +const LOCAL_FAMILIES = new Set([ + 'sans-serif', 'serif', 'monospace', 'cursive', 'fantasy', + 'system-ui', 'ui-sans-serif', 'ui-serif', 'ui-monospace', + 'segoe ui', 'helvetica', 'helvetica neue', 'arial', 'roboto' +]); + +const isTheme = (value: unknown): value is IgxTheme => + typeof value === 'string' && Object.hasOwn(THEME_STYLESHEETS, value); + +const isMode = (value: unknown): value is ThemeMode => + value === 'light' || value === 'dark' || value === 'system'; + +/** + * Swaps the Ignite UI theme of the samples application at runtime. + * + * Samples are embedded in the documentation as iframes and the site's theming + * widget posts the visitor's selection into them, so the whole application has + * to be able to move between the Material, Fluent, Bootstrap and Indigo themes + * (each in a light and a dark variant) without reloading. That is done by + * pointing a single `` at one of the prebuilt stylesheets instead of + * compiling a single theme into `styles.scss`. + */ +@Injectable({ providedIn: 'root' }) +export class ThemeService { + private document = inject(DOCUMENT); + private themeToken = inject(THEME_TOKEN); + private isBrowser = isPlatformBrowser(inject(PLATFORM_ID)); + + /** The selected theme. */ + public readonly theme = signal('material'); + + /** The selected color mode, `system` included. */ + public readonly mode = signal('light'); + + /** The color mode actually in effect, with `system` already resolved. */ + public readonly colorScheme = signal('light'); + + private prefersDark: MediaQueryList; + private typefaces = new Set(); + + /** + * Applies the initial theme and starts following the OS color preference. + * Safe to call more than once. + */ + public init(): void { + if (this.isBrowser && !this.prefersDark) { + this.prefersDark = this.document.defaultView?.matchMedia('(prefers-color-scheme: dark)'); + // Only relevant while the widget is on `system`; `apply` ignores it otherwise. + this.prefersDark?.addEventListener('change', () => this.apply()); + } + + this.apply(); + } + + /** + * Handles a `message` event coming from the documentation site. + * + * The widget posts `{ type: 'igd-sample-theme', theme, themeName, mode }` + * once when the iframe loads and again on every change. The message is + * trusted for its shape rather than for its origin - the documentation is + * served from a number of hosts, and the only thing acted upon is a choice + * between the four known themes and the three known modes. + * + * @returns whether the message was recognized and applied. + */ + public handleMessage(event: MessageEvent): boolean { + const data = event.data; + + if (!data || (data.type !== THEME_MESSAGE && data.event !== THEME_MESSAGE)) { + return false; + } + + return this.set(data.theme ?? data.themeName, data.mode); + } + + /** + * Switches to `theme` / `mode`. Unknown or missing values leave the + * corresponding part of the selection untouched. + * + * @returns whether anything was recognized. + */ + public set(theme?: unknown, mode?: unknown): boolean { + let known = false; + + if (isTheme(theme)) { + this.theme.set(theme); + known = true; + } + + if (isMode(mode)) { + this.mode.set(mode); + known = true; + } + + if (known) { + this.apply(); + } + + return known; + } + + private apply(): void { + if (!this.isBrowser) { + return; + } + + const theme = this.theme(); + const scheme = this.resolveScheme(); + this.colorScheme.set(scheme); + + // Exposed for samples that need to react to the selection. Deliberately + // not used to paint a page background: the documentation's Sample + // component owns the surface behind the iframe. + const root = this.document.documentElement; + root.dataset.igTheme = theme; + root.dataset.igMode = scheme; + + const href = THEMES_PATH + THEME_STYLESHEETS[theme][scheme]; + const link = this.themeLink(); + + if (!link.getAttribute('href')?.endsWith(href)) { + link.addEventListener('load', () => this.loadTypeface(), { once: true }); + link.href = href; + } + + // Components such as igx-input-group render differently per theme and + // take the theme from this token rather than from the stylesheet. + this.themeToken.set(theme); + } + + private resolveScheme(): ColorScheme { + const mode = this.mode(); + + if (mode !== 'system') { + return mode; + } + + return this.prefersDark?.matches ? 'dark' : 'light'; + } + + private themeLink(): HTMLLinkElement { + let link = this.document.getElementById(THEME_LINK_ID) as HTMLLinkElement; + + if (!link) { + link = this.document.createElement('link'); + link.id = THEME_LINK_ID; + link.rel = 'stylesheet'; + // Ahead of everything else in the head, so that the application's + // own styles keep overriding the theme as they do in index.html. + this.document.head.insertBefore(link, this.document.head.firstChild); + } + + return link; + } + + /** + * Each theme comes with its own typeface. Once a theme stylesheet is in + * place, take the first family off `--ig-font-family` and pick it up from + * Google Fonts unless it is one the browser already has. + */ + private loadTypeface(): void { + const view = this.document.defaultView; + + if (!view) { + return; + } + + const family = view.getComputedStyle(this.document.body) + .getPropertyValue('--ig-font-family') + .split(',')[0] + .trim() + .replace(/['"]/g, ''); + + if (!family || family.startsWith('-') || LOCAL_FAMILIES.has(family.toLowerCase())) { + return; + } + + if (this.typefaces.has(family)) { + return; + } + + this.typefaces.add(family); + + // A link per family, so that switching back to an earlier theme does + // not have to fetch its typeface again. + const link = this.document.createElement('link'); + link.rel = 'stylesheet'; + link.href = TYPEFACE_URL + family.split(' ').join('+') + TYPEFACE_WEIGHTS; + this.document.head.appendChild(link); + } +} diff --git a/src/index.html b/src/index.html index 9920eced30..65e26031de 100644 --- a/src/index.html +++ b/src/index.html @@ -12,6 +12,12 @@ + + + diff --git a/src/styles.scss b/src/styles.scss index 8c144ff6dd..03a2dd70b9 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -5,6 +5,14 @@ @use 'app-layout'; @import "tailwindcss"; +// The Ignite UI theme itself is deliberately NOT compiled into this file. Every +// sample is embedded in the documentation next to a theming widget that can +// switch it between the Material, Fluent, Bootstrap and Indigo themes in light +// or dark, so the theme is loaded as a swappable stylesheet instead - see the +// `igniteui-theme` link in index.html, the `assets/themes` entry in angular.json +// and `src/app/services/theme.service.ts`. A theme compiled in here would sit +// later in the cascade and win over the one the visitor picked. + // Specifies large size for all components to match the previous defaults // This may not be needed for your project. Please consult https://www.infragistics.com/products/ignite-ui-angular/angular/components/general/update-guide for more details. :root { @@ -19,6 +27,13 @@ body { margin: 0; } +// Nothing here paints a page background per color mode on purpose. The sample +// is embedded in an iframe and the documentation's Sample component draws the +// surface behind it from the same mode the theming widget posts down here, so +// the iframe is left transparent for it to show through. `ThemeService` still +// reflects `data-ig-theme` / `data-ig-mode` onto the root element for samples +// that need to react to the selection themselves. + body.custom-body:has( app-badge-overview, app-badge-styling, @@ -34,16 +49,8 @@ body.custom-body:has( background: transparent; } -@include core(); -@include typography(); -@include theme( - $palette: $palette, - $schema: $schema -); - -:root { - @include palette($palette); -} +// `core()`, `typography()`, `theme()` and the root palette all ship inside the +// prebuilt stylesheets loaded through the `igniteui-theme` link (see above). .light-theme { @include light-theme($palette); From c6fec0cc4e0ed15566f4bf19e4b9b7cfae81c2e5 Mon Sep 17 00:00:00 2001 From: Viktor Kombov Date: Fri, 18 Sep 2026 18:26:47 +0300 Subject: [PATCH 11/22] Update to 22.2.0-rc.0 --- package-lock.json | 32 +++---- package.json | 8 +- .../virtual-scroll-horizontal.component.html | 2 +- ...tual-scroll-infinite-scroll.component.html | 2 +- .../virtual-scroll-overview.component.html | 2 +- .../virtual-scroll-paged-data.component.html | 2 +- ...tual-scroll-scroll-to-index.component.html | 2 +- ...irtual-scroll-variable-size.component.html | 2 +- .../drop-down-remote.component.html | 19 +++-- .../drop-down-remote.component.scss | 2 +- .../drop-down-remote.component.ts | 85 +++++++++---------- .../drop-down-virtual.component.html | 15 ++-- .../drop-down-virtual.component.scss | 4 +- .../drop-down-virtual.component.ts | 8 +- 14 files changed, 89 insertions(+), 96 deletions(-) diff --git a/package-lock.json b/package-lock.json index f1400169da..0b1d5246ac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,11 +34,11 @@ "express": "^4.18.2", "file-saver": "^2.0.2", "fuse.js": "^7.1.0", - "igniteui-angular": "22.1.0", + "igniteui-angular": "22.2.0-rc.0", "igniteui-angular-charts": "^22.0.0", "igniteui-angular-core": "^22.0.0", - "igniteui-angular-extras": "22.1.0", - "igniteui-angular-i18n": "22.1.0", + "igniteui-angular-extras": "22.2.0-rc.0", + "igniteui-angular-i18n": "22.2.0-rc.0", "igniteui-dockmanager": "^1.17.0", "igniteui-grid-lite": "0.10.0", "igniteui-i18n-resources": "^1.0.4", @@ -10455,15 +10455,15 @@ "license": "BSD-3-Clause" }, "node_modules/igniteui-angular": { - "version": "22.1.0", - "resolved": "https://registry.npmjs.org/igniteui-angular/-/igniteui-angular-22.1.0.tgz", - "integrity": "sha512-05Wdj9RvkIVm6wYyZFNdqi0oS/P9IKhrUAnwVzQ8nW8i5NHA13Fn+a6ZY3q/SKXyBc5C2Sb5ZyBL2DwK1Bbxrg==", + "version": "22.2.0-rc.0", + "resolved": "https://registry.npmjs.org/igniteui-angular/-/igniteui-angular-22.2.0-rc.0.tgz", + "integrity": "sha512-nul1lwEjNuzVd1YaKnjnBCjPsIvx+COmpGHxJVT2vXYKAYBuElFn18g7oMHugw61F2Euq7kZTllhg9v37raSCQ==", "license": "SEE LICENSE IN LICENSE", "dependencies": { "@igniteui/material-icons-extended": "^3.1.0", "fflate": "^0.8.2", "igniteui-i18n-core": "^1.0.5", - "igniteui-theming": "^28.1.1", + "igniteui-theming": "^29.0.0", "igniteui-trial-watermark": "^3.1.0", "jspdf": "^4.2.1", "lodash-es": "^4.17.21", @@ -10516,9 +10516,9 @@ } }, "node_modules/igniteui-angular-extras": { - "version": "22.1.0", - "resolved": "https://registry.npmjs.org/igniteui-angular-extras/-/igniteui-angular-extras-22.1.0.tgz", - "integrity": "sha512-6uGpfV6hbH/FPegXBAdiCtiwp8Qq0/mqcBUw5S2kFkUyQoaIaESvgtzCE0swi153NpHPA36OhWGKq5jbw0vsqQ==", + "version": "22.2.0-rc.0", + "resolved": "https://registry.npmjs.org/igniteui-angular-extras/-/igniteui-angular-extras-22.2.0-rc.0.tgz", + "integrity": "sha512-iPUv5RayP3wFqbylsbHIKEu6oKqD382+8DRu0ZKZgKuc/jBdBSFwWaNG+HSj3GNKRAMpix2KO+0imO/SZMZ7CQ==", "license": "SEE LICENSE IN LICENSE", "dependencies": { "igniteui-trial-watermark": "^3.1.0", @@ -10533,9 +10533,9 @@ } }, "node_modules/igniteui-angular-i18n": { - "version": "22.1.0", - "resolved": "https://registry.npmjs.org/igniteui-angular-i18n/-/igniteui-angular-i18n-22.1.0.tgz", - "integrity": "sha512-rwGcf7ZUNp7mLU2K5FhsGEWX/8v6EZYitlDLlbLYZL/O2oFZISBfJRvzqi3GLJhEINJTE4Q8h8FNrjhz0tj8RQ==", + "version": "22.2.0-rc.0", + "resolved": "https://registry.npmjs.org/igniteui-angular-i18n/-/igniteui-angular-i18n-22.2.0-rc.0.tgz", + "integrity": "sha512-3l/K/jhOjj8wxX+h6C8SmTsi1xeiwimK7vS3wZnJKxkeZlGwdkCnp1PwJv8uM6XZwUhrbE7G8CZzRmaApiLBiA==", "license": "MIT", "dependencies": { "igniteui-i18n-core": "^1.0.2", @@ -10602,9 +10602,9 @@ "license": "MIT" }, "node_modules/igniteui-theming": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/igniteui-theming/-/igniteui-theming-28.1.1.tgz", - "integrity": "sha512-ioNSE9t36nqNfItashgM6oZxfgiLPjzeJ4X2g++3kU9oU0kklkz1Ax9F0FmGiwyIC2atWELkb76LsyT+0ZSTSQ==", + "version": "29.0.0", + "resolved": "https://registry.npmjs.org/igniteui-theming/-/igniteui-theming-29.0.0.tgz", + "integrity": "sha512-WpOJs6xX+VKG7uO2Dvkb1EmmXVDj+vnUCnlwmr6XCflgKv3baJLDDb3b/APWMLjPggDFxysrpgqAr6QHuI55Bw==", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.28.0", diff --git a/package.json b/package.json index 2ca6bbe650..22e85c4deb 100644 --- a/package.json +++ b/package.json @@ -71,11 +71,11 @@ "express": "^4.18.2", "file-saver": "^2.0.2", "fuse.js": "^7.1.0", - "igniteui-angular": "22.1.0", + "igniteui-angular": "22.2.0-rc.0", "igniteui-angular-charts": "^22.0.0", "igniteui-angular-core": "^22.0.0", - "igniteui-angular-extras": "22.1.0", - "igniteui-angular-i18n": "22.1.0", + "igniteui-angular-extras": "22.2.0-rc.0", + "igniteui-angular-i18n": "22.2.0-rc.0", "igniteui-dockmanager": "^1.17.0", "igniteui-grid-lite": "0.10.0", "igniteui-i18n-resources": "^1.0.4", @@ -110,7 +110,7 @@ "@angular/compiler": "^22.0.0" }, "igniteui-angular-extras": { - "igniteui-angular": "22.1.0", + "igniteui-angular": "22.2.0-rc.0", "@infragistics/igniteui-angular": "^22.0.0", "igniteui-angular-core": "^22.0.0", "igniteui-angular-charts": "^22.0.0", diff --git a/src/app/data-display/virtual-scroll/virtual-scroll-horizontal/virtual-scroll-horizontal.component.html b/src/app/data-display/virtual-scroll/virtual-scroll-horizontal/virtual-scroll-horizontal.component.html index a0d68475e5..35519873f7 100644 --- a/src/app/data-display/virtual-scroll/virtual-scroll-horizontal/virtual-scroll-horizontal.component.html +++ b/src/app/data-display/virtual-scroll/virtual-scroll-horizontal/virtual-scroll-horizontal.component.html @@ -1,4 +1,4 @@ - +
diff --git a/src/app/data-display/virtual-scroll/virtual-scroll-overview/virtual-scroll-overview.component.html b/src/app/data-display/virtual-scroll/virtual-scroll-overview/virtual-scroll-overview.component.html index e7d3861d4d..c7968217bc 100644 --- a/src/app/data-display/virtual-scroll/virtual-scroll-overview/virtual-scroll-overview.component.html +++ b/src/app/data-display/virtual-scroll/virtual-scroll-overview/virtual-scroll-overview.component.html @@ -1,6 +1,6 @@ Employees ({{ employees.length }}) - + diff --git a/src/app/data-display/virtual-scroll/virtual-scroll-paged-data/virtual-scroll-paged-data.component.html b/src/app/data-display/virtual-scroll/virtual-scroll-paged-data/virtual-scroll-paged-data.component.html index 987b68dd2c..27b8534f49 100644 --- a/src/app/data-display/virtual-scroll/virtual-scroll-paged-data/virtual-scroll-paged-data.component.html +++ b/src/app/data-display/virtual-scroll/virtual-scroll-paged-data/virtual-scroll-paged-data.component.html @@ -5,7 +5,7 @@ diff --git a/src/app/data-display/virtual-scroll/virtual-scroll-scroll-to-index/virtual-scroll-scroll-to-index.component.html b/src/app/data-display/virtual-scroll/virtual-scroll-scroll-to-index/virtual-scroll-scroll-to-index.component.html index 83646da7da..4469bcaace 100644 --- a/src/app/data-display/virtual-scroll/virtual-scroll-scroll-to-index/virtual-scroll-scroll-to-index.component.html +++ b/src/app/data-display/virtual-scroll/virtual-scroll-scroll-to-index/virtual-scroll-scroll-to-index.component.html @@ -29,7 +29,7 @@ Employees ({{ employees.length }}) - + Team directory ({{ employees.length }}) - + diff --git a/src/app/data-entries/dropdown/drop-down-remote-virtual/drop-down-remote.component.html b/src/app/data-entries/dropdown/drop-down-remote-virtual/drop-down-remote.component.html index 326ce80547..a51fc5cce1 100644 --- a/src/app/data-entries/dropdown/drop-down-remote-virtual/drop-down-remote.component.html +++ b/src/app/data-entries/dropdown/drop-down-remote-virtual/drop-down-remote.component.html @@ -1,13 +1,16 @@ - + + + + {{ item.ProductName }} + + +
Selected Product: {{ remoteDropDown.selectedItem?.value }} diff --git a/src/app/data-entries/dropdown/drop-down-remote-virtual/drop-down-remote.component.scss b/src/app/data-entries/dropdown/drop-down-remote-virtual/drop-down-remote.component.scss index 7e4e00cd9b..7a96deeff0 100644 --- a/src/app/data-entries/dropdown/drop-down-remote-virtual/drop-down-remote.component.scss +++ b/src/app/data-entries/dropdown/drop-down-remote-virtual/drop-down-remote.component.scss @@ -1,5 +1,5 @@ +// The virtual scroll host is the scroll container, so it needs a fixed height. .drop-down-virtual-wrapper { - overflow-y: hidden; width: 260px; height: 320px; } diff --git a/src/app/data-entries/dropdown/drop-down-remote-virtual/drop-down-remote.component.ts b/src/app/data-entries/dropdown/drop-down-remote-virtual/drop-down-remote.component.ts index 9a2941bfec..8077fe682d 100644 --- a/src/app/data-entries/dropdown/drop-down-remote-virtual/drop-down-remote.component.ts +++ b/src/app/data-entries/dropdown/drop-down-remote-virtual/drop-down-remote.component.ts @@ -1,74 +1,65 @@ -import { ChangeDetectorRef, Component, OnDestroy, OnInit, ViewChild, AfterViewInit, inject } from '@angular/core'; -// tslint:disable-next-line:max-line-length -import { IForOfState, IgxButtonDirective, IgxForOfDirective, IgxToggleActionDirective } from 'igniteui-angular/directives'; +import { Component, OnDestroy, OnInit, ViewChild, inject, signal } from '@angular/core'; +import { IgxButtonDirective, IgxToggleActionDirective } from 'igniteui-angular/directives'; import { IgxDropDownComponent, IgxDropDownItemComponent, IgxDropDownItemNavigationDirective } from 'igniteui-angular/drop-down'; import { IgxToastComponent } from 'igniteui-angular/toast'; import { VerticalAlignment } from 'igniteui-angular/core'; -import { Subject, Subscription } from 'rxjs'; -import { takeUntil } from 'rxjs/operators'; +import { IgxVirtualItemDirective, IgxVirtualScrollComponent, VirtualDataWindow, VirtualScrollState } from 'igniteui-angular/virtual-scroll'; +import { Subscription } from 'rxjs'; import { RemoteNWindService } from '../../../services/remoteNwind.service'; -import { AsyncPipe } from '@angular/common'; -// tslint:disable:object-literal-sort-keys +/** Extra records requested on each side of the range the viewport wants. */ +const BUFFER = 10; + @Component({ providers: [RemoteNWindService], selector: 'app-drop-down-remote', templateUrl: './drop-down-remote.component.html', styleUrls: ['./drop-down-remote.component.scss'], - imports: [IgxButtonDirective, IgxToggleActionDirective, IgxDropDownItemNavigationDirective, IgxDropDownComponent, IgxForOfDirective, IgxDropDownItemComponent, IgxToastComponent, AsyncPipe] + imports: [IgxButtonDirective, IgxToggleActionDirective, IgxDropDownItemNavigationDirective, IgxDropDownComponent, IgxVirtualScrollComponent, IgxVirtualItemDirective, IgxDropDownItemComponent, IgxToastComponent] }) -export class DropDownRemoteComponent implements OnInit, OnDestroy, AfterViewInit { +export class DropDownRemoteComponent implements OnInit, OnDestroy { private remoteService = inject(RemoteNWindService); - cdr = inject(ChangeDetectorRef); @ViewChild('loadingToast', { read: IgxToastComponent, static: true }) public loadingToast: IgxToastComponent; - @ViewChild(IgxForOfDirective, { read: IgxForOfDirective, static: true }) - public remoteForDir: IgxForOfDirective; @ViewChild('remoteDropDown', { read: IgxDropDownComponent, static: true }) public remoteDropDown: IgxDropDownComponent; - public itemHeight = 48; - public itemsMaxHeight = 320; - public prevRequest: Subscription; - public rData: any; - private destroy$ = new Subject(); + public itemHeight = 40; - public ngAfterViewInit() { - const initialState: IForOfState = { - startIndex: 0, chunkSize: Math.floor(this.itemsMaxHeight / this.itemHeight) + 1 - }; - this.remoteService.getData(initialState, null, (data) => { - this.remoteForDir.totalItemCount = data['@odata.count']; - }); - this.remoteForDir.chunkPreload.pipe(takeUntil(this.destroy$)).subscribe((data) => { - this.dataLoading(data); - }); + /** The loaded page; the list is as long as `totalCount`, so the scrollbar spans every product. */ + public readonly page = signal>({ items: [], startIndex: 0, totalCount: 0 }); + + private pending: Subscription; + + public ngOnInit() { + this.loadPage(0, 2 * BUFFER); } - public dataLoading(evt) { - if (this.prevRequest) { - this.prevRequest.unsubscribe(); + /** `stateChange` reports the range the viewport wants; load a page when the loaded one does not cover it. */ + public onStateChange(state: VirtualScrollState) { + const page = this.page(); + if (state.startIndex >= page.startIndex && state.endIndex < page.startIndex + page.items.length) { + return; } - this.loadingToast.positionSettings.verticalDirection = VerticalAlignment.Middle; - this.loadingToast.autoHide = false; - this.loadingToast.open('Loading Remote Data...'); - this.cdr.detectChanges(); - this.prevRequest = this.remoteService.getData( - evt, - null, - (data) => { - this.remoteForDir.totalItemCount = data['@odata.count']; - this.loadingToast.close(); - this.cdr.detectChanges(); - }); - } - public ngOnInit() { - this.rData = this.remoteService.remoteData; + const startIndex = Math.max(0, state.startIndex - BUFFER); + this.loadPage(startIndex, state.endIndex - startIndex + 1 + BUFFER); } public ngOnDestroy() { - this.destroy$.next(); - this.destroy$.complete(); + this.pending?.unsubscribe(); + } + + private loadPage(startIndex: number, count: number) { + // Cancel the previous request, so a slow response cannot replace a newer page. + this.pending?.unsubscribe(); + this.loadingToast.positionSettings.verticalDirection = VerticalAlignment.Middle; + this.loadingToast.autoHide = false; + this.loadingToast.open('Loading Remote Data...'); + + this.pending = this.remoteService.getData({ startIndex, chunkSize: count }, null, (data) => { + this.page.set({ items: data.value, startIndex, totalCount: data['@odata.count'] }); + this.loadingToast.close(); + }); } } diff --git a/src/app/data-entries/dropdown/drop-down-virtual/drop-down-virtual.component.html b/src/app/data-entries/dropdown/drop-down-virtual/drop-down-virtual.component.html index b1d9861c2b..67ffd36299 100644 --- a/src/app/data-entries/dropdown/drop-down-virtual/drop-down-virtual.component.html +++ b/src/app/data-entries/dropdown/drop-down-virtual/drop-down-virtual.component.html @@ -1,12 +1,11 @@ - + + + + {{ item.name }} + + +
Selected Model: {{ dropdown.selectedItem?.value.name }}
diff --git a/src/app/data-entries/dropdown/drop-down-virtual/drop-down-virtual.component.scss b/src/app/data-entries/dropdown/drop-down-virtual/drop-down-virtual.component.scss index 888c5ba127..bb5418c335 100644 --- a/src/app/data-entries/dropdown/drop-down-virtual/drop-down-virtual.component.scss +++ b/src/app/data-entries/dropdown/drop-down-virtual/drop-down-virtual.component.scss @@ -1,6 +1,6 @@ +// The virtual scroll host is the scroll container, so it needs a fixed height. .drop-down-virtual-wrapper { - overflow: hidden; - max-height: 240px; + height: 240px; width: 180px; } diff --git a/src/app/data-entries/dropdown/drop-down-virtual/drop-down-virtual.component.ts b/src/app/data-entries/dropdown/drop-down-virtual/drop-down-virtual.component.ts index f7efad5d6f..4904b88554 100644 --- a/src/app/data-entries/dropdown/drop-down-virtual/drop-down-virtual.component.ts +++ b/src/app/data-entries/dropdown/drop-down-virtual/drop-down-virtual.component.ts @@ -1,6 +1,7 @@ import { Component } from '@angular/core'; -import { IgxButtonDirective, IgxForOfDirective, IgxToggleActionDirective } from 'igniteui-angular/directives'; +import { IgxButtonDirective, IgxToggleActionDirective } from 'igniteui-angular/directives'; import { IgxDropDownComponent, IgxDropDownItemComponent, IgxDropDownItemNavigationDirective } from 'igniteui-angular/drop-down'; +import { IgxVirtualItemDirective, IgxVirtualScrollComponent } from 'igniteui-angular/virtual-scroll'; // tslint:disable:object-literal-sort-keys // tslint:disable-next-line:interface-name @@ -15,12 +16,11 @@ interface DataItem { selector: 'app-drop-down-virtual', templateUrl: './drop-down-virtual.component.html', styleUrls: ['./drop-down-virtual.component.scss'], - imports: [IgxButtonDirective, IgxToggleActionDirective, IgxDropDownItemNavigationDirective, IgxDropDownComponent, IgxForOfDirective, IgxDropDownItemComponent] + imports: [IgxButtonDirective, IgxToggleActionDirective, IgxDropDownItemNavigationDirective, IgxDropDownComponent, IgxVirtualScrollComponent, IgxVirtualItemDirective, IgxDropDownItemComponent] }) export class DropDownVirtualComponent { public items: DataItem[]; - public itemHeight = 48; - public itemsMaxHeight = 240; + public itemHeight = 40; constructor() { const itemsCollection: DataItem[] = []; From dcc592478d059aa7108bd829c0f35e388a9c12a3 Mon Sep 17 00:00:00 2001 From: Viktor Kombov Date: Mon, 21 Sep 2026 13:50:01 +0300 Subject: [PATCH 12/22] Fix build errors --- .../data-entries/button/button-size/button-size.component.ts | 2 +- .../grid-groupby-summary-styling-sample.component.scss | 1 - .../tree-grid-summary-styling.component.scss | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/app/data-entries/button/button-size/button-size.component.ts b/src/app/data-entries/button/button-size/button-size.component.ts index 916c5da122..016ad98c77 100644 --- a/src/app/data-entries/button/button-size/button-size.component.ts +++ b/src/app/data-entries/button/button-size/button-size.component.ts @@ -11,5 +11,5 @@ import { IgxIconComponent } from 'igniteui-angular/icon'; }) export class ButtonSizeComponent { public sizes = ['large', 'medium', 'small']; - public variants = ['contained', 'outlined', 'flat']; + public variants = ['contained', 'outlined', 'flat'] as const; } diff --git a/src/app/grid/grid-groupby-summary-styling-sample/grid-groupby-summary-styling-sample.component.scss b/src/app/grid/grid-groupby-summary-styling-sample/grid-groupby-summary-styling-sample.component.scss index 0ade0da842..e886abfc87 100644 --- a/src/app/grid/grid-groupby-summary-styling-sample/grid-groupby-summary-styling-sample.component.scss +++ b/src/app/grid/grid-groupby-summary-styling-sample/grid-groupby-summary-styling-sample.component.scss @@ -7,7 +7,6 @@ $custom-theme: grid-summary-theme( $background-color: $summaries-background, $label-color: #e41c77, $result-color: black, - $pinned-border-width: 2px, $pinned-border-style: dotted, $pinned-border-color: #e41c77, ); diff --git a/src/app/tree-grid/tree-grid-summary-styling/tree-grid-summary-styling.component.scss b/src/app/tree-grid/tree-grid-summary-styling/tree-grid-summary-styling.component.scss index 07c3707c3a..6013b5f3df 100644 --- a/src/app/tree-grid/tree-grid-summary-styling/tree-grid-summary-styling.component.scss +++ b/src/app/tree-grid/tree-grid-summary-styling/tree-grid-summary-styling.component.scss @@ -7,7 +7,6 @@ $custom-theme: grid-summary-theme( $background-color: $summaries-background, $label-color: #486821, $result-color: #172505, - $pinned-border-width: 2px, $pinned-border-style: dotted, $pinned-border-color: #172505, ); From 11b35227b0750c13f7d6239a965a3e31c7b51a58 Mon Sep 17 00:00:00 2001 From: Adrian Petrov Date: Wed, 23 Sep 2026 13:41:23 +0300 Subject: [PATCH 13/22] feat(qr-code): split sample in two --- .../data-display/data-display-routes-data.ts | 3 ++- src/app/data-display/data-display.routes.ts | 14 +++++++---- .../qr-code-corner-shapes.component.html | 12 ++++++++++ .../qr-code-corner-shapes.component.scss} | 1 + .../qr-code-corner-shapes.component.ts | 13 ++++++++++ .../qr-code-dot-shapes.component.html | 12 ++++++++++ .../qr-code-dot-shapes.component.scss | 24 +++++++++++++++++++ .../qr-code-dot-shapes.component.ts} | 8 +++---- .../qr-code-error-correction.component.scss | 1 + .../qr-code-shapes.component.html | 12 ---------- .../qr-code-size/qr-code-size.component.scss | 1 + 11 files changed, 80 insertions(+), 21 deletions(-) create mode 100644 src/app/data-display/qr-code/qr-code-corner-shapes/qr-code-corner-shapes.component.html rename src/app/data-display/qr-code/{qr-code-shapes/qr-code-shapes.component.scss => qr-code-corner-shapes/qr-code-corner-shapes.component.scss} (89%) create mode 100644 src/app/data-display/qr-code/qr-code-corner-shapes/qr-code-corner-shapes.component.ts create mode 100644 src/app/data-display/qr-code/qr-code-dot-shapes/qr-code-dot-shapes.component.html create mode 100644 src/app/data-display/qr-code/qr-code-dot-shapes/qr-code-dot-shapes.component.scss rename src/app/data-display/qr-code/{qr-code-shapes/qr-code-shapes.component.ts => qr-code-dot-shapes/qr-code-dot-shapes.component.ts} (55%) delete mode 100644 src/app/data-display/qr-code/qr-code-shapes/qr-code-shapes.component.html diff --git a/src/app/data-display/data-display-routes-data.ts b/src/app/data-display/data-display-routes-data.ts index 6dce452ba3..75e1bc7613 100644 --- a/src/app/data-display/data-display-routes-data.ts +++ b/src/app/data-display/data-display-routes-data.ts @@ -47,7 +47,8 @@ export const dataDisplayRoutesData = { "qr-code-overview": { displayName: "Overview", parentName: "QR Code" }, "qr-code-error-correction": { displayName: "QR Code Error Correction", parentName: "QR Code" }, "qr-code-size": { displayName: "QR Code Size", parentName: "QR Code" }, - "qr-code-shapes": { displayName: "QR Code Shapes", parentName: "QR Code" }, + "qr-code-dot-shapes": { displayName: "QR Code Dot Shapes", parentName: "QR Code" }, + "qr-code-corner-shapes": { displayName: "QR Code Corner Shapes", parentName: "QR Code" }, "qr-code-logo": { displayName: "QR Code Logo", parentName: "QR Code" }, "qr-code-styling": { displayName: "QR Code Styling", parentName: "QR Code" }, "qr-code-tailwind-styling": { displayName: "QR Code Tailwind Styling", parentName: "QR Code" } diff --git a/src/app/data-display/data-display.routes.ts b/src/app/data-display/data-display.routes.ts index 16ede57200..c5bc2f3584 100644 --- a/src/app/data-display/data-display.routes.ts +++ b/src/app/data-display/data-display.routes.ts @@ -56,7 +56,8 @@ import { dataDisplayRoutesData } from './data-display-routes-data'; import { Routes } from '@angular/router'; import { QrCodeErrorCorrectionComponent } from './qr-code/qr-code-error-correction/qr-code-error-correction.component'; import { QrCodeSizeComponent } from './qr-code/qr-code-size/qr-code-size.component'; -import { QrCodeShapesComponent } from './qr-code/qr-code-shapes/qr-code-shapes.component'; +import { QrCodeDotShapesComponent } from './qr-code/qr-code-dot-shapes/qr-code-dot-shapes.component'; +import { QrCodeCornerShapesComponent } from './qr-code/qr-code-corner-shapes/qr-code-corner-shapes.component'; import { QrCodeLogoComponent } from './qr-code/qr-code-logo/qr-code-logo.component'; export const DataDisplayRoutes: Routes = [ @@ -311,9 +312,14 @@ export const DataDisplayRoutes: Routes = [ path: 'qr-code-styling' }, { - component: QrCodeShapesComponent, - data: dataDisplayRoutesData['qr-code-shapes'], - path: 'qr-code-shapes' + component: QrCodeDotShapesComponent, + data: dataDisplayRoutesData['qr-code-dot-shapes'], + path: 'qr-code-dot-shapes' + }, + { + component: QrCodeCornerShapesComponent, + data: dataDisplayRoutesData['qr-code-corner-shapes'], + path: 'qr-code-corner-shapes' }, { component: QrCodeLogoComponent, diff --git a/src/app/data-display/qr-code/qr-code-corner-shapes/qr-code-corner-shapes.component.html b/src/app/data-display/qr-code/qr-code-corner-shapes/qr-code-corner-shapes.component.html new file mode 100644 index 0000000000..3727a0191d --- /dev/null +++ b/src/app/data-display/qr-code/qr-code-corner-shapes/qr-code-corner-shapes.component.html @@ -0,0 +1,12 @@ +
+ + square style: square +
+
+ + square style: circle +
+
+ + square style: rounded +
diff --git a/src/app/data-display/qr-code/qr-code-shapes/qr-code-shapes.component.scss b/src/app/data-display/qr-code/qr-code-corner-shapes/qr-code-corner-shapes.component.scss similarity index 89% rename from src/app/data-display/qr-code/qr-code-shapes/qr-code-shapes.component.scss rename to src/app/data-display/qr-code/qr-code-corner-shapes/qr-code-corner-shapes.component.scss index 49f1e101cc..a289e861f7 100644 --- a/src/app/data-display/qr-code/qr-code-shapes/qr-code-shapes.component.scss +++ b/src/app/data-display/qr-code/qr-code-corner-shapes/qr-code-corner-shapes.component.scss @@ -6,6 +6,7 @@ flex-direction: row; overflow-y: auto; height: 100%; + font-family: "Aktiv Grotesk", sans-serif; } div { diff --git a/src/app/data-display/qr-code/qr-code-corner-shapes/qr-code-corner-shapes.component.ts b/src/app/data-display/qr-code/qr-code-corner-shapes/qr-code-corner-shapes.component.ts new file mode 100644 index 0000000000..a8c806359c --- /dev/null +++ b/src/app/data-display/qr-code/qr-code-corner-shapes/qr-code-corner-shapes.component.ts @@ -0,0 +1,13 @@ +import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { defineComponents, IgcQrCodeComponent } from 'igniteui-webcomponents'; + +defineComponents(IgcQrCodeComponent); + +@Component({ + selector: 'app-qr-code-corner-shapes', + templateUrl: './qr-code-corner-shapes.component.html', + styleUrls: ['./qr-code-corner-shapes.component.scss'], + schemas: [CUSTOM_ELEMENTS_SCHEMA], +}) +export class QrCodeCornerShapesComponent { +} diff --git a/src/app/data-display/qr-code/qr-code-dot-shapes/qr-code-dot-shapes.component.html b/src/app/data-display/qr-code/qr-code-dot-shapes/qr-code-dot-shapes.component.html new file mode 100644 index 0000000000..154b5ffe63 --- /dev/null +++ b/src/app/data-display/qr-code/qr-code-dot-shapes/qr-code-dot-shapes.component.html @@ -0,0 +1,12 @@ +
+ + dot style: square +
+
+ + dot style: circle +
+
+ + dot style: rounded +
diff --git a/src/app/data-display/qr-code/qr-code-dot-shapes/qr-code-dot-shapes.component.scss b/src/app/data-display/qr-code/qr-code-dot-shapes/qr-code-dot-shapes.component.scss new file mode 100644 index 0000000000..a289e861f7 --- /dev/null +++ b/src/app/data-display/qr-code/qr-code-dot-shapes/qr-code-dot-shapes.component.scss @@ -0,0 +1,24 @@ +:host { + display: flex; + align-items: flex-start; + gap: 3.75rem; + justify-content: center; + flex-direction: row; + overflow-y: auto; + height: 100%; + font-family: "Aktiv Grotesk", sans-serif; +} + +div { + display: flex; + flex-direction: column; + align-items: center; +} + +@media (width < 850px) { + :host { + flex-direction: column; + align-items: center; + justify-content: flex-start; + } +} \ No newline at end of file diff --git a/src/app/data-display/qr-code/qr-code-shapes/qr-code-shapes.component.ts b/src/app/data-display/qr-code/qr-code-dot-shapes/qr-code-dot-shapes.component.ts similarity index 55% rename from src/app/data-display/qr-code/qr-code-shapes/qr-code-shapes.component.ts rename to src/app/data-display/qr-code/qr-code-dot-shapes/qr-code-dot-shapes.component.ts index 42ac4674c7..a41518855d 100644 --- a/src/app/data-display/qr-code/qr-code-shapes/qr-code-shapes.component.ts +++ b/src/app/data-display/qr-code/qr-code-dot-shapes/qr-code-dot-shapes.component.ts @@ -4,10 +4,10 @@ import { defineComponents, IgcQrCodeComponent } from 'igniteui-webcomponents'; defineComponents(IgcQrCodeComponent); @Component({ - selector: 'app-qr-code-shapes', - templateUrl: './qr-code-shapes.component.html', - styleUrls: ['./qr-code-shapes.component.scss'], + selector: 'app-qr-code-dot-shapes', + templateUrl: './qr-code-dot-shapes.component.html', + styleUrls: ['./qr-code-dot-shapes.component.scss'], schemas: [CUSTOM_ELEMENTS_SCHEMA], }) -export class QrCodeShapesComponent { +export class QrCodeDotShapesComponent { } diff --git a/src/app/data-display/qr-code/qr-code-error-correction/qr-code-error-correction.component.scss b/src/app/data-display/qr-code/qr-code-error-correction/qr-code-error-correction.component.scss index 49f1e101cc..a289e861f7 100644 --- a/src/app/data-display/qr-code/qr-code-error-correction/qr-code-error-correction.component.scss +++ b/src/app/data-display/qr-code/qr-code-error-correction/qr-code-error-correction.component.scss @@ -6,6 +6,7 @@ flex-direction: row; overflow-y: auto; height: 100%; + font-family: "Aktiv Grotesk", sans-serif; } div { diff --git a/src/app/data-display/qr-code/qr-code-shapes/qr-code-shapes.component.html b/src/app/data-display/qr-code/qr-code-shapes/qr-code-shapes.component.html deleted file mode 100644 index bf7afd0619..0000000000 --- a/src/app/data-display/qr-code/qr-code-shapes/qr-code-shapes.component.html +++ /dev/null @@ -1,12 +0,0 @@ -
- - dot and square style: square -
-
- > - dot and square style: circle -
-
- > - dot and square style: rounded -
diff --git a/src/app/data-display/qr-code/qr-code-size/qr-code-size.component.scss b/src/app/data-display/qr-code/qr-code-size/qr-code-size.component.scss index 561d30de2e..05177afe34 100644 --- a/src/app/data-display/qr-code/qr-code-size/qr-code-size.component.scss +++ b/src/app/data-display/qr-code/qr-code-size/qr-code-size.component.scss @@ -6,6 +6,7 @@ flex-direction: row; overflow-y: auto; height: 100%; + font-family: "Aktiv Grotesk", sans-serif; } div { From 5ff2e38e034d9fda50577f35691c29a6e0df2060 Mon Sep 17 00:00:00 2001 From: Stamen Stoychev Date: Wed, 23 Sep 2026 14:24:06 +0300 Subject: [PATCH 14/22] feat(*): updating to rc.1 --- package-lock.json | 32 +++++++++---------- package.json | 10 +++--- .../data-analysis-dock-manager.component.scss | 8 ++--- ...upby-summary-styling-sample.component.scss | 1 - .../tree-grid-summary-styling.component.scss | 1 - 5 files changed, 25 insertions(+), 27 deletions(-) diff --git a/package-lock.json b/package-lock.json index f1400169da..9f3c5f8b47 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,11 +34,11 @@ "express": "^4.18.2", "file-saver": "^2.0.2", "fuse.js": "^7.1.0", - "igniteui-angular": "22.1.0", + "igniteui-angular": "22.2.0-rc.1", "igniteui-angular-charts": "^22.0.0", "igniteui-angular-core": "^22.0.0", - "igniteui-angular-extras": "22.1.0", - "igniteui-angular-i18n": "22.1.0", + "igniteui-angular-extras": "22.2.0-rc.1", + "igniteui-angular-i18n": "22.2.0-rc.1", "igniteui-dockmanager": "^1.17.0", "igniteui-grid-lite": "0.10.0", "igniteui-i18n-resources": "^1.0.4", @@ -10455,15 +10455,15 @@ "license": "BSD-3-Clause" }, "node_modules/igniteui-angular": { - "version": "22.1.0", - "resolved": "https://registry.npmjs.org/igniteui-angular/-/igniteui-angular-22.1.0.tgz", - "integrity": "sha512-05Wdj9RvkIVm6wYyZFNdqi0oS/P9IKhrUAnwVzQ8nW8i5NHA13Fn+a6ZY3q/SKXyBc5C2Sb5ZyBL2DwK1Bbxrg==", + "version": "22.2.0-rc.1", + "resolved": "https://registry.npmjs.org/igniteui-angular/-/igniteui-angular-22.2.0-rc.1.tgz", + "integrity": "sha512-2+M+q/AYFby0Hhlj3DSaCBda32mEr7RIpUV/auuJiE5FwtSQ3fihpMB8rjE7L7ykvIy0Ams9FaIcHq0DS12Yow==", "license": "SEE LICENSE IN LICENSE", "dependencies": { "@igniteui/material-icons-extended": "^3.1.0", "fflate": "^0.8.2", "igniteui-i18n-core": "^1.0.5", - "igniteui-theming": "^28.1.1", + "igniteui-theming": "^29.0.0", "igniteui-trial-watermark": "^3.1.0", "jspdf": "^4.2.1", "lodash-es": "^4.17.21", @@ -10516,9 +10516,9 @@ } }, "node_modules/igniteui-angular-extras": { - "version": "22.1.0", - "resolved": "https://registry.npmjs.org/igniteui-angular-extras/-/igniteui-angular-extras-22.1.0.tgz", - "integrity": "sha512-6uGpfV6hbH/FPegXBAdiCtiwp8Qq0/mqcBUw5S2kFkUyQoaIaESvgtzCE0swi153NpHPA36OhWGKq5jbw0vsqQ==", + "version": "22.2.0-rc.1", + "resolved": "https://registry.npmjs.org/igniteui-angular-extras/-/igniteui-angular-extras-22.2.0-rc.1.tgz", + "integrity": "sha512-18eDYPWxGqA26BQpzjyKIWAjs3BRazt+AfwQXgkIVAidOnFozkxil7Z4EoSiUWg6d8sDXZo/SIRjIs4vtJ+LHA==", "license": "SEE LICENSE IN LICENSE", "dependencies": { "igniteui-trial-watermark": "^3.1.0", @@ -10533,9 +10533,9 @@ } }, "node_modules/igniteui-angular-i18n": { - "version": "22.1.0", - "resolved": "https://registry.npmjs.org/igniteui-angular-i18n/-/igniteui-angular-i18n-22.1.0.tgz", - "integrity": "sha512-rwGcf7ZUNp7mLU2K5FhsGEWX/8v6EZYitlDLlbLYZL/O2oFZISBfJRvzqi3GLJhEINJTE4Q8h8FNrjhz0tj8RQ==", + "version": "22.2.0-rc.1", + "resolved": "https://registry.npmjs.org/igniteui-angular-i18n/-/igniteui-angular-i18n-22.2.0-rc.1.tgz", + "integrity": "sha512-ukhFVO8nZwbs29pRxkiYW5hktuA7hAlqbII3v4S6+Dy4jGWWH5NVrXwSxirOHBK6Q28aOF3T2mGhBBU3RAizwA==", "license": "MIT", "dependencies": { "igniteui-i18n-core": "^1.0.2", @@ -10602,9 +10602,9 @@ "license": "MIT" }, "node_modules/igniteui-theming": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/igniteui-theming/-/igniteui-theming-28.1.1.tgz", - "integrity": "sha512-ioNSE9t36nqNfItashgM6oZxfgiLPjzeJ4X2g++3kU9oU0kklkz1Ax9F0FmGiwyIC2atWELkb76LsyT+0ZSTSQ==", + "version": "29.0.0", + "resolved": "https://registry.npmjs.org/igniteui-theming/-/igniteui-theming-29.0.0.tgz", + "integrity": "sha512-WpOJs6xX+VKG7uO2Dvkb1EmmXVDj+vnUCnlwmr6XCflgKv3baJLDDb3b/APWMLjPggDFxysrpgqAr6QHuI55Bw==", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.28.0", diff --git a/package.json b/package.json index 2ca6bbe650..c69b545669 100644 --- a/package.json +++ b/package.json @@ -71,11 +71,11 @@ "express": "^4.18.2", "file-saver": "^2.0.2", "fuse.js": "^7.1.0", - "igniteui-angular": "22.1.0", + "igniteui-angular": "22.2.0-rc.1", "igniteui-angular-charts": "^22.0.0", "igniteui-angular-core": "^22.0.0", - "igniteui-angular-extras": "22.1.0", - "igniteui-angular-i18n": "22.1.0", + "igniteui-angular-extras": "22.2.0-rc.1", + "igniteui-angular-i18n": "22.2.0-rc.1", "igniteui-dockmanager": "^1.17.0", "igniteui-grid-lite": "0.10.0", "igniteui-i18n-resources": "^1.0.4", @@ -110,8 +110,8 @@ "@angular/compiler": "^22.0.0" }, "igniteui-angular-extras": { - "igniteui-angular": "22.1.0", - "@infragistics/igniteui-angular": "^22.0.0", + "igniteui-angular": "22.2.0-rc.1", + "@infragistics/igniteui-angular": "^22.2.0-rc.1", "igniteui-angular-core": "^22.0.0", "igniteui-angular-charts": "^22.0.0", "@angular/core": "^22.0.0", diff --git a/projects/app-lob/src/app/grid-dynamic-chart-data/data-analysis-dock-manager/data-analysis-dock-manager.component.scss b/projects/app-lob/src/app/grid-dynamic-chart-data/data-analysis-dock-manager/data-analysis-dock-manager.component.scss index 8e1de676e3..5ed51b7c00 100644 --- a/projects/app-lob/src/app/grid-dynamic-chart-data/data-analysis-dock-manager/data-analysis-dock-manager.component.scss +++ b/projects/app-lob/src/app/grid-dynamic-chart-data/data-analysis-dock-manager/data-analysis-dock-manager.component.scss @@ -32,7 +32,7 @@ .selection-area { - @include scrollbar(scrollbar-theme($sb-size: 6px)); + @include scrollbar(scrollbar-theme()); width: 100%; height: 90%; display: inline-flex; @@ -91,7 +91,7 @@ $custom-badge-theme: badge-theme( .grid-chart-contextmenu-wrapper { igx-grid { - @include scrollbar(scrollbar-theme($sb-size: 16px)); + @include scrollbar(scrollbar-theme()); } } @@ -124,7 +124,7 @@ $custom-badge-theme: badge-theme( } igx-tab-content { - @include scrollbar(scrollbar-theme($sb-size: 10px)); + @include scrollbar(scrollbar-theme()); } } @@ -146,7 +146,7 @@ $custom-badge-theme: badge-theme( $font-family: 'Titillium Web', 'Roboto', 'Helvetica Neue', sans-serif; .tab-options-wrapper { - @include scrollbar(scrollbar-theme($sb-size: 6px)); + @include scrollbar(scrollbar-theme()); display: flex; flex-flow: column; diff --git a/src/app/grid/grid-groupby-summary-styling-sample/grid-groupby-summary-styling-sample.component.scss b/src/app/grid/grid-groupby-summary-styling-sample/grid-groupby-summary-styling-sample.component.scss index 0ade0da842..e886abfc87 100644 --- a/src/app/grid/grid-groupby-summary-styling-sample/grid-groupby-summary-styling-sample.component.scss +++ b/src/app/grid/grid-groupby-summary-styling-sample/grid-groupby-summary-styling-sample.component.scss @@ -7,7 +7,6 @@ $custom-theme: grid-summary-theme( $background-color: $summaries-background, $label-color: #e41c77, $result-color: black, - $pinned-border-width: 2px, $pinned-border-style: dotted, $pinned-border-color: #e41c77, ); diff --git a/src/app/tree-grid/tree-grid-summary-styling/tree-grid-summary-styling.component.scss b/src/app/tree-grid/tree-grid-summary-styling/tree-grid-summary-styling.component.scss index 07c3707c3a..6013b5f3df 100644 --- a/src/app/tree-grid/tree-grid-summary-styling/tree-grid-summary-styling.component.scss +++ b/src/app/tree-grid/tree-grid-summary-styling/tree-grid-summary-styling.component.scss @@ -7,7 +7,6 @@ $custom-theme: grid-summary-theme( $background-color: $summaries-background, $label-color: #486821, $result-color: #172505, - $pinned-border-width: 2px, $pinned-border-style: dotted, $pinned-border-color: #172505, ); From 0278c37719d4413dac0b2a077fb20d8b086cd205 Mon Sep 17 00:00:00 2001 From: Adrian Petrov Date: Wed, 23 Sep 2026 15:17:26 +0300 Subject: [PATCH 15/22] fix(): lint errors + change font color on some samples --- .../qr-code-corner-shapes.component.html | 6 +++--- .../qr-code-corner-shapes.component.scss | 5 +++++ .../qr-code-corner-shapes.component.ts | 2 +- .../qr-code-dot-shapes/qr-code-dot-shapes.component.html | 6 +++--- .../qr-code-dot-shapes/qr-code-dot-shapes.component.scss | 5 +++++ .../qr-code-dot-shapes/qr-code-dot-shapes.component.ts | 2 +- .../qr-code-error-correction.component.html | 6 +++--- .../qr-code-error-correction.component.scss | 5 +++++ .../qr-code-error-correction.component.ts | 2 +- .../qr-code/qr-code-logo/qr-code-logo.component.ts | 2 +- .../qr-code-overview/qr-code-overview.component.ts | 2 +- .../qr-code/qr-code-size/qr-code-size.component.html | 6 +++--- .../qr-code/qr-code-size/qr-code-size.component.scss | 5 +++++ .../qr-code/qr-code-size/qr-code-size.component.ts | 2 +- .../qr-code/qr-code-styling/qr-code-styling.component.ts | 2 +- .../qr-code-tailwind-styling.component.html | 8 ++++---- .../qr-code-tailwind-styling.component.ts | 3 +-- 17 files changed, 44 insertions(+), 25 deletions(-) diff --git a/src/app/data-display/qr-code/qr-code-corner-shapes/qr-code-corner-shapes.component.html b/src/app/data-display/qr-code/qr-code-corner-shapes/qr-code-corner-shapes.component.html index 3727a0191d..9d4298ed79 100644 --- a/src/app/data-display/qr-code/qr-code-corner-shapes/qr-code-corner-shapes.component.html +++ b/src/app/data-display/qr-code/qr-code-corner-shapes/qr-code-corner-shapes.component.html @@ -1,12 +1,12 @@
- square style: square + Square style: square
- square style: circle + Square style: circle
- square style: rounded + Square style: rounded
diff --git a/src/app/data-display/qr-code/qr-code-corner-shapes/qr-code-corner-shapes.component.scss b/src/app/data-display/qr-code/qr-code-corner-shapes/qr-code-corner-shapes.component.scss index a289e861f7..29dc353065 100644 --- a/src/app/data-display/qr-code/qr-code-corner-shapes/qr-code-corner-shapes.component.scss +++ b/src/app/data-display/qr-code/qr-code-corner-shapes/qr-code-corner-shapes.component.scss @@ -15,6 +15,11 @@ div { align-items: center; } +span { + margin-block-start: 1rem; + color: var(--ig-gray-600); +} + @media (width < 850px) { :host { flex-direction: column; diff --git a/src/app/data-display/qr-code/qr-code-corner-shapes/qr-code-corner-shapes.component.ts b/src/app/data-display/qr-code/qr-code-corner-shapes/qr-code-corner-shapes.component.ts index a8c806359c..882bfce599 100644 --- a/src/app/data-display/qr-code/qr-code-corner-shapes/qr-code-corner-shapes.component.ts +++ b/src/app/data-display/qr-code/qr-code-corner-shapes/qr-code-corner-shapes.component.ts @@ -7,7 +7,7 @@ defineComponents(IgcQrCodeComponent); selector: 'app-qr-code-corner-shapes', templateUrl: './qr-code-corner-shapes.component.html', styleUrls: ['./qr-code-corner-shapes.component.scss'], - schemas: [CUSTOM_ELEMENTS_SCHEMA], + schemas: [CUSTOM_ELEMENTS_SCHEMA] }) export class QrCodeCornerShapesComponent { } diff --git a/src/app/data-display/qr-code/qr-code-dot-shapes/qr-code-dot-shapes.component.html b/src/app/data-display/qr-code/qr-code-dot-shapes/qr-code-dot-shapes.component.html index 154b5ffe63..af3cf80ce3 100644 --- a/src/app/data-display/qr-code/qr-code-dot-shapes/qr-code-dot-shapes.component.html +++ b/src/app/data-display/qr-code/qr-code-dot-shapes/qr-code-dot-shapes.component.html @@ -1,12 +1,12 @@
- dot style: square + Dot style: square
- dot style: circle + Dot style: circle
- dot style: rounded + Dot style: rounded
diff --git a/src/app/data-display/qr-code/qr-code-dot-shapes/qr-code-dot-shapes.component.scss b/src/app/data-display/qr-code/qr-code-dot-shapes/qr-code-dot-shapes.component.scss index a289e861f7..29dc353065 100644 --- a/src/app/data-display/qr-code/qr-code-dot-shapes/qr-code-dot-shapes.component.scss +++ b/src/app/data-display/qr-code/qr-code-dot-shapes/qr-code-dot-shapes.component.scss @@ -15,6 +15,11 @@ div { align-items: center; } +span { + margin-block-start: 1rem; + color: var(--ig-gray-600); +} + @media (width < 850px) { :host { flex-direction: column; diff --git a/src/app/data-display/qr-code/qr-code-dot-shapes/qr-code-dot-shapes.component.ts b/src/app/data-display/qr-code/qr-code-dot-shapes/qr-code-dot-shapes.component.ts index a41518855d..8ad0cc61e0 100644 --- a/src/app/data-display/qr-code/qr-code-dot-shapes/qr-code-dot-shapes.component.ts +++ b/src/app/data-display/qr-code/qr-code-dot-shapes/qr-code-dot-shapes.component.ts @@ -7,7 +7,7 @@ defineComponents(IgcQrCodeComponent); selector: 'app-qr-code-dot-shapes', templateUrl: './qr-code-dot-shapes.component.html', styleUrls: ['./qr-code-dot-shapes.component.scss'], - schemas: [CUSTOM_ELEMENTS_SCHEMA], + schemas: [CUSTOM_ELEMENTS_SCHEMA] }) export class QrCodeDotShapesComponent { } diff --git a/src/app/data-display/qr-code/qr-code-error-correction/qr-code-error-correction.component.html b/src/app/data-display/qr-code/qr-code-error-correction/qr-code-error-correction.component.html index faa3fa0f9a..be9ca34e2e 100644 --- a/src/app/data-display/qr-code/qr-code-error-correction/qr-code-error-correction.component.html +++ b/src/app/data-display/qr-code/qr-code-error-correction/qr-code-error-correction.component.html @@ -1,12 +1,12 @@
> - error-level: L + Error level: L
> - error-level: M + Error level: M
> - error-level: Q + Error level: Q
diff --git a/src/app/data-display/qr-code/qr-code-error-correction/qr-code-error-correction.component.scss b/src/app/data-display/qr-code/qr-code-error-correction/qr-code-error-correction.component.scss index a289e861f7..29dc353065 100644 --- a/src/app/data-display/qr-code/qr-code-error-correction/qr-code-error-correction.component.scss +++ b/src/app/data-display/qr-code/qr-code-error-correction/qr-code-error-correction.component.scss @@ -15,6 +15,11 @@ div { align-items: center; } +span { + margin-block-start: 1rem; + color: var(--ig-gray-600); +} + @media (width < 850px) { :host { flex-direction: column; diff --git a/src/app/data-display/qr-code/qr-code-error-correction/qr-code-error-correction.component.ts b/src/app/data-display/qr-code/qr-code-error-correction/qr-code-error-correction.component.ts index f6a9e2d59c..3790218fca 100644 --- a/src/app/data-display/qr-code/qr-code-error-correction/qr-code-error-correction.component.ts +++ b/src/app/data-display/qr-code/qr-code-error-correction/qr-code-error-correction.component.ts @@ -7,7 +7,7 @@ defineComponents(IgcQrCodeComponent); selector: 'app-qr-code-error-correction', templateUrl: './qr-code-error-correction.component.html', styleUrls: ['./qr-code-error-correction.component.scss'], - schemas: [CUSTOM_ELEMENTS_SCHEMA], + schemas: [CUSTOM_ELEMENTS_SCHEMA] }) export class QrCodeErrorCorrectionComponent { } diff --git a/src/app/data-display/qr-code/qr-code-logo/qr-code-logo.component.ts b/src/app/data-display/qr-code/qr-code-logo/qr-code-logo.component.ts index 63ad259ef5..03601dda0a 100644 --- a/src/app/data-display/qr-code/qr-code-logo/qr-code-logo.component.ts +++ b/src/app/data-display/qr-code/qr-code-logo/qr-code-logo.component.ts @@ -7,7 +7,7 @@ defineComponents(IgcQrCodeComponent); selector: 'app-qr-code-logo', templateUrl: './qr-code-logo.component.html', styleUrls: ['./qr-code-logo.component.scss'], - schemas: [CUSTOM_ELEMENTS_SCHEMA], + schemas: [CUSTOM_ELEMENTS_SCHEMA] }) export class QrCodeLogoComponent { public readonly logoSrc = 'https://static.infragistics.com/marketing/Website/products/ignite-ui/shared/ignite-ui-logo-light-background-horizontal.svg'; diff --git a/src/app/data-display/qr-code/qr-code-overview/qr-code-overview.component.ts b/src/app/data-display/qr-code/qr-code-overview/qr-code-overview.component.ts index c5f3729bde..90bdb47186 100644 --- a/src/app/data-display/qr-code/qr-code-overview/qr-code-overview.component.ts +++ b/src/app/data-display/qr-code/qr-code-overview/qr-code-overview.component.ts @@ -11,7 +11,7 @@ defineComponents(IgcQrCodeComponent); templateUrl: './qr-code-overview.component.html', styleUrls: ['./qr-code-overview.component.scss'], schemas: [CUSTOM_ELEMENTS_SCHEMA], - imports: [FormsModule, IgxRadioGroupDirective, IgxRadioComponent, IgxSwitchComponent], + imports: [FormsModule, IgxRadioGroupDirective, IgxRadioComponent, IgxSwitchComponent] }) export class QrCodeOverviewComponent { public shape: 'square' | 'circle' | 'rounded' = 'square'; diff --git a/src/app/data-display/qr-code/qr-code-size/qr-code-size.component.html b/src/app/data-display/qr-code/qr-code-size/qr-code-size.component.html index ec38f6605a..dc437fda32 100644 --- a/src/app/data-display/qr-code/qr-code-size/qr-code-size.component.html +++ b/src/app/data-display/qr-code/qr-code-size/qr-code-size.component.html @@ -1,12 +1,12 @@
> - size: 128px + Size: 128px
> - size: 192px + Size: 192px
> - size: 256px + Size: 256px
\ No newline at end of file diff --git a/src/app/data-display/qr-code/qr-code-size/qr-code-size.component.scss b/src/app/data-display/qr-code/qr-code-size/qr-code-size.component.scss index 05177afe34..0219154c6a 100644 --- a/src/app/data-display/qr-code/qr-code-size/qr-code-size.component.scss +++ b/src/app/data-display/qr-code/qr-code-size/qr-code-size.component.scss @@ -15,6 +15,11 @@ div { align-items: center; } +span { + margin-block-start: 1rem; + color: var(--ig-gray-600); +} + @media (width < 850px) { :host { flex-direction: column; diff --git a/src/app/data-display/qr-code/qr-code-size/qr-code-size.component.ts b/src/app/data-display/qr-code/qr-code-size/qr-code-size.component.ts index 693fbe9693..173efa4b85 100644 --- a/src/app/data-display/qr-code/qr-code-size/qr-code-size.component.ts +++ b/src/app/data-display/qr-code/qr-code-size/qr-code-size.component.ts @@ -7,7 +7,7 @@ defineComponents(IgcQrCodeComponent); selector: 'app-qr-code-size', templateUrl: './qr-code-size.component.html', styleUrls: ['./qr-code-size.component.scss'], - schemas: [CUSTOM_ELEMENTS_SCHEMA], + schemas: [CUSTOM_ELEMENTS_SCHEMA] }) export class QrCodeSizeComponent { public readonly value = 'https://www.infragistics.com/products/ignite-ui-web-components'; diff --git a/src/app/data-display/qr-code/qr-code-styling/qr-code-styling.component.ts b/src/app/data-display/qr-code/qr-code-styling/qr-code-styling.component.ts index c2165eaee4..7fa8456031 100644 --- a/src/app/data-display/qr-code/qr-code-styling/qr-code-styling.component.ts +++ b/src/app/data-display/qr-code/qr-code-styling/qr-code-styling.component.ts @@ -7,7 +7,7 @@ defineComponents(IgcQrCodeComponent); selector: 'app-qr-code-styling', templateUrl: './qr-code-styling.component.html', styleUrls: ['./qr-code-styling.component.scss'], - schemas: [CUSTOM_ELEMENTS_SCHEMA], + schemas: [CUSTOM_ELEMENTS_SCHEMA] }) export class QrCodeStylingComponent { public readonly value = 'https://www.infragistics.com/products/ignite-ui-web-components'; diff --git a/src/app/data-display/qr-code/qr-code-tailwind-styling/qr-code-tailwind-styling.component.html b/src/app/data-display/qr-code/qr-code-tailwind-styling/qr-code-tailwind-styling.component.html index 7e10177508..22a1bb3e2d 100644 --- a/src/app/data-display/qr-code/qr-code-tailwind-styling/qr-code-tailwind-styling.component.html +++ b/src/app/data-display/qr-code/qr-code-tailwind-styling/qr-code-tailwind-styling.component.html @@ -2,18 +2,18 @@ + class="!light-qr-code [--ig-qr-code-dark-color:#1a1a1a] [--ig-qr-code-background:#f7df1e] [--ig-qr-code-corner-square-color:#1a1a1a] [--ig-qr-code-corner-dot-color:#1a1a1a]"> + class="!light-qr-code [--ig-qr-code-dark-color:#ffffff] [--ig-qr-code-background:#e44d26] [--ig-qr-code-corner-square-color:#ffffff] [--ig-qr-code-corner-dot-color:#ffffff]"> + class="!light-qr-code [--ig-qr-code-dark-color:#ffffff] [--ig-qr-code-background:#1572b6] [--ig-qr-code-corner-square-color:#ffffff] [--ig-qr-code-corner-dot-color:#ffffff]"> + class="!light-qr-code [--ig-qr-code-dark-color:#0f172a] [--ig-qr-code-background:#ffffff] [--ig-qr-code-corner-square-color:#0f172a] [--ig-qr-code-corner-dot-color:#0f172a]">
\ No newline at end of file diff --git a/src/app/data-display/qr-code/qr-code-tailwind-styling/qr-code-tailwind-styling.component.ts b/src/app/data-display/qr-code/qr-code-tailwind-styling/qr-code-tailwind-styling.component.ts index 171cb8654f..16a0739ba4 100644 --- a/src/app/data-display/qr-code/qr-code-tailwind-styling/qr-code-tailwind-styling.component.ts +++ b/src/app/data-display/qr-code/qr-code-tailwind-styling/qr-code-tailwind-styling.component.ts @@ -7,7 +7,6 @@ defineComponents(IgcQrCodeComponent); selector: 'app-qr-code-tailwind-styling', templateUrl: './qr-code-tailwind-styling.component.html', styleUrls: ['./qr-code-tailwind-styling.component.scss'], - schemas: [CUSTOM_ELEMENTS_SCHEMA], - imports: [] + schemas: [CUSTOM_ELEMENTS_SCHEMA] }) export class QrCodeTailwindStylingComponent { } From e6263957573b16f4e6562947eff913bc890432d6 Mon Sep 17 00:00:00 2001 From: Marin Popov Date: Wed, 23 Sep 2026 18:09:19 +0300 Subject: [PATCH 16/22] Merge pull request #4020 from IgniteUI/mpopov/update-samples-styles refactor(button-group): update styles and simplify layout structure across all samples --- .../configs/ButtonGroupConfigGenerator.ts | 1 - .../badge/badge-dot/badge-dot.component.scss | 8 +- .../badge-icon/badge-icon.component.scss | 7 +- .../badge-outlined.component.scss | 4 +- .../badge-shape/badge-shape.component.scss | 7 +- .../badge-size/badge-size.component.scss | 7 +- .../badge-type/badge-type.component.scss | 7 +- .../badge-variants.component.scss | 7 +- .../button/_bootstrap-button-theme.scss | 61 --------- .../button-contained.component.scss | 2 - .../button-download.component.scss | 2 - .../button-fab/button-fab.component.scss | 2 - .../button-flat/button-flat.component.scss | 2 - .../button-interaction-states.component.scss | 1 - .../button-layout.component.scss | 2 - .../button-outlined.component.scss | 2 - .../button-overview.component.scss | 2 - .../button-size/button-size.component.scss | 2 - .../button-states.component.scss | 2 - .../button-group-alignment.component.html | 6 +- .../button-group-alignment.component.scss | 47 +++---- .../button-group-custom-toggle.component.html | 4 +- .../button-group-custom-toggle.component.scss | 14 +- ...on-group-interaction-states.component.html | 37 ++--- ...on-group-interaction-states.component.scss | 128 ++++++++++++------ .../button-group-layout.component.html | 5 +- .../button-group-layout.component.scss | 25 ++-- .../button-group-overview.component.html | 6 +- .../button-group-overview.component.scss | 33 ++--- .../button-group-selection.component.html | 26 ++-- .../button-group-selection.component.scss | 58 +++++--- .../button-group-size.component.html | 18 +-- .../button-group-size.component.scss | 85 ++++++++---- .../button-group-states.component.html | 36 ++--- .../button-group-states.component.scss | 95 +++++++++---- .../button-group-styling.component.html | 12 +- .../button-group-styling.component.scss | 14 +- .../button-group-styling/layout.scss | 13 -- ...tton-group-tailwind-styling.component.html | 13 +- ...tton-group-tailwind-styling.component.scss | 24 ++-- .../button-group-tailwind-styling/layout.scss | 16 --- .../data-entries/switch/switch-bootstrap.scss | 65 --------- .../switch-disabled.component.scss | 8 -- .../switch-enabled.component.scss | 8 -- .../switch-layout.component.scss | 8 -- .../switch-overview.component.scss | 10 +- .../switch-selected.component.scss | 8 -- .../switch-styling.component.scss | 7 - .../switch-tailwind-styling.component.scss | 4 - .../avatar-shape/avatar-shape.component.scss | 5 + .../avatar-size/avatar-size.component.scss | 5 + .../avatar-variants.component.scss | 5 + src/index.html | 4 + 53 files changed, 472 insertions(+), 508 deletions(-) delete mode 100644 src/app/data-entries/button/_bootstrap-button-theme.scss delete mode 100644 src/app/data-entries/buttonGroup/button-group-styling/layout.scss delete mode 100644 src/app/data-entries/buttonGroup/button-group-tailwind-styling/layout.scss delete mode 100644 src/app/data-entries/switch/switch-bootstrap.scss diff --git a/live-editing/configs/ButtonGroupConfigGenerator.ts b/live-editing/configs/ButtonGroupConfigGenerator.ts index 9db78ec06d..64aeafcbc4 100644 --- a/live-editing/configs/ButtonGroupConfigGenerator.ts +++ b/live-editing/configs/ButtonGroupConfigGenerator.ts @@ -69,7 +69,6 @@ export class ButtonGroupConfigGenerator implements IConfigGenerator { // button group styling configs.push(new Config({ component: 'ButtonGroupStylingComponent', - additionalFiles: ["/src/app/data-entries/buttonGroup/button-group-styling/layout.scss"], appConfig: BaseAppConfig, shortenComponentPathBy: "/data-entries/buttonGroup/" })); diff --git a/src/app/data-display/badge/badge-dot/badge-dot.component.scss b/src/app/data-display/badge/badge-dot/badge-dot.component.scss index db1defa585..ffb0282478 100644 --- a/src/app/data-display/badge/badge-dot/badge-dot.component.scss +++ b/src/app/data-display/badge/badge-dot/badge-dot.component.scss @@ -2,7 +2,7 @@ @use "igniteui-theming/sass/typography" as *; :host { - --sample-accent: #0057a9; + --sample-accent: var(--ig-primary-800); display: grid; grid-auto-flow: column; @@ -21,6 +21,10 @@ igx-badge { translate: -50% -50%; } +igx-avatar.icon-anchor { + --ig-avatar-background: var(--ig-gray-300); +} + $anchors: icon, avatar; @each $anchor in $anchors { @@ -70,7 +74,7 @@ $anchors: icon, avatar; } .unread { - color: var(--sample-accent); + color: var(--ig-gray-900); font-weight: 600; } diff --git a/src/app/data-display/badge/badge-icon/badge-icon.component.scss b/src/app/data-display/badge/badge-icon/badge-icon.component.scss index 5dccea83e4..5f295bcc03 100644 --- a/src/app/data-display/badge/badge-icon/badge-icon.component.scss +++ b/src/app/data-display/badge/badge-icon/badge-icon.component.scss @@ -30,7 +30,12 @@ span { grid-row: 2; text-align: center; - color: var(--ig-gray-700); + color: var(--ig-gray-600); + font-family: "Aktiv Grotesk", sans-serif; + font-size: rem(13px); + font-weight: 400; + line-height: rem(20px); + letter-spacing: rem(0.3px); } igx-badge:last-of-type { diff --git a/src/app/data-display/badge/badge-outlined/badge-outlined.component.scss b/src/app/data-display/badge/badge-outlined/badge-outlined.component.scss index 7f7ef73214..4dd987fdd4 100644 --- a/src/app/data-display/badge/badge-outlined/badge-outlined.component.scss +++ b/src/app/data-display/badge/badge-outlined/badge-outlined.component.scss @@ -7,7 +7,7 @@ place-content: center; place-items: center; column-gap: rem(60px); - min-height: 7rem; + min-height: 100vh; padding-inline: rem(16px); ::ng-deep { @@ -55,7 +55,7 @@ igx-stepper { --ig-stepper-step-separator-style: dashed; --ig-stepper-step-separator-color: var(--ig-gray-400); - max-width: rem(316px); + inline-size: rem(320px); } span[igxStepIndicator] { diff --git a/src/app/data-display/badge/badge-shape/badge-shape.component.scss b/src/app/data-display/badge/badge-shape/badge-shape.component.scss index 8e7dfd50b4..5d38bab74a 100644 --- a/src/app/data-display/badge/badge-shape/badge-shape.component.scss +++ b/src/app/data-display/badge/badge-shape/badge-shape.component.scss @@ -13,7 +13,12 @@ span { justify-self: end; - color: var(--ig-gray-700); + color: var(--ig-gray-600); + font-family: "Aktiv Grotesk", sans-serif; + font-size: rem(13px); + font-weight: 400; + line-height: rem(20px); + letter-spacing: rem(0.3px); @include type-style("body-2") { margin: 0; diff --git a/src/app/data-display/badge/badge-size/badge-size.component.scss b/src/app/data-display/badge/badge-size/badge-size.component.scss index bdedf7a51b..7f2108c1b2 100644 --- a/src/app/data-display/badge/badge-size/badge-size.component.scss +++ b/src/app/data-display/badge/badge-size/badge-size.component.scss @@ -13,7 +13,12 @@ span { justify-self: end; - color: var(--ig-gray-700); + color: var(--ig-gray-600); + font-family: "Aktiv Grotesk", sans-serif; + font-size: rem(13px); + font-weight: 400; + line-height: rem(20px); + letter-spacing: rem(0.3px); @include type-style("body-2") { margin: 0; diff --git a/src/app/data-display/badge/badge-type/badge-type.component.scss b/src/app/data-display/badge/badge-type/badge-type.component.scss index 9b22c01142..ae272a6dc2 100644 --- a/src/app/data-display/badge/badge-type/badge-type.component.scss +++ b/src/app/data-display/badge/badge-type/badge-type.component.scss @@ -24,7 +24,12 @@ igx-avatar { span { grid-row: 2; text-align: center; - color: var(--ig-gray-700); + color: var(--ig-gray-600); + font-family: "Aktiv Grotesk", sans-serif; + font-size: rem(13px); + font-weight: 400; + line-height: rem(20px); + letter-spacing: rem(0.3px); @include type-style("caption") { margin: 0; diff --git a/src/app/data-display/badge/badge-variants/badge-variants.component.scss b/src/app/data-display/badge/badge-variants/badge-variants.component.scss index 7cbd9ac603..8f88e19dac 100644 --- a/src/app/data-display/badge/badge-variants/badge-variants.component.scss +++ b/src/app/data-display/badge/badge-variants/badge-variants.component.scss @@ -22,7 +22,12 @@ igx-avatar { span { grid-row: 2; text-align: center; - color: var(--ig-gray-700); + color: var(--ig-gray-600); + font-family: "Aktiv Grotesk", sans-serif; + font-size: rem(13px); + font-weight: 400; + line-height: rem(20px); + letter-spacing: rem(0.3px); @include type-style("body-2") { margin: 0; diff --git a/src/app/data-entries/button/_bootstrap-button-theme.scss b/src/app/data-entries/button/_bootstrap-button-theme.scss deleted file mode 100644 index 6ce81fd333..0000000000 --- a/src/app/data-entries/button/_bootstrap-button-theme.scss +++ /dev/null @@ -1,61 +0,0 @@ -@use 'igniteui-angular/theming' as *; -@use 'igniteui-angular/lib/core/styles/components/button/button-component' as button; -@use 'igniteui-angular/lib/core/styles/themes/presets/igniteui-bootstrap-light'; -@use 'igniteui-theming/sass/typography/presets' as typography-presets; - -:host ::ng-deep { - @include typography( - $font-family: typography-presets.$bootstrap-typeface, - $type-scale: typography-presets.$bootstrap-type-scale - ); - - @include button( - $flat: flat-button-theme( - $schema: $light-bootstrap-schema, - $foreground: color($light-bootstrap-palette, 'primary'), - $hover-foreground: color($light-bootstrap-palette, 'primary'), - $disabled-foreground: color($light-bootstrap-palette, 'primary', 200) - ), - $contained: contained-button-theme( - $schema: $light-bootstrap-schema, - $background: color($light-bootstrap-palette, 'primary'), - $foreground: var(--ig-gray-50), - $hover-background: color($light-bootstrap-palette, 'primary', 600), - $hover-foreground: var(--ig-gray-50), - $focus-background: color($light-bootstrap-palette, 'primary', 800), - $focus-foreground: var(--ig-gray-50), - $focus-hover-background: color($light-bootstrap-palette, 'primary', 600), - $focus-hover-foreground: var(--ig-gray-50), - $disabled-background: color($light-bootstrap-palette, 'primary', 50), - $disabled-foreground: color($light-bootstrap-palette, 'primary', 200) - ), - $outlined: outlined-button-theme( - $schema: $light-bootstrap-schema, - $foreground: color($light-bootstrap-palette, 'primary'), - $hover-background: color($light-bootstrap-palette, 'primary'), - $hover-foreground: var(--ig-gray-50), - $disabled-foreground: color($light-bootstrap-palette, 'primary', 200), - $disabled-border-color: color($light-bootstrap-palette, 'primary', 50) - ), - $fab: fab-button-theme( - $schema: $light-bootstrap-schema, - $background: color($light-bootstrap-palette, 'secondary'), - $foreground: var(--ig-gray-50), - $hover-background: color($light-bootstrap-palette, 'primary'), - $hover-foreground: var(--ig-gray-50), - $disabled-background: color($light-bootstrap-palette, 'gray', 300), - $disabled-foreground: color($light-bootstrap-palette, 'gray', 500), - $resting-shadow: none, - $hover-shadow: none - ) - ); - @include button.component(); - - [igxButton] { - --ig-size: var(--ig-size-medium); - } - - button[igxButton='fab'] { - --ig-size: var(--ig-size-large); - } -} diff --git a/src/app/data-entries/button/button-contained/button-contained.component.scss b/src/app/data-entries/button/button-contained/button-contained.component.scss index 2bfc8c5087..c98e6acd18 100644 --- a/src/app/data-entries/button/button-contained/button-contained.component.scss +++ b/src/app/data-entries/button/button-contained/button-contained.component.scss @@ -1,5 +1,3 @@ -@use '../_bootstrap-button-theme'; - .button-sample { display: flex; padding: 2.5rem; diff --git a/src/app/data-entries/button/button-download/button-download.component.scss b/src/app/data-entries/button/button-download/button-download.component.scss index 54492fe328..0809677340 100644 --- a/src/app/data-entries/button/button-download/button-download.component.scss +++ b/src/app/data-entries/button/button-download/button-download.component.scss @@ -1,5 +1,3 @@ -@use '../_bootstrap-button-theme'; - .button-sample { display: flex; padding: 2.5rem; diff --git a/src/app/data-entries/button/button-fab/button-fab.component.scss b/src/app/data-entries/button/button-fab/button-fab.component.scss index 8bb51245de..d41b93c4b1 100644 --- a/src/app/data-entries/button/button-fab/button-fab.component.scss +++ b/src/app/data-entries/button/button-fab/button-fab.component.scss @@ -1,5 +1,3 @@ -@use '../_bootstrap-button-theme'; - .button-sample { display: flex; padding: 2rem; diff --git a/src/app/data-entries/button/button-flat/button-flat.component.scss b/src/app/data-entries/button/button-flat/button-flat.component.scss index 2bfc8c5087..c98e6acd18 100644 --- a/src/app/data-entries/button/button-flat/button-flat.component.scss +++ b/src/app/data-entries/button/button-flat/button-flat.component.scss @@ -1,5 +1,3 @@ -@use '../_bootstrap-button-theme'; - .button-sample { display: flex; padding: 2.5rem; diff --git a/src/app/data-entries/button/button-interaction-states/button-interaction-states.component.scss b/src/app/data-entries/button/button-interaction-states/button-interaction-states.component.scss index bb5a34685d..02a12c7905 100644 --- a/src/app/data-entries/button/button-interaction-states/button-interaction-states.component.scss +++ b/src/app/data-entries/button/button-interaction-states/button-interaction-states.component.scss @@ -1,4 +1,3 @@ -@use '../_bootstrap-button-theme'; @use "igniteui-angular/theming" as *; .button-container { diff --git a/src/app/data-entries/button/button-layout/button-layout.component.scss b/src/app/data-entries/button/button-layout/button-layout.component.scss index 770c65f296..7b8cb2563f 100644 --- a/src/app/data-entries/button/button-layout/button-layout.component.scss +++ b/src/app/data-entries/button/button-layout/button-layout.component.scss @@ -1,5 +1,3 @@ -@use '../_bootstrap-button-theme'; - .button-container { display: flex; align-items: center; diff --git a/src/app/data-entries/button/button-outlined/button-outlined.component.scss b/src/app/data-entries/button/button-outlined/button-outlined.component.scss index 2bfc8c5087..c98e6acd18 100644 --- a/src/app/data-entries/button/button-outlined/button-outlined.component.scss +++ b/src/app/data-entries/button/button-outlined/button-outlined.component.scss @@ -1,5 +1,3 @@ -@use '../_bootstrap-button-theme'; - .button-sample { display: flex; padding: 2.5rem; diff --git a/src/app/data-entries/button/button-overview/button-overview.component.scss b/src/app/data-entries/button/button-overview/button-overview.component.scss index e464378d47..6c2b3ea3ca 100644 --- a/src/app/data-entries/button/button-overview/button-overview.component.scss +++ b/src/app/data-entries/button/button-overview/button-overview.component.scss @@ -1,5 +1,3 @@ -@use '../_bootstrap-button-theme'; - .form { display: flex; justify-content: center; diff --git a/src/app/data-entries/button/button-size/button-size.component.scss b/src/app/data-entries/button/button-size/button-size.component.scss index 2b0a6afd17..58d897c929 100644 --- a/src/app/data-entries/button/button-size/button-size.component.scss +++ b/src/app/data-entries/button/button-size/button-size.component.scss @@ -1,5 +1,3 @@ -@use '../_bootstrap-button-theme'; - :host { display: flex; justify-content: center; diff --git a/src/app/data-entries/button/button-states/button-states.component.scss b/src/app/data-entries/button/button-states/button-states.component.scss index ac098876d8..3b224d1409 100644 --- a/src/app/data-entries/button/button-states/button-states.component.scss +++ b/src/app/data-entries/button/button-states/button-states.component.scss @@ -1,5 +1,3 @@ -@use '../_bootstrap-button-theme'; - .button-container { display: flex; justify-content: center; diff --git a/src/app/data-entries/buttonGroup/button-group-alignment/button-group-alignment.component.html b/src/app/data-entries/buttonGroup/button-group-alignment/button-group-alignment.component.html index 4bf378781a..e4d6a8727e 100644 --- a/src/app/data-entries/buttonGroup/button-group-alignment/button-group-alignment.component.html +++ b/src/app/data-entries/buttonGroup/button-group-alignment/button-group-alignment.component.html @@ -1,6 +1,6 @@ -
+
@for (alignment of alignments; track alignment.value) { -
+
{{ alignment.label }} @for (city of cities; track city) { @@ -9,4 +9,4 @@
} -
+
diff --git a/src/app/data-entries/buttonGroup/button-group-alignment/button-group-alignment.component.scss b/src/app/data-entries/buttonGroup/button-group-alignment/button-group-alignment.component.scss index d8f1c12333..a91d9b616d 100644 --- a/src/app/data-entries/buttonGroup/button-group-alignment/button-group-alignment.component.scss +++ b/src/app/data-entries/buttonGroup/button-group-alignment/button-group-alignment.component.scss @@ -1,35 +1,36 @@ -.button-group-alignment { - display: flex; - align-items: flex-start; - justify-content: center; - gap: 60px; - padding: 24px; +@use 'igniteui-theming' as *; + +:host { + display: grid; + place-items: center; + height: 100vh; } -.button-group-alignment-item { +.sample-layout { display: flex; - flex-direction: column; - align-items: center; - justify-content: flex-start; - gap: 16px; + gap: rem(32px); + align-items: start; + justify-content: center; + flex-wrap: wrap; } -.button-group-alignment-item igx-buttongroup { - width: 240px; +.sample-inner-layout { + display: grid; + gap: rem(8px); + align-items: start; } -.button-group-alignment-item:first-child igx-buttongroup { - width: 320px; +igx-buttongroup { + min-width: rem(280px); } -.button-group-alignment-item span { - width: 100%; - text-align: center; - color: #556c86; +span { + color: var(--ig-gray-600); font-family: "Aktiv Grotesk", sans-serif; - font-size: 13px; + font-size: rem(13px); font-weight: 400; - font-style: normal; - line-height: 20px; - letter-spacing: 0.3px; + line-height: rem(20px); + letter-spacing: rem(0.3px); + margin: rem(8px); + text-align: center; } diff --git a/src/app/data-entries/buttonGroup/button-group-custom-toggle/button-group-custom-toggle.component.html b/src/app/data-entries/buttonGroup/button-group-custom-toggle/button-group-custom-toggle.component.html index 6c27c58e2a..03fc4ff1ff 100644 --- a/src/app/data-entries/buttonGroup/button-group-custom-toggle/button-group-custom-toggle.component.html +++ b/src/app/data-entries/buttonGroup/button-group-custom-toggle/button-group-custom-toggle.component.html @@ -1,3 +1 @@ -
- -
+ diff --git a/src/app/data-entries/buttonGroup/button-group-custom-toggle/button-group-custom-toggle.component.scss b/src/app/data-entries/buttonGroup/button-group-custom-toggle/button-group-custom-toggle.component.scss index 157e28c3ca..134b02ca04 100644 --- a/src/app/data-entries/buttonGroup/button-group-custom-toggle/button-group-custom-toggle.component.scss +++ b/src/app/data-entries/buttonGroup/button-group-custom-toggle/button-group-custom-toggle.component.scss @@ -1,11 +1,11 @@ -.button-group-custom-toggle { - display: flex; - justify-content: center; - align-items: center; - min-height: 7rem; +@use 'igniteui-theming' as *; + +:host { + display: grid; + place-items: center; + height: 100vh; } igx-buttongroup { - display: inline-block; - width: 300px; + inline-size: rem(180px); } diff --git a/src/app/data-entries/buttonGroup/button-group-interaction-states/button-group-interaction-states.component.html b/src/app/data-entries/buttonGroup/button-group-interaction-states/button-group-interaction-states.component.html index 49b20d26bf..21bcea7b66 100644 --- a/src/app/data-entries/buttonGroup/button-group-interaction-states/button-group-interaction-states.component.html +++ b/src/app/data-entries/buttonGroup/button-group-interaction-states/button-group-interaction-states.component.html @@ -1,28 +1,31 @@ -
-
+
+
@for (state of states; track state) { {{ getLabel(state) }} } -
+ @for (row of rows; track row.label) { -
+
{{ row.label }} @for (state of states; track state) { - - - +
+ {{ getLabel(state) }} + + + +
} -
+ }
diff --git a/src/app/data-entries/buttonGroup/button-group-interaction-states/button-group-interaction-states.component.scss b/src/app/data-entries/buttonGroup/button-group-interaction-states/button-group-interaction-states.component.scss index c78233443a..3619484b4a 100644 --- a/src/app/data-entries/buttonGroup/button-group-interaction-states/button-group-interaction-states.component.scss +++ b/src/app/data-entries/buttonGroup/button-group-interaction-states/button-group-interaction-states.component.scss @@ -1,73 +1,119 @@ -.button-group-interaction-states { - display: flex; - align-items: center; - justify-content: center; - flex-direction: column; - gap: 20px; - padding: 20px; +@use "igniteui-theming/sass/typography" as *; + +:host { + container-type: inline-size; + display: grid; + grid-template-columns: minmax(0, 1fr); + align-content: center; + height: 100vh; +} + +.states-matrix { + display: grid; + grid-template-columns: auto repeat(3, minmax(rem(124px), 1fr)); + gap: rem(16px); + inline-size: 100%; + max-inline-size: rem(680px); + margin-inline: auto; } -.button-group-interaction-states-row { +.states-row { display: grid; - grid-template-columns: 120px 164px 164px 164px; + grid-column: 1 / -1; + grid-template-columns: subgrid; align-items: center; - gap: 16px; } -.button-group-interaction-states .row-label, -.button-group-interaction-states .column-label { - color: #556c86; +.row-label, +.column-label, +.cell-label { + color: var(--ig-gray-600); font-family: "Aktiv Grotesk", sans-serif; - font-size: 13px; + font-size: rem(13px); font-weight: 400; - font-style: normal; - line-height: 20px; - letter-spacing: 0.3px; + line-height: rem(20px); + letter-spacing: rem(0.3px); } -.button-group-interaction-states .column-label { +.column-label, +.cell-label { text-align: center; } -.button-group-interaction-states igx-buttongroup { - width: 164px; +.cell-label { + display: none; +} + +.state-cell { + display: grid; + gap: rem(4px); +} + +igx-icon { + --ig-icon-size: #{rem(16px)}; } -.button-group-interaction-states button { - width: 100%; - gap: 4px; +@container (width < 34rem) { + .states-matrix { + grid-template-columns: minmax(0, 1fr); + } + + .states-row { + grid-template-columns: repeat(auto-fit, minmax(rem(150px), 1fr)); + } + + header.states-row { + display: none; + } + + .row-label { + grid-column: 1 / -1; + } + + .cell-label { + display: block; + text-align: start; + margin-block-start: rem(16px); + } + + .state-cell { + margin-inline-end: rem(8px); + } } -.button-group-interaction-states igx-icon { - --ig-icon-size: 16px; +// WARNING START: Demo overrides only. Do not copy to production. +// Forced state classes are used here solely to present all component states visually. +igx-buttongroup{ + pointer-events: none; } -.button-group-interaction-states button.state-hover:not(.state-selected) { +.igx-button-group__item.state-hover:not(.state-selected) { background: var(--item-hover-background); border-color: var(--item-hover-border-color); color: var(--item-hover-text-color); } -.button-group-interaction-states button.state-idle.state-selected { - background: var(--item-active-background); - border-color: var(--item-active-border-color); - color: var(--item-active-text-color); +.igx-button-group__item.state-idle.state-selected { + background: var(--item-selected-background); + border-color: var(--item-selected-border-color); + color: var(--item-selected-text-color); } -.button-group-interaction-states button.state-focused:not(.state-selected) { - background: var(--item-focused-hover-background); - border-color: var(--item-focused-hover-border-color); - color: var(--item-focused-hover-text-color); +.igx-button-group__item.state-focused:not(.state-selected) { + background: var(--item-focused-background); + border-color: var(--item-focused-border-color); + color: var(--item-focused-text-color); } -.button-group-interaction-states button.state-hover.state-selected { - background: var(--item-selected-active-background); - border-color: var(--item-selected-active-border-color); +.igx-button-group__item.state-hover.state-selected { + background: var(--item-selected-hover-background); + border-color: var(--item-selected-hover-border-color); color: var(--item-selected-hover-text-color); } -.button-group-interaction-states button.state-focused.state-selected { - background: var(--item-selected-active-background); - border-color: var(--item-selected-active-border-color); - color: var(--item-focused-hover-text-color); +.igx-button-group__item.state-focused.state-selected { + background: var(--item-selected-focus-background); + border-color: var(--item-selected-hover-border-color); + color: var(--item-selected-text-color); } +// WARNING END diff --git a/src/app/data-entries/buttonGroup/button-group-layout/button-group-layout.component.html b/src/app/data-entries/buttonGroup/button-group-layout/button-group-layout.component.html index f2cee52a01..bc87b51456 100644 --- a/src/app/data-entries/buttonGroup/button-group-layout/button-group-layout.component.html +++ b/src/app/data-entries/buttonGroup/button-group-layout/button-group-layout.component.html @@ -1,10 +1,9 @@ -
+
@for (layout of layouts; track layout.value) { } - @for (layout of layouts; track layout.value) { } -
+
diff --git a/src/app/data-entries/buttonGroup/button-group-layout/button-group-layout.component.scss b/src/app/data-entries/buttonGroup/button-group-layout/button-group-layout.component.scss index fc95cf4014..9b0b34eb79 100644 --- a/src/app/data-entries/buttonGroup/button-group-layout/button-group-layout.component.scss +++ b/src/app/data-entries/buttonGroup/button-group-layout/button-group-layout.component.scss @@ -1,21 +1,20 @@ -.button-group-layout { +@use 'igniteui-theming' as *; + +:host { + display: grid; + place-items: center; + height: 100vh; +} + +.sample-layout { display: flex; - flex-direction: row; align-items: center; justify-content: center; - gap: 80px; - min-height: 5.5rem; + flex-wrap: wrap; + gap: rem(60px); } igx-buttongroup { - display: inline-block; max-width: 400px; -} - -.button-group-layout button { - min-width: 100px; -} - -.button-group-layout igx-icon { - --ig-icon-size: 20px; + min-width: 280px; } diff --git a/src/app/data-entries/buttonGroup/button-group-overview/button-group-overview.component.html b/src/app/data-entries/buttonGroup/button-group-overview/button-group-overview.component.html index e6f995b8d8..ee2f12c634 100644 --- a/src/app/data-entries/buttonGroup/button-group-overview/button-group-overview.component.html +++ b/src/app/data-entries/buttonGroup/button-group-overview/button-group-overview.component.html @@ -1,4 +1,4 @@ -
+
+ diff --git a/src/app/data-entries/buttonGroup/button-group-overview/button-group-overview.component.scss b/src/app/data-entries/buttonGroup/button-group-overview/button-group-overview.component.scss index 128e5f6f92..37cdf83608 100644 --- a/src/app/data-entries/buttonGroup/button-group-overview/button-group-overview.component.scss +++ b/src/app/data-entries/buttonGroup/button-group-overview/button-group-overview.component.scss @@ -1,31 +1,32 @@ -.button-group-overview { - display: flex; - flex-direction: column; - align-items: center; +@use 'igniteui-theming' as *; + +:host { + display: grid; + place-items: center; + height: 100vh; } -igx-buttongroup { - display: block; - width: 280px; - max-width: 100%; +.sample-layout { + display: grid; + width: rem(280px); + gap: rem(8px); } -.album { - margin-top: 8px; - width: 280px; - max-width: 100%; +igx-buttongroup { + max-width: rem(280px); } .album-title { - display: inline-block; - margin-bottom: 8px; - color: #1f89d4; + @include type-style('body-2'); + + margin-block: 0 rem(8px); + color: var(--ig-primary-500); } .album-photos { display: grid; grid-template-columns: repeat(2, 1fr); - gap: 4px; + gap: rem(4px); } .album-photos img { diff --git a/src/app/data-entries/buttonGroup/button-group-selection/button-group-selection.component.html b/src/app/data-entries/buttonGroup/button-group-selection/button-group-selection.component.html index 65ff4542c1..c904dd7fc7 100644 --- a/src/app/data-entries/buttonGroup/button-group-selection/button-group-selection.component.html +++ b/src/app/data-entries/buttonGroup/button-group-selection/button-group-selection.component.html @@ -1,18 +1,16 @@
@for (mode of selectionModes; track mode.value) { -
- {{ mode.label }} - - - - - -
+ {{ mode.label }} + + + + + }
diff --git a/src/app/data-entries/buttonGroup/button-group-selection/button-group-selection.component.scss b/src/app/data-entries/buttonGroup/button-group-selection/button-group-selection.component.scss index 7e52239fa8..5bf42ecfb0 100644 --- a/src/app/data-entries/buttonGroup/button-group-selection/button-group-selection.component.scss +++ b/src/app/data-entries/buttonGroup/button-group-selection/button-group-selection.component.scss @@ -1,30 +1,48 @@ -.selection-samples { - display: flex; - justify-content: center; - flex-direction: column; - align-items: flex-start; - gap: 35px; - padding-left: 48px; +@use 'igniteui-theming' as *; + +:host { + container-type: inline-size; + display: grid; + grid-template-columns: minmax(0, 1fr); + align-content: center; + height: 100vh; } -.selection-sample { - display: flex; +.selection-samples { + display: grid; + grid-template-columns: auto minmax(rem(180px), 1fr); align-items: center; - gap: 30px; + gap: rem(24px) rem(32px); + inline-size: 100%; + max-inline-size: rem(380px); + margin-inline: auto; } -.selection-sample > span { - width: 120px; - text-align: right; - color: #556c86; +.sample-label { + color: var(--ig-gray-600); font-family: "Aktiv Grotesk", sans-serif; - font-size: 13px; + font-size: rem(13px); font-weight: 400; - font-style: normal; - line-height: 20px; - letter-spacing: 0.3px; + line-height: rem(20px); + letter-spacing: rem(0.3px); + text-align: end; } -.selection-sample igx-buttongroup { - width: 200px; +igx-buttongroup { + inline-size: 100%; +} + +@container (width < 22rem) { + .selection-samples { + grid-template-columns: minmax(0, 1fr); + gap: rem(4px); + } + + .sample-label { + text-align: start; + + &:not(:first-of-type) { + margin-block-start: rem(16px); + } + } } diff --git a/src/app/data-entries/buttonGroup/button-group-size/button-group-size.component.html b/src/app/data-entries/buttonGroup/button-group-size/button-group-size.component.html index 57418c0d59..bfc42db3f3 100644 --- a/src/app/data-entries/buttonGroup/button-group-size/button-group-size.component.html +++ b/src/app/data-entries/buttonGroup/button-group-size/button-group-size.component.html @@ -1,16 +1,10 @@
@for (size of sizes; track size) { -
- {{ getLabel(size) }} - - @for (city of cities; track city) { - - } - -
+ {{ getLabel(size) }} + + @for (city of cities; track city) { + + } + }
diff --git a/src/app/data-entries/buttonGroup/button-group-size/button-group-size.component.scss b/src/app/data-entries/buttonGroup/button-group-size/button-group-size.component.scss index 7d9127e015..d1e5c076b0 100644 --- a/src/app/data-entries/buttonGroup/button-group-size/button-group-size.component.scss +++ b/src/app/data-entries/buttonGroup/button-group-size/button-group-size.component.scss @@ -1,41 +1,70 @@ -.button-group-size { - display: flex; - flex-direction: column; - align-items: flex-start; - justify-content: center; - gap: 32px; - padding: 13px; - padding-left: 3rem; +@use 'igniteui-theming' as *; + +:host { + container-type: inline-size; + display: grid; + grid-template-columns: minmax(0, 1fr); + place-items: center; + height: 100vh; } -.button-group-size-item { - display: flex; - flex-direction: row; +.button-group-size { + display: grid; + grid-template-columns: auto minmax(rem(240px), 1fr); align-items: center; - justify-content: flex-start; - gap: 32px; + gap: rem(24px) rem(32px); + inline-size: 100%; + max-inline-size: rem(480px); + margin-inline: auto; } -.button-group-size-item span { - width: 52px; - text-align: right; - color: #556c86; +.sample-label { + color: var(--ig-gray-600); font-family: "Aktiv Grotesk", sans-serif; - font-size: 13px; + font-size: rem(13px); font-weight: 400; - font-style: normal; - line-height: 20px; - letter-spacing: 0.3px; + line-height: rem(20px); + letter-spacing: rem(0.3px); + text-align: end; } -.button-group-small button { - min-width: 90px; -} +igx-buttongroup { + &:nth-of-type(1n) { + --ig-size: var(--ig-size-small); + + ::ng-deep button.igx-button-group__item { + min-height: rem(32px); + } + } -.button-group-medium button { - min-width: 100px; + &:nth-of-type(2n) { + --ig-size: var(--ig-size-medium); + + ::ng-deep button.igx-button-group__item { + min-height: rem(40px); + } + } + + &:nth-of-type(3n) { + --ig-size: var(--ig-size-large); + + ::ng-deep button.igx-button-group__item { + min-height: rem(48px); + } + } } -.button-group-large button { - min-width: 110px; +@container (width < 22rem) { + .button-group-size { + grid-template-columns: minmax(0, 1fr); + gap: rem(4px); + } + + .sample-label { + text-align: start; + + &:not(:first-of-type) { + margin-block-start: rem(16px); + } + } } diff --git a/src/app/data-entries/buttonGroup/button-group-states/button-group-states.component.html b/src/app/data-entries/buttonGroup/button-group-states/button-group-states.component.html index 81234c33df..de47bb98db 100644 --- a/src/app/data-entries/buttonGroup/button-group-states/button-group-states.component.html +++ b/src/app/data-entries/buttonGroup/button-group-states/button-group-states.component.html @@ -1,26 +1,30 @@ -
-
+
+
Enabled Disabled -
+ @for (row of rows; track row.label) { -
+
{{ row.label }} - - - +
+ Enabled + + + +
- - - -
+
+ Disabled + + + +
+ }
diff --git a/src/app/data-entries/buttonGroup/button-group-states/button-group-states.component.scss b/src/app/data-entries/buttonGroup/button-group-states/button-group-states.component.scss index c823cd9347..813e4e4902 100644 --- a/src/app/data-entries/buttonGroup/button-group-states/button-group-states.component.scss +++ b/src/app/data-entries/buttonGroup/button-group-states/button-group-states.component.scss @@ -1,41 +1,86 @@ -.button-group-states { - display: flex; - align-items: center; - justify-content: center; - flex-direction: column; - gap: 20px; - padding: 20px; +@use 'igniteui-theming' as *; + +:host { + container-type: inline-size; + display: grid; + grid-template-columns: minmax(0, 1fr); + align-content: center; + height: 100vh; +} + +.states-matrix { + --state-columns: 2; + + display: grid; + grid-template-columns: auto repeat(var(--state-columns), minmax(rem(120px), 1fr)); + gap: rem(16px); + inline-size: 100%; + max-inline-size: rem(520px); + margin-inline: auto; } -.button-group-states-row { +.states-row { display: grid; - grid-template-columns: 120px 160px 160px; + grid-column: 1 / -1; + grid-template-columns: subgrid; align-items: center; - gap: 16px; } -.button-group-states .row-label, -.button-group-states .column-label { - color: #556c86; +.row-label, +.column-label, +.cell-label { + color: var(--ig-gray-600); font-family: "Aktiv Grotesk", sans-serif; - font-size: 13px; + font-size: rem(13px); font-weight: 400; - font-style: normal; - line-height: 20px; - letter-spacing: 0.3px; + line-height: rem(20px); + letter-spacing: rem(0.3px); +} + +.column-label, +.cell-label { text-align: center; } -.button-group-states igx-buttongroup { - width: 160px; +.cell-label { + display: none; +} + +.state-cell { + display: grid; + gap: rem(4px); } -.button-group-states button { - width: 100%; +// Too narrow for the matrix: drop the header, let the cells wrap, and move +// each column label into the cell it describes. +@container (width < 24rem) { + .states-matrix { + grid-template-columns: minmax(0, 1fr); + } + + .states-row { + grid-template-columns: repeat(auto-fit, minmax(rem(140px), 1fr)); + column-gap: rem(8px); + } + + header.states-row { + display: none; + } + + .row-label { + grid-column: 1 / -1; + } + + .cell-label { + display: block; + text-align: start; + margin-block-start: rem(16px); + } } -.button-group-states button.state-idle.state-selected { - background: var(--item-active-background); - border-color: var(--item-active-border-color); - color: var(--item-active-text-color); +// WARNING START: Demo overrides only. Do not copy to production. +// Interaction is disabled so the matrix stays a static picture of each state. +igx-buttongroup { + pointer-events: none; } +// WARNING END diff --git a/src/app/data-entries/buttonGroup/button-group-styling/button-group-styling.component.html b/src/app/data-entries/buttonGroup/button-group-styling/button-group-styling.component.html index c59162f0a1..1a47dc7e80 100644 --- a/src/app/data-entries/buttonGroup/button-group-styling/button-group-styling.component.html +++ b/src/app/data-entries/buttonGroup/button-group-styling/button-group-styling.component.html @@ -1,7 +1,5 @@ -
- - @for (layout of layouts; track layout) { - - } - -
+ + @for (layout of layouts; track layout) { + + } + diff --git a/src/app/data-entries/buttonGroup/button-group-styling/button-group-styling.component.scss b/src/app/data-entries/buttonGroup/button-group-styling/button-group-styling.component.scss index 4475acc9d9..34bed7af82 100644 --- a/src/app/data-entries/buttonGroup/button-group-styling/button-group-styling.component.scss +++ b/src/app/data-entries/buttonGroup/button-group-styling/button-group-styling.component.scss @@ -1,7 +1,19 @@ -@use "layout.scss" as *; @use "igniteui-angular/theming" as *; +:host { + display: grid; + place-items: center; + height: 100vh; +} + +igx-buttongroup { + display: inline-block; + width: 100%; + max-width: rem(400px); +} + $custom-button-group: button-group-theme( + $border-radius: 4px, $item-text-color: #4a5a66, $item-background: #cfe8fb, $item-border-color: #4da3e8, diff --git a/src/app/data-entries/buttonGroup/button-group-styling/layout.scss b/src/app/data-entries/buttonGroup/button-group-styling/layout.scss deleted file mode 100644 index 544499adef..0000000000 --- a/src/app/data-entries/buttonGroup/button-group-styling/layout.scss +++ /dev/null @@ -1,13 +0,0 @@ -.button-group-styling { - display: flex; - align-items: center; - justify-content: center; - min-height: 7rem; -} - -igx-buttongroup { - width: 420px; - border: 2px solid #4da3e8; - border-radius: 4px; - overflow: hidden; -} diff --git a/src/app/data-entries/buttonGroup/button-group-tailwind-styling/button-group-tailwind-styling.component.html b/src/app/data-entries/buttonGroup/button-group-tailwind-styling/button-group-tailwind-styling.component.html index 8a1bc14d88..4ea6203b54 100644 --- a/src/app/data-entries/buttonGroup/button-group-tailwind-styling/button-group-tailwind-styling.component.html +++ b/src/app/data-entries/buttonGroup/button-group-tailwind-styling/button-group-tailwind-styling.component.html @@ -1,7 +1,6 @@ -
- - @for (view of views; track view) { - - } - -
+ + @for (view of views; track view) { + + } + diff --git a/src/app/data-entries/buttonGroup/button-group-tailwind-styling/button-group-tailwind-styling.component.scss b/src/app/data-entries/buttonGroup/button-group-tailwind-styling/button-group-tailwind-styling.component.scss index 2c28a26070..f83f399b97 100644 --- a/src/app/data-entries/buttonGroup/button-group-tailwind-styling/button-group-tailwind-styling.component.scss +++ b/src/app/data-entries/buttonGroup/button-group-tailwind-styling/button-group-tailwind-styling.component.scss @@ -1,15 +1,13 @@ -@use "layout.scss"; +@use 'igniteui-theming' as *; -.button-group-style { - --item-text-color: #6d28d9; - --item-background: #ffffff; - --item-border-color: #c4b5fd; - --item-hover-text-color: #6d28d9; - --item-hover-background: #fae8ff; - --item-hover-border-color: #c4b5fd; - --item-selected-text-color: #ffffff; - --item-selected-background: #7c3aed; - --item-selected-border-color: #c4b5fd; - --item-selected-hover-text-color: #ffffff; - --item-selected-hover-background: #7c3aed; +:host { + display: grid; + place-items: center; + height: 100vh; +} + +igx-buttongroup { + display: inline-block; + width: 100%; + max-width: rem(400px); } diff --git a/src/app/data-entries/buttonGroup/button-group-tailwind-styling/layout.scss b/src/app/data-entries/buttonGroup/button-group-tailwind-styling/layout.scss deleted file mode 100644 index 4b18df3f16..0000000000 --- a/src/app/data-entries/buttonGroup/button-group-tailwind-styling/layout.scss +++ /dev/null @@ -1,16 +0,0 @@ -.button-group-tailwind-styling { - display: flex; - align-items: center; - justify-content: center; - min-height: 7rem; - width: 100%; - padding: 1.5rem; - box-sizing: border-box; - background: #f5f3ff; -} - -.button-group-tailwind-styling igx-buttongroup { - width: 420px; - max-width: 100%; - overflow: hidden; -} diff --git a/src/app/data-entries/switch/switch-bootstrap.scss b/src/app/data-entries/switch/switch-bootstrap.scss deleted file mode 100644 index 3212de8336..0000000000 --- a/src/app/data-entries/switch/switch-bootstrap.scss +++ /dev/null @@ -1,65 +0,0 @@ -@use "igniteui-angular/theming" as *; - -// Bootstrap switch geometry, aligned with the Bootstrap form-switch proportions. -@mixin bootstrap-switch { - :host ::ng-deep igx-switch { - --switch-width: #{rem(32px)}; - --switch-height: #{rem(16px)}; - --switch-thumb-size: #{rem(9px)}; - --switch-on-offset: #{rem(3px)}; - --switch-off-offset: #{rem(3px)}; - - ::ng-deep { - .igx-switch__composite { - box-sizing: border-box; - } - - .igx-switch__composite-thumb { - width: #{rem(9px)}; - height: #{rem(9px)}; - min-width: #{rem(9px)}; - box-shadow: none; - } - - .igx-switch__thumb { - width: #{rem(9px)}; - height: #{rem(9px)}; - min-width: #{rem(9px)}; - } - - .igx-switch__composite-thumb, - .igx-switch__thumb { - inline-size: #{rem(9px)}; - block-size: #{rem(9px)}; - min-inline-size: #{rem(9px)}; - max-inline-size: #{rem(9px)}; - min-block-size: #{rem(9px)}; - max-block-size: #{rem(9px)}; - } - } - - &.igx-switch--checked:not(.igx-switch--disabled) ::ng-deep .igx-switch__composite-thumb { - transform: translateX(#{rem(18px)}); - } - - &.igx-switch--checked:not(.igx-switch--disabled) ::ng-deep .igx-switch__composite { - background: var(--ig-primary-500); - } - - &.igx-switch--disabled ::ng-deep .igx-switch__composite-thumb { - transform: translateX(#{rem(3px)}) translateY(-1px); - } - - &.igx-switch--disabled.igx-switch--checked ::ng-deep .igx-switch__composite-thumb { - transform: translateX(#{rem(18px)}) translateY(0); - } - } - - :host ::ng-deep igx-switch.igx-switch--disabled.igx-switch--checked .igx-switch__composite-thumb { - transform: translateX(#{rem(18px)}) translateY(0); - } - - :host ::ng-deep igx-switch:not(.igx-switch--disabled) { - --track-on-color: var(--ig-primary-500); - } -} diff --git a/src/app/data-entries/switch/switch-disabled/switch-disabled.component.scss b/src/app/data-entries/switch/switch-disabled/switch-disabled.component.scss index 7adeb2efb1..28c0265f91 100644 --- a/src/app/data-entries/switch/switch-disabled/switch-disabled.component.scss +++ b/src/app/data-entries/switch/switch-disabled/switch-disabled.component.scss @@ -1,9 +1,3 @@ -@use "igniteui-angular/theming" as *; -@use "sass:map"; -@use "../switch-bootstrap" as switch-bootstrap; - -@include switch-bootstrap.bootstrap-switch; - :host { display: flex; min-block-size: 100%; @@ -11,8 +5,6 @@ place-content: center; place-items: center; padding: 16px; - - @include tokens(switch-theme($schema: map.get($light-bootstrap-schema, switch))); } .states { diff --git a/src/app/data-entries/switch/switch-enabled/switch-enabled.component.scss b/src/app/data-entries/switch/switch-enabled/switch-enabled.component.scss index 331ca49c32..d36f357ba4 100644 --- a/src/app/data-entries/switch/switch-enabled/switch-enabled.component.scss +++ b/src/app/data-entries/switch/switch-enabled/switch-enabled.component.scss @@ -1,16 +1,8 @@ -@use "igniteui-angular/theming" as *; -@use "sass:map"; -@use "../switch-bootstrap" as switch-bootstrap; - -@include switch-bootstrap.bootstrap-switch; - :host { display: flex; place-content: center; place-items: center; padding: 16px; - - @include tokens(switch-theme($schema: map.get($light-bootstrap-schema, switch))); } .states { diff --git a/src/app/data-entries/switch/switch-layout/switch-layout.component.scss b/src/app/data-entries/switch/switch-layout/switch-layout.component.scss index c281c73024..9cb1380aaa 100644 --- a/src/app/data-entries/switch/switch-layout/switch-layout.component.scss +++ b/src/app/data-entries/switch/switch-layout/switch-layout.component.scss @@ -1,9 +1,3 @@ -@use "igniteui-angular/theming" as *; -@use "sass:map"; -@use "../switch-bootstrap" as switch-bootstrap; - -@include switch-bootstrap.bootstrap-switch; - :host { display: flex; min-block-size: 100%; @@ -11,8 +5,6 @@ place-content: center; place-items: center; padding: 16px; - - @include tokens(switch-theme($schema: map.get($light-bootstrap-schema, switch))); } .variants { diff --git a/src/app/data-entries/switch/switch-overview/switch-overview.component.scss b/src/app/data-entries/switch/switch-overview/switch-overview.component.scss index 289bdc2420..4eb2dd76b2 100644 --- a/src/app/data-entries/switch/switch-overview/switch-overview.component.scss +++ b/src/app/data-entries/switch/switch-overview/switch-overview.component.scss @@ -1,16 +1,8 @@ -@use "igniteui-angular/theming" as *; -@use "sass:map"; -@use "../switch-bootstrap" as switch-bootstrap; - -@include switch-bootstrap.bootstrap-switch; - :host { display: flex; place-content: center; place-items: center; padding: 16px; - - @include tokens(switch-theme($schema: map.get($light-bootstrap-schema, switch))); } .notifications { @@ -26,7 +18,7 @@ font: 400 10px / 16px "Titillium Web", sans-serif; letter-spacing: 1.5px; text-transform: uppercase; - color: var(--ig-primary-500); + color: var(--ig-secondary-500); } .notifications__row { diff --git a/src/app/data-entries/switch/switch-selected/switch-selected.component.scss b/src/app/data-entries/switch/switch-selected/switch-selected.component.scss index 58683f9b6e..3b46e34548 100644 --- a/src/app/data-entries/switch/switch-selected/switch-selected.component.scss +++ b/src/app/data-entries/switch/switch-selected/switch-selected.component.scss @@ -1,16 +1,8 @@ -@use "igniteui-angular/theming" as *; -@use "sass:map"; -@use "../switch-bootstrap" as switch-bootstrap; - -@include switch-bootstrap.bootstrap-switch; - :host { display: flex; place-content: center; place-items: center; padding: 16px; - - @include tokens(switch-theme($schema: map.get($light-bootstrap-schema, switch))); } .states { diff --git a/src/app/data-entries/switch/switch-styling/switch-styling.component.scss b/src/app/data-entries/switch/switch-styling/switch-styling.component.scss index 49bbd9abd2..1bcc8dcda4 100644 --- a/src/app/data-entries/switch/switch-styling/switch-styling.component.scss +++ b/src/app/data-entries/switch/switch-styling/switch-styling.component.scss @@ -1,8 +1,4 @@ @use "igniteui-angular/theming" as *; -@use "sass:map"; -@use "../switch-bootstrap" as switch-bootstrap; - -@include switch-bootstrap.bootstrap-switch; :host ::ng-deep igx-switch .igx-switch__thumb { min-width: 10px; @@ -19,9 +15,6 @@ place-items: center; min-block-size: 100%; padding: 1rem; - - @include tokens(switch-theme($schema: map.get($light-bootstrap-schema, switch))); - @include tokens(radio-theme($schema: map.get($light-bootstrap-schema, radio))); } .security { diff --git a/src/app/data-entries/switch/switch-tailwind-styling/switch-tailwind-styling.component.scss b/src/app/data-entries/switch/switch-tailwind-styling/switch-tailwind-styling.component.scss index e5b4f5cd37..20b66dbc13 100644 --- a/src/app/data-entries/switch/switch-tailwind-styling/switch-tailwind-styling.component.scss +++ b/src/app/data-entries/switch/switch-tailwind-styling/switch-tailwind-styling.component.scss @@ -1,7 +1,3 @@ -@use "../switch-bootstrap" as switch-bootstrap; - -@include switch-bootstrap.bootstrap-switch; - :host ::ng-deep igx-switch .igx-switch__thumb { min-width: 10px; } diff --git a/src/app/layouts/avatar/avatar-shape/avatar-shape.component.scss b/src/app/layouts/avatar/avatar-shape/avatar-shape.component.scss index a6a47666fd..cbaac2cdce 100644 --- a/src/app/layouts/avatar/avatar-shape/avatar-shape.component.scss +++ b/src/app/layouts/avatar/avatar-shape/avatar-shape.component.scss @@ -23,6 +23,11 @@ span { grid-row: 2; text-align: center; color: var(--ig-gray-600); + font-family: "Aktiv Grotesk", sans-serif; + font-size: rem(13px); + font-weight: 400; + line-height: rem(20px); + letter-spacing: rem(0.3px); @include type-style("body-1") { margin: 0; diff --git a/src/app/layouts/avatar/avatar-size/avatar-size.component.scss b/src/app/layouts/avatar/avatar-size/avatar-size.component.scss index 79f4204bbe..119e5278c7 100644 --- a/src/app/layouts/avatar/avatar-size/avatar-size.component.scss +++ b/src/app/layouts/avatar/avatar-size/avatar-size.component.scss @@ -21,6 +21,11 @@ span { grid-row: 2; text-align: center; color: var(--ig-gray-600); + font-family: "Aktiv Grotesk", sans-serif; + font-size: rem(13px); + font-weight: 400; + line-height: rem(20px); + letter-spacing: rem(0.3px); @include type-style("body-1") { margin: 0; diff --git a/src/app/layouts/avatar/avatar-variants/avatar-variants.component.scss b/src/app/layouts/avatar/avatar-variants/avatar-variants.component.scss index a4c56b17fc..25fc17d779 100644 --- a/src/app/layouts/avatar/avatar-variants/avatar-variants.component.scss +++ b/src/app/layouts/avatar/avatar-variants/avatar-variants.component.scss @@ -24,6 +24,11 @@ $avatars: circle, square, rounded; grid-row: 2; text-align: center; color: var(--ig-gray-600); + font-family: "Aktiv Grotesk", sans-serif; + font-size: rem(13px); + font-weight: 400; + line-height: rem(20px); + letter-spacing: rem(0.3px); @include type-style("body-1") { margin: 0; diff --git a/src/index.html b/src/index.html index 65e26031de..84b261710f 100644 --- a/src/index.html +++ b/src/index.html @@ -3,6 +3,10 @@ + + Angular Demos From da6c1e4a90c634a2509bc26ad79449b9ae9e444b Mon Sep 17 00:00:00 2001 From: Viktor Kombov <75325639+viktorkombov@users.noreply.github.com> Date: Wed, 23 Sep 2026 18:28:06 +0300 Subject: [PATCH 17/22] fix(theming): declare Tailwind layers before the theme link (#4033) Co-authored-by: Stamen Stoychev --- src/index.html | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/index.html b/src/index.html index 84b261710f..edf598d753 100644 --- a/src/index.html +++ b/src/index.html @@ -21,6 +21,8 @@ documentation site's theming widget posts a new selection into the sample; it stays ahead of the application's own stylesheet so that styles.scss keeps overriding the theme. --> + + From 387837d8f694c5474502f5f93c77d27b67f7fc93 Mon Sep 17 00:00:00 2001 From: Adrian Petrov Date: Thu, 24 Sep 2026 10:27:10 +0300 Subject: [PATCH 18/22] fix(): add logo-margin --- .../qr-code/qr-code-logo/qr-code-logo.component.html | 3 ++- .../qr-code/qr-code-overview/qr-code-overview.component.html | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/app/data-display/qr-code/qr-code-logo/qr-code-logo.component.html b/src/app/data-display/qr-code/qr-code-logo/qr-code-logo.component.html index 6cbe319214..69175e4213 100644 --- a/src/app/data-display/qr-code/qr-code-logo/qr-code-logo.component.html +++ b/src/app/data-display/qr-code/qr-code-logo/qr-code-logo.component.html @@ -1 +1,2 @@ - + \ No newline at end of file diff --git a/src/app/data-display/qr-code/qr-code-overview/qr-code-overview.component.html b/src/app/data-display/qr-code/qr-code-overview/qr-code-overview.component.html index dafeba766d..cb914d8622 100644 --- a/src/app/data-display/qr-code/qr-code-overview/qr-code-overview.component.html +++ b/src/app/data-display/qr-code/qr-code-overview/qr-code-overview.component.html @@ -23,4 +23,5 @@ error-level="H" [attr.logo-src]="showLogo ? logoSrc : null" logo-size="1" + logo-margin="3" > From cb1df9b4b8cd3c9aff83062d28bf43bc9a92c402 Mon Sep 17 00:00:00 2001 From: Ivan Minchev <61944284+IMinchev64@users.noreply.github.com> Date: Thu, 24 Sep 2026 17:12:31 +0300 Subject: [PATCH 19/22] fix(theming): match root color-scheme to the selected theme mode (#4034) --- src/app/services/theme.service.spec.ts | 11 +++++++++++ src/app/services/theme.service.ts | 4 ++++ 2 files changed, 15 insertions(+) diff --git a/src/app/services/theme.service.spec.ts b/src/app/services/theme.service.spec.ts index aa97a511dd..b38886632a 100644 --- a/src/app/services/theme.service.spec.ts +++ b/src/app/services/theme.service.spec.ts @@ -53,4 +53,15 @@ describe('ThemeService theme validation', () => { .toBe(`assets/themes/${stylesheet}`); }); } + + it('reflects the color mode as the root color-scheme', () => { + const root = document.documentElement; + expect(root.style.colorScheme).toBe('light'); + + expect(service.set('bootstrap', 'dark')).toBeTrue(); + expect(root.style.colorScheme).toBe('dark'); + + expect(service.set('bootstrap', 'light')).toBeTrue(); + expect(root.style.colorScheme).toBe('light'); + }); }); diff --git a/src/app/services/theme.service.ts b/src/app/services/theme.service.ts index bc24357df4..03f2ef9c81 100644 --- a/src/app/services/theme.service.ts +++ b/src/app/services/theme.service.ts @@ -154,6 +154,10 @@ export class ThemeService { const root = this.document.documentElement; root.dataset.igTheme = theme; root.dataset.igMode = scheme; + // The Sample component gives its iframe the same color-scheme. When the + // two differ, the browser paints an opaque default canvas behind the + // page instead of leaving it transparent for that surface to show through. + root.style.colorScheme = scheme; const href = THEMES_PATH + THEME_STYLESHEETS[theme][scheme]; const link = this.themeLink(); From b0aea06652ad1bd626dea4140bc75754f162caa2 Mon Sep 17 00:00:00 2001 From: Ivan Minchev Date: Fri, 25 Sep 2026 12:27:30 +0300 Subject: [PATCH 20/22] fix(avatar): fix overview sample styling to work with Indigo theme --- .../avatar/avatar-overview/avatar-overview.component.scss | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/app/layouts/avatar/avatar-overview/avatar-overview.component.scss b/src/app/layouts/avatar/avatar-overview/avatar-overview.component.scss index 6ee88140a1..66ce9fc688 100644 --- a/src/app/layouts/avatar/avatar-overview/avatar-overview.component.scss +++ b/src/app/layouts/avatar/avatar-overview/avatar-overview.component.scss @@ -26,10 +26,13 @@ display: flex; igx-avatar { - box-shadow: 0 0 0 rem(6px) var(--ig-surface-500); + box-shadow: 0 0 0 calc(var(--size) * 0.07) var(--ig-surface-500); + igx-avatar { - margin-inline-start: rem(-24px); + // Proportional to the avatar's own rendered size (--size, set by + // the theme) rather than a fixed length, since themes disagree + // widely on how big a "large" avatar actually is. + margin-inline-start: calc(var(--size) * -0.27); } &:last-child { From 402b63bb5d1b6d2a5111ad85f9e0478780a5e302 Mon Sep 17 00:00:00 2001 From: Adrian Petrov Date: Fri, 25 Sep 2026 12:56:21 +0300 Subject: [PATCH 21/22] feat(color-picker): add samples --- .../alpha/color-picker-alpha.component.html | 3 + .../alpha/color-picker-alpha.component.scss | 13 ++ .../alpha/color-picker-alpha.component.ts | 21 +++ .../format/color-picker-format.component.html | 3 + .../format/color-picker-format.component.scss | 13 ++ .../format/color-picker-format.component.ts | 21 +++ .../color-picker-input-sizes.component.html | 14 ++ .../color-picker-input-sizes.component.scss | 40 ++++ .../color-picker-input-sizes.component.ts | 21 +++ .../input/color-picker-input.component.html | 3 + .../input/color-picker-input.component.scss | 13 ++ .../input/color-picker-input.component.ts | 21 +++ .../color-picker-overview.component.html | 34 ++++ .../color-picker-overview.component.scss | 80 ++++++++ .../color-picker-overview.component.ts | 41 ++++ .../color-picker-reactive-form.component.html | 45 +++++ .../color-picker-reactive-form.component.scss | 62 ++++++ .../color-picker-reactive-form.component.ts | 57 ++++++ .../sizes/color-picker-sizes.component.html | 14 ++ .../sizes/color-picker-sizes.component.scss | 40 ++++ .../sizes/color-picker-sizes.component.ts | 21 +++ .../states/color-picker-states.component.html | 14 ++ .../states/color-picker-states.component.scss | 30 +++ .../states/color-picker-states.component.ts | 27 +++ .../color-picker-styling.component.html | 57 ++++++ .../color-picker-styling.component.scss | 16 ++ .../styling/color-picker-styling.component.ts | 16 ++ .../color-picker/styling/layout.scss | 99 ++++++++++ .../color-picker-swatches.component.html | 4 + .../color-picker-swatches.component.scss | 14 ++ .../color-picker-swatches.component.ts | 31 +++ ...lor-picker-tailwind-styling.component.html | 62 ++++++ ...lor-picker-tailwind-styling.component.scss | 176 ++++++++++++++++++ ...color-picker-tailwind-styling.component.ts | 60 ++++++ .../value/color-picker-value.component.html | 3 + .../value/color-picker-value.component.scss | 17 ++ .../value/color-picker-value.component.ts | 21 +++ .../data-entries/data-entries-routes-data.ts | 12 ++ src/app/data-entries/data-entries.routes.ts | 72 +++++++ 39 files changed, 1311 insertions(+) create mode 100644 src/app/data-entries/color-picker/alpha/color-picker-alpha.component.html create mode 100644 src/app/data-entries/color-picker/alpha/color-picker-alpha.component.scss create mode 100644 src/app/data-entries/color-picker/alpha/color-picker-alpha.component.ts create mode 100644 src/app/data-entries/color-picker/format/color-picker-format.component.html create mode 100644 src/app/data-entries/color-picker/format/color-picker-format.component.scss create mode 100644 src/app/data-entries/color-picker/format/color-picker-format.component.ts create mode 100644 src/app/data-entries/color-picker/input-sizes/color-picker-input-sizes.component.html create mode 100644 src/app/data-entries/color-picker/input-sizes/color-picker-input-sizes.component.scss create mode 100644 src/app/data-entries/color-picker/input-sizes/color-picker-input-sizes.component.ts create mode 100644 src/app/data-entries/color-picker/input/color-picker-input.component.html create mode 100644 src/app/data-entries/color-picker/input/color-picker-input.component.scss create mode 100644 src/app/data-entries/color-picker/input/color-picker-input.component.ts create mode 100644 src/app/data-entries/color-picker/overview/color-picker-overview.component.html create mode 100644 src/app/data-entries/color-picker/overview/color-picker-overview.component.scss create mode 100644 src/app/data-entries/color-picker/overview/color-picker-overview.component.ts create mode 100644 src/app/data-entries/color-picker/reactive-form/color-picker-reactive-form.component.html create mode 100644 src/app/data-entries/color-picker/reactive-form/color-picker-reactive-form.component.scss create mode 100644 src/app/data-entries/color-picker/reactive-form/color-picker-reactive-form.component.ts create mode 100644 src/app/data-entries/color-picker/sizes/color-picker-sizes.component.html create mode 100644 src/app/data-entries/color-picker/sizes/color-picker-sizes.component.scss create mode 100644 src/app/data-entries/color-picker/sizes/color-picker-sizes.component.ts create mode 100644 src/app/data-entries/color-picker/states/color-picker-states.component.html create mode 100644 src/app/data-entries/color-picker/states/color-picker-states.component.scss create mode 100644 src/app/data-entries/color-picker/states/color-picker-states.component.ts create mode 100644 src/app/data-entries/color-picker/styling/color-picker-styling.component.html create mode 100644 src/app/data-entries/color-picker/styling/color-picker-styling.component.scss create mode 100644 src/app/data-entries/color-picker/styling/color-picker-styling.component.ts create mode 100644 src/app/data-entries/color-picker/styling/layout.scss create mode 100644 src/app/data-entries/color-picker/swatches/color-picker-swatches.component.html create mode 100644 src/app/data-entries/color-picker/swatches/color-picker-swatches.component.scss create mode 100644 src/app/data-entries/color-picker/swatches/color-picker-swatches.component.ts create mode 100644 src/app/data-entries/color-picker/tailwind-styling/color-picker-tailwind-styling.component.html create mode 100644 src/app/data-entries/color-picker/tailwind-styling/color-picker-tailwind-styling.component.scss create mode 100644 src/app/data-entries/color-picker/tailwind-styling/color-picker-tailwind-styling.component.ts create mode 100644 src/app/data-entries/color-picker/value/color-picker-value.component.html create mode 100644 src/app/data-entries/color-picker/value/color-picker-value.component.scss create mode 100644 src/app/data-entries/color-picker/value/color-picker-value.component.ts diff --git a/src/app/data-entries/color-picker/alpha/color-picker-alpha.component.html b/src/app/data-entries/color-picker/alpha/color-picker-alpha.component.html new file mode 100644 index 0000000000..ebd41ed541 --- /dev/null +++ b/src/app/data-entries/color-picker/alpha/color-picker-alpha.component.html @@ -0,0 +1,3 @@ +
+ +
diff --git a/src/app/data-entries/color-picker/alpha/color-picker-alpha.component.scss b/src/app/data-entries/color-picker/alpha/color-picker-alpha.component.scss new file mode 100644 index 0000000000..f4cefbb18b --- /dev/null +++ b/src/app/data-entries/color-picker/alpha/color-picker-alpha.component.scss @@ -0,0 +1,13 @@ +.sample-container { + --ig-size: 2; + + display: flex; + justify-content: center; + padding-block-start: 0.5rem; +} + +igc-color-picker::part(picker) { + --picker-elevation: var(--ig-elevation-4); + + margin-top: 0.5rem; +} diff --git a/src/app/data-entries/color-picker/alpha/color-picker-alpha.component.ts b/src/app/data-entries/color-picker/alpha/color-picker-alpha.component.ts new file mode 100644 index 0000000000..b9c1958d69 --- /dev/null +++ b/src/app/data-entries/color-picker/alpha/color-picker-alpha.component.ts @@ -0,0 +1,21 @@ +import { Component, CUSTOM_ELEMENTS_SCHEMA, ViewChild, ElementRef, AfterViewInit } from '@angular/core'; +import { defineComponents, IgcColorPickerComponent } from 'igniteui-webcomponents'; + +defineComponents(IgcColorPickerComponent); + +@Component({ + selector: 'app-color-picker-alpha', + styleUrls: ['./color-picker-alpha.component.scss'], + templateUrl: './color-picker-alpha.component.html', + imports: [], + schemas: [CUSTOM_ELEMENTS_SCHEMA] +}) + +export class ColorPickerAlphaComponent implements AfterViewInit { + @ViewChild('colorPicker', { static: true }) + colorPicker!: ElementRef; + + ngAfterViewInit() { + this.colorPicker.nativeElement.toggle(); + } +} diff --git a/src/app/data-entries/color-picker/format/color-picker-format.component.html b/src/app/data-entries/color-picker/format/color-picker-format.component.html new file mode 100644 index 0000000000..e0e0fbdc83 --- /dev/null +++ b/src/app/data-entries/color-picker/format/color-picker-format.component.html @@ -0,0 +1,3 @@ +
+ +
diff --git a/src/app/data-entries/color-picker/format/color-picker-format.component.scss b/src/app/data-entries/color-picker/format/color-picker-format.component.scss new file mode 100644 index 0000000000..f4cefbb18b --- /dev/null +++ b/src/app/data-entries/color-picker/format/color-picker-format.component.scss @@ -0,0 +1,13 @@ +.sample-container { + --ig-size: 2; + + display: flex; + justify-content: center; + padding-block-start: 0.5rem; +} + +igc-color-picker::part(picker) { + --picker-elevation: var(--ig-elevation-4); + + margin-top: 0.5rem; +} diff --git a/src/app/data-entries/color-picker/format/color-picker-format.component.ts b/src/app/data-entries/color-picker/format/color-picker-format.component.ts new file mode 100644 index 0000000000..a867942a14 --- /dev/null +++ b/src/app/data-entries/color-picker/format/color-picker-format.component.ts @@ -0,0 +1,21 @@ +import { Component, CUSTOM_ELEMENTS_SCHEMA, ViewChild, ElementRef, AfterViewInit } from '@angular/core'; +import { defineComponents, IgcColorPickerComponent } from 'igniteui-webcomponents'; + +defineComponents(IgcColorPickerComponent); + +@Component({ + selector: 'app-color-picker-format', + styleUrls: ['./color-picker-format.component.scss'], + templateUrl: './color-picker-format.component.html', + imports: [], + schemas: [CUSTOM_ELEMENTS_SCHEMA] +}) + +export class ColorPickerFormatComponent implements AfterViewInit { + @ViewChild('colorPicker', { static: true }) + colorPicker!: ElementRef; + + ngAfterViewInit() { + this.colorPicker.nativeElement.toggle(); + } +} diff --git a/src/app/data-entries/color-picker/input-sizes/color-picker-input-sizes.component.html b/src/app/data-entries/color-picker/input-sizes/color-picker-input-sizes.component.html new file mode 100644 index 0000000000..cc4d57f304 --- /dev/null +++ b/src/app/data-entries/color-picker/input-sizes/color-picker-input-sizes.component.html @@ -0,0 +1,14 @@ +
+
+ Small + +
+
+ Medium + +
+
+ Large + +
+
diff --git a/src/app/data-entries/color-picker/input-sizes/color-picker-input-sizes.component.scss b/src/app/data-entries/color-picker/input-sizes/color-picker-input-sizes.component.scss new file mode 100644 index 0000000000..708377b7c8 --- /dev/null +++ b/src/app/data-entries/color-picker/input-sizes/color-picker-input-sizes.component.scss @@ -0,0 +1,40 @@ +.small-picker { + --ig-size: var(--ig-size-small); +} + +.medium-picker { + --ig-size: var(--ig-size-medium); +} + +.large-picker { + --ig-size: var(--ig-size-large); +} + +.sample-container { + display: flex; + flex-direction: row; + justify-content: center; + gap: 2rem; + padding-block-start: 0.5rem; + font-family: "Aktiv Grotesk", sans-serif; +} + +span { + display: block; + text-align: center; + margin-block-end: 1rem; + color: var(--ig-gray-600); +} + +igc-color-picker::part(picker) { + --picker-elevation: var(--ig-elevation-4); + + margin-top: 0.5rem; +} + +@media (width < 450px) { + .sample-container { + flex-direction: column; + align-items: center; + } +} diff --git a/src/app/data-entries/color-picker/input-sizes/color-picker-input-sizes.component.ts b/src/app/data-entries/color-picker/input-sizes/color-picker-input-sizes.component.ts new file mode 100644 index 0000000000..04443afb1a --- /dev/null +++ b/src/app/data-entries/color-picker/input-sizes/color-picker-input-sizes.component.ts @@ -0,0 +1,21 @@ +import { Component, CUSTOM_ELEMENTS_SCHEMA, ViewChild, ElementRef, AfterViewInit } from '@angular/core'; +import { defineComponents, IgcColorPickerComponent } from 'igniteui-webcomponents'; + +defineComponents(IgcColorPickerComponent); + +@Component({ + selector: 'app-color-picker-input-sizes', + styleUrls: ['./color-picker-input-sizes.component.scss'], + templateUrl: './color-picker-input-sizes.component.html', + imports: [], + schemas: [CUSTOM_ELEMENTS_SCHEMA] +}) + +export class ColorPickerInputSizesComponent implements AfterViewInit { + @ViewChild('colorPicker', { static: true }) + colorPicker!: ElementRef; + + ngAfterViewInit() { + this.colorPicker.nativeElement.toggle(); + } +} diff --git a/src/app/data-entries/color-picker/input/color-picker-input.component.html b/src/app/data-entries/color-picker/input/color-picker-input.component.html new file mode 100644 index 0000000000..67554f034e --- /dev/null +++ b/src/app/data-entries/color-picker/input/color-picker-input.component.html @@ -0,0 +1,3 @@ +
+ +
diff --git a/src/app/data-entries/color-picker/input/color-picker-input.component.scss b/src/app/data-entries/color-picker/input/color-picker-input.component.scss new file mode 100644 index 0000000000..f4cefbb18b --- /dev/null +++ b/src/app/data-entries/color-picker/input/color-picker-input.component.scss @@ -0,0 +1,13 @@ +.sample-container { + --ig-size: 2; + + display: flex; + justify-content: center; + padding-block-start: 0.5rem; +} + +igc-color-picker::part(picker) { + --picker-elevation: var(--ig-elevation-4); + + margin-top: 0.5rem; +} diff --git a/src/app/data-entries/color-picker/input/color-picker-input.component.ts b/src/app/data-entries/color-picker/input/color-picker-input.component.ts new file mode 100644 index 0000000000..161e442ffe --- /dev/null +++ b/src/app/data-entries/color-picker/input/color-picker-input.component.ts @@ -0,0 +1,21 @@ +import { Component, CUSTOM_ELEMENTS_SCHEMA, ViewChild, ElementRef, AfterViewInit } from '@angular/core'; +import { defineComponents, IgcColorPickerComponent } from 'igniteui-webcomponents'; + +defineComponents(IgcColorPickerComponent); + +@Component({ + selector: 'app-color-picker-input', + styleUrls: ['./color-picker-input.component.scss'], + templateUrl: './color-picker-input.component.html', + imports: [], + schemas: [CUSTOM_ELEMENTS_SCHEMA] +}) + +export class ColorPickerInputComponent implements AfterViewInit { + @ViewChild('colorPicker', { static: true }) + colorPicker!: ElementRef; + + ngAfterViewInit() { + this.colorPicker.nativeElement.toggle(); + } +} diff --git a/src/app/data-entries/color-picker/overview/color-picker-overview.component.html b/src/app/data-entries/color-picker/overview/color-picker-overview.component.html new file mode 100644 index 0000000000..befe6c3b9d --- /dev/null +++ b/src/app/data-entries/color-picker/overview/color-picker-overview.component.html @@ -0,0 +1,34 @@ +
+ + +

Choose your interior color

+ + + @for (item of paintTypes; track item) { + {{ item }} + } + + + + @for (item of paintQuantities; track item) { + {{ item }} + } + +
+ + +
+
+ + +
+ + + +
+ +
+
+
diff --git a/src/app/data-entries/color-picker/overview/color-picker-overview.component.scss b/src/app/data-entries/color-picker/overview/color-picker-overview.component.scss new file mode 100644 index 0000000000..df7e8a0f54 --- /dev/null +++ b/src/app/data-entries/color-picker/overview/color-picker-overview.component.scss @@ -0,0 +1,80 @@ +.sample-container { + display: flex; + justify-content: center; + align-items: center; + padding-block-start: 0.5rem; +} + +igx-card { + --ig-size: 2; + + width: 22rem; +} + +h2 { + margin: 0 0 1rem; + font-size: 1.25rem; + color: var(--ig-gray-900); +} + +igx-card-content { + display: flex; + flex-direction: column; + gap: 1.25rem; +} + +igx-select { + width: 100%; +} + +.color-row { + position: relative; +} + +igc-color-picker { + width: 100%; +} + +igc-color-picker::part(color-picker) { + width: 100%; + grid-template-columns: auto; +} + +igc-color-picker::part(picker) { + --picker-elevation: var(--ig-elevation-12); +} + +.igx-icon-button { + position: absolute; + right: 0.5rem; + top: 0.5rem; + z-index: 1; +} + +igx-card-actions { + display: flex; + align-items: center; + justify-content: space-between; +} + +.stepper { + display: flex; + gap: 0.375rem; +} + +.stepper .dot { + width: 0.375rem; + height: 0.375rem; + border-radius: 50%; + background: var(--ig-gray-300); +} + +.stepper .dot.active { + background: var(--ig-secondary-500); +} + +::ng-deep { + .igx-card-actions__end { + margin-inline-start: unset; + } +} diff --git a/src/app/data-entries/color-picker/overview/color-picker-overview.component.ts b/src/app/data-entries/color-picker/overview/color-picker-overview.component.ts new file mode 100644 index 0000000000..10d22cf962 --- /dev/null +++ b/src/app/data-entries/color-picker/overview/color-picker-overview.component.ts @@ -0,0 +1,41 @@ +import { Component, ElementRef, ViewChild, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { defineComponents, IgcColorPickerComponent } from 'igniteui-webcomponents'; +import { IgxCardComponent, IgxCardContentDirective, IgxCardActionsComponent } from 'igniteui-angular/card'; +import { IgxButtonDirective, IgxIconButtonDirective } from 'igniteui-angular/directives'; +import { IgxIconComponent } from 'igniteui-angular/icon'; +import { IgxSelectComponent, IgxSelectItemComponent } from 'igniteui-angular/select'; +import { IgxLabelDirective } from 'igniteui-angular/input-group'; + +defineComponents(IgcColorPickerComponent); + +@Component({ + selector: 'app-color-picker-overview', + styleUrls: ['./color-picker-overview.component.scss'], + templateUrl: './color-picker-overview.component.html', + imports: [ + FormsModule, + IgxCardComponent, + IgxCardContentDirective, + IgxCardActionsComponent, + IgxButtonDirective, + IgxIconButtonDirective, + IgxIconComponent, + IgxSelectComponent, + IgxSelectItemComponent, + IgxLabelDirective + ], + schemas: [CUSTOM_ELEMENTS_SCHEMA] +}) + +export class ColorPickerOverviewComponent { + @ViewChild('picker', { static: true }) + public picker!: ElementRef; + + public paintTypes = ['Matte', 'Satin', 'Eggshell', 'Gloss']; + public paintQuantities = ['1 litre', '3 litres', '5 litres', '10 litres']; + + public resetColor(): void { + this.picker.nativeElement.value = ''; + } +} diff --git a/src/app/data-entries/color-picker/reactive-form/color-picker-reactive-form.component.html b/src/app/data-entries/color-picker/reactive-form/color-picker-reactive-form.component.html new file mode 100644 index 0000000000..97f917eef7 --- /dev/null +++ b/src/app/data-entries/color-picker/reactive-form/color-picker-reactive-form.component.html @@ -0,0 +1,45 @@ +
+ + +
+

Create a label

+ + + + @if (name.touched && name.invalid) { + A label name is required. + } + + + Pick a swatch or select any color value. + A label color is required. + + + +
+ Preview + + {{ labelForm.value.name || 'Label' }} + +
+
+ + +
+
+
+
+
diff --git a/src/app/data-entries/color-picker/reactive-form/color-picker-reactive-form.component.scss b/src/app/data-entries/color-picker/reactive-form/color-picker-reactive-form.component.scss new file mode 100644 index 0000000000..c5b1f896f1 --- /dev/null +++ b/src/app/data-entries/color-picker/reactive-form/color-picker-reactive-form.component.scss @@ -0,0 +1,62 @@ +.sample-container { + --ig-size: 2; + + display: flex; + justify-content: center; + padding-block-start: 0.5rem; +} + +igx-card { + width: 24rem; +} + +form { + display: flex; + flex-direction: column; + gap: 1.25rem; +} + +h2 { + margin: 0; + font-size: 1.25rem; + color: var(--ig-gray-900); +} + +igc-color-picker[mode="input"] { + width: 100%; +} + +igc-color-picker[mode="input"]::part(color-picker) { + width: 100%; + grid-template-columns: auto; +} + +igc-color-picker::part(picker) { + --picker-elevation: var(--ig-elevation-4); + + margin-top: 0.5rem; +} + +.preview { + display: flex; + align-items: center; + gap: 0.75rem; +} + +.preview-caption { + font-size: 0.875rem; + color: var(--ig-gray-600); +} + +.preview-label { + padding: 0.25rem 0.75rem; + border-radius: 1rem; + font-size: 0.875rem; + font-weight: 600; +} + +.actions { + display: flex; + justify-content: flex-end; + gap: 0.5rem; +} diff --git a/src/app/data-entries/color-picker/reactive-form/color-picker-reactive-form.component.ts b/src/app/data-entries/color-picker/reactive-form/color-picker-reactive-form.component.ts new file mode 100644 index 0000000000..a0a7fea1a1 --- /dev/null +++ b/src/app/data-entries/color-picker/reactive-form/color-picker-reactive-form.component.ts @@ -0,0 +1,57 @@ +import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; +import { defineComponents, IgcColorPickerComponent } from 'igniteui-webcomponents'; +import { IgcFormControlDirective, IgxButtonDirective } from 'igniteui-angular/directives'; +import { IgxCardComponent, IgxCardContentDirective } from 'igniteui-angular/card'; +import { IgxHintDirective, IgxInputDirective, IgxInputGroupComponent, IgxLabelDirective } from 'igniteui-angular/input-group'; + +defineComponents(IgcColorPickerComponent); + +interface LabelForm { + name: FormControl; + color: FormControl; + textColor: FormControl; +} + +const initialValue = { name: '', color: '', textColor: '#000000' }; + +@Component({ + selector: 'app-color-picker-reactive-form', + styleUrls: ['./color-picker-reactive-form.component.scss'], + templateUrl: './color-picker-reactive-form.component.html', + imports: [ + ReactiveFormsModule, + IgcFormControlDirective, + IgxButtonDirective, + IgxCardComponent, + IgxCardContentDirective, + IgxInputGroupComponent, + IgxInputDirective, + IgxLabelDirective, + IgxHintDirective + ], + schemas: [CUSTOM_ELEMENTS_SCHEMA] +}) + +export class ColorPickerReactiveFormComponent { + public swatches = ['#d32f2f', '#f57c00', '#fbc02d', '#388e3c', '#1976d2', '#7b1fa2', '#455a64']; + + public labelForm = new FormGroup({ + name: new FormControl(initialValue.name, Validators.required), + color: new FormControl(initialValue.color, Validators.required), + textColor: new FormControl(initialValue.textColor) + }); + + public get name() { + return this.labelForm.controls.name; + } + + public get color() { + return this.labelForm.controls.color; + } + + public onReset(form: HTMLFormElement): void { + form.reset(); + this.labelForm.reset(initialValue); + } +} diff --git a/src/app/data-entries/color-picker/sizes/color-picker-sizes.component.html b/src/app/data-entries/color-picker/sizes/color-picker-sizes.component.html new file mode 100644 index 0000000000..11a68b6c13 --- /dev/null +++ b/src/app/data-entries/color-picker/sizes/color-picker-sizes.component.html @@ -0,0 +1,14 @@ +
+
+ Small + +
+
+ Medium + +
+
+ Large + +
+
diff --git a/src/app/data-entries/color-picker/sizes/color-picker-sizes.component.scss b/src/app/data-entries/color-picker/sizes/color-picker-sizes.component.scss new file mode 100644 index 0000000000..708377b7c8 --- /dev/null +++ b/src/app/data-entries/color-picker/sizes/color-picker-sizes.component.scss @@ -0,0 +1,40 @@ +.small-picker { + --ig-size: var(--ig-size-small); +} + +.medium-picker { + --ig-size: var(--ig-size-medium); +} + +.large-picker { + --ig-size: var(--ig-size-large); +} + +.sample-container { + display: flex; + flex-direction: row; + justify-content: center; + gap: 2rem; + padding-block-start: 0.5rem; + font-family: "Aktiv Grotesk", sans-serif; +} + +span { + display: block; + text-align: center; + margin-block-end: 1rem; + color: var(--ig-gray-600); +} + +igc-color-picker::part(picker) { + --picker-elevation: var(--ig-elevation-4); + + margin-top: 0.5rem; +} + +@media (width < 450px) { + .sample-container { + flex-direction: column; + align-items: center; + } +} diff --git a/src/app/data-entries/color-picker/sizes/color-picker-sizes.component.ts b/src/app/data-entries/color-picker/sizes/color-picker-sizes.component.ts new file mode 100644 index 0000000000..9d0a203e94 --- /dev/null +++ b/src/app/data-entries/color-picker/sizes/color-picker-sizes.component.ts @@ -0,0 +1,21 @@ +import { Component, CUSTOM_ELEMENTS_SCHEMA, ViewChild, ElementRef, AfterViewInit } from '@angular/core'; +import { defineComponents, IgcColorPickerComponent } from 'igniteui-webcomponents'; + +defineComponents(IgcColorPickerComponent); + +@Component({ + selector: 'app-color-picker-sizes', + styleUrls: ['./color-picker-sizes.component.scss'], + templateUrl: './color-picker-sizes.component.html', + imports: [], + schemas: [CUSTOM_ELEMENTS_SCHEMA] +}) + +export class ColorPickerSizesComponent implements AfterViewInit { + @ViewChild('colorPicker', { static: true }) + colorPicker!: ElementRef; + + ngAfterViewInit() { + this.colorPicker.nativeElement.toggle(); + } +} diff --git a/src/app/data-entries/color-picker/states/color-picker-states.component.html b/src/app/data-entries/color-picker/states/color-picker-states.component.html new file mode 100644 index 0000000000..5ac47a4df9 --- /dev/null +++ b/src/app/data-entries/color-picker/states/color-picker-states.component.html @@ -0,0 +1,14 @@ +
+
+ Default state + +
+
+ Invalid state + +
+
+ Disabled state + +
+
diff --git a/src/app/data-entries/color-picker/states/color-picker-states.component.scss b/src/app/data-entries/color-picker/states/color-picker-states.component.scss new file mode 100644 index 0000000000..37ab4063ce --- /dev/null +++ b/src/app/data-entries/color-picker/states/color-picker-states.component.scss @@ -0,0 +1,30 @@ +.sample-container { + --ig-size: 2; + + display: flex; + flex-direction: row; + justify-content: center; + gap: 2rem; + padding-block-start: 0.5rem; + font-family: "Aktiv Grotesk", sans-serif; +} + +span { + display: block; + text-align: center; + margin-block-end: 1rem; + color: var(--ig-gray-600); +} + +igc-color-picker::part(picker) { + --picker-elevation: var(--ig-elevation-4); + + margin-top: 0.5rem; +} + +@media (width < 450px) { + .sample-container { + flex-direction: column; + align-items: center; + } +} diff --git a/src/app/data-entries/color-picker/states/color-picker-states.component.ts b/src/app/data-entries/color-picker/states/color-picker-states.component.ts new file mode 100644 index 0000000000..1578339f88 --- /dev/null +++ b/src/app/data-entries/color-picker/states/color-picker-states.component.ts @@ -0,0 +1,27 @@ +import { Component, CUSTOM_ELEMENTS_SCHEMA, ViewChild, ElementRef, AfterViewInit } from '@angular/core'; +import { defineComponents, IgcColorPickerComponent } from 'igniteui-webcomponents'; + +defineComponents(IgcColorPickerComponent); + +@Component({ + selector: 'app-color-picker-states', + styleUrls: ['./color-picker-states.component.scss'], + templateUrl: './color-picker-states.component.html', + imports: [], + schemas: [CUSTOM_ELEMENTS_SCHEMA] +}) + +export class ColorPickerStatesComponent implements AfterViewInit { + public invalid = true; + + public onInput(): void { + this.invalid = false; + } + + @ViewChild('colorPicker', { static: true }) + colorPicker!: ElementRef; + + ngAfterViewInit() { + this.colorPicker.nativeElement.toggle(); + } +} diff --git a/src/app/data-entries/color-picker/styling/color-picker-styling.component.html b/src/app/data-entries/color-picker/styling/color-picker-styling.component.html new file mode 100644 index 0000000000..29b527c55f --- /dev/null +++ b/src/app/data-entries/color-picker/styling/color-picker-styling.component.html @@ -0,0 +1,57 @@ +
+
+
+ Text +
+ +
+
+
+ Alignment +
+ + + + +
+
+
+ Content +
+ + + +
+
+
+ Charts +
+ +
+
+
+ Colors +
+ +
+
+
+
diff --git a/src/app/data-entries/color-picker/styling/color-picker-styling.component.scss b/src/app/data-entries/color-picker/styling/color-picker-styling.component.scss new file mode 100644 index 0000000000..055ca3c761 --- /dev/null +++ b/src/app/data-entries/color-picker/styling/color-picker-styling.component.scss @@ -0,0 +1,16 @@ +@use "layout.scss"; + +igc-color-picker { + --ig-color-picker-picker-background: #e6f2ff; + --ig-color-picker-picker-border-color: #a9b8cc; + --ig-color-picker-picker-border-radius: 1rem; + --ig-color-picker-picker-elevation: none; +} + +igc-color-picker::part(anchor) { + border: 0.125rem solid #a9b8cc; +} + +igc-color-picker::part(picker-canvas) { + border-radius: 0.25rem; +} diff --git a/src/app/data-entries/color-picker/styling/color-picker-styling.component.ts b/src/app/data-entries/color-picker/styling/color-picker-styling.component.ts new file mode 100644 index 0000000000..43903a85f0 --- /dev/null +++ b/src/app/data-entries/color-picker/styling/color-picker-styling.component.ts @@ -0,0 +1,16 @@ +import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { defineComponents, IgcColorPickerComponent } from 'igniteui-webcomponents'; +import { IgxIconButtonDirective } from 'igniteui-angular/directives'; +import { IgxIconComponent } from 'igniteui-angular/icon'; + +defineComponents(IgcColorPickerComponent); + +@Component({ + selector: 'app-color-picker-styling', + styleUrls: ['./color-picker-styling.component.scss'], + templateUrl: './color-picker-styling.component.html', + imports: [IgxIconButtonDirective, IgxIconComponent], + schemas: [CUSTOM_ELEMENTS_SCHEMA] +}) + +export class ColorPickerStylingComponent {} diff --git a/src/app/data-entries/color-picker/styling/layout.scss b/src/app/data-entries/color-picker/styling/layout.scss new file mode 100644 index 0000000000..6a8181ff03 --- /dev/null +++ b/src/app/data-entries/color-picker/styling/layout.scss @@ -0,0 +1,99 @@ +.sample-container { + --ig-size: 2; + + display: flex; + justify-content: center; + align-items: center; + padding-block-start: 0.5rem; +} + +.editor-toolbar { + display: flex; + align-items: stretch; + gap: 0.5rem; + padding: 1rem; + border-radius: 1rem; + background: #00142b; + font-family: "Aktiv Grotesk", sans-serif; +} + +.toolbar-group { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 0.5rem; +} + +.toolbar-group-label { + font-size: 0.75rem; + font-weight: 600; + line-height: 1rem; + letter-spacing: 0.009375rem; + color: #d2dbe8; +} + +.toolbar-actions { + border-radius: 0.5rem; + background: #556c86; +} + +[igxIconButton] { + width: fit-content; + height: fit-content; + padding: 0.5rem; + --foreground: #fcfcfc; + --hover-foreground: #fff; +} + +[igxIconButton] igx-icon { + --size: 0.875rem; + width: 1.6em; + height: 1.6em; + align-items: center; + justify-content: center; +} + +.toolbar-group:nth-child(2) { + [igxIconButton]:nth-of-type(2) { + padding-inline: unset; + } + + [igxIconButton]:nth-of-type(3) { + padding-inline-end: unset; + } +} + +.toolbar-group:nth-child(3) [igxIconButton]:nth-of-type(2) { + padding-inline: unset; +} + +igc-color-picker { + --ig-size: var(--ig-size-small); + --ig-input-group-border-color: transparent; + --ig-input-group-hover-border-color: rgb(255 255 255 / 15%); + --ig-input-group-focused-border-color: transparent; + --ig-input-group-border-border-radius: 0.5rem; + --ig-input-group-filled-text-color: #fff; + --ig-input-group-filled-text-hover-color: #fff; + --ig-input-group-focused-text-color: #fff; + --ig-input-group-placeholder-color: #fff; + --ig-input-group-hover-placeholder-color: #fff; + --ig-input-group-focus-placeholder-color: #fff; + + width: 8.75rem; +} + +igc-color-picker::part(picker) { + --ig-input-group-filled-text-color: var(--ig-gray-900); + --ig-input-group-filled-text-hover-color: var(--ig-gray-900); + --ig-input-group-focused-text-color: var(--ig-gray-900); + --ig-input-group-placeholder-color: var(--ig-gray-900); + --ig-input-group-hover-placeholder-color: var(--ig-gray-900); + --ig-input-group-focus-placeholder-color: var(--ig-gray-900); + --ig-input-group-border-color: var(--ig-gray-500); + --ig-input-group-hover-border-color: var(--ig-gray-500); + --ig-input-group-focused-border-color: var(--ig-gray-500); + --ig-input-group-border-border-radius: 0.25rem; + + margin-top: 1.25rem; +} \ No newline at end of file diff --git a/src/app/data-entries/color-picker/swatches/color-picker-swatches.component.html b/src/app/data-entries/color-picker/swatches/color-picker-swatches.component.html new file mode 100644 index 0000000000..8408e1d465 --- /dev/null +++ b/src/app/data-entries/color-picker/swatches/color-picker-swatches.component.html @@ -0,0 +1,4 @@ +
+ + +
diff --git a/src/app/data-entries/color-picker/swatches/color-picker-swatches.component.scss b/src/app/data-entries/color-picker/swatches/color-picker-swatches.component.scss new file mode 100644 index 0000000000..b4ca3f0bb6 --- /dev/null +++ b/src/app/data-entries/color-picker/swatches/color-picker-swatches.component.scss @@ -0,0 +1,14 @@ +.sample-container { + --ig-size: 2; + + display: flex; + flex-direction: row; + justify-content: space-between; + padding-block-start: 0.5rem; +} + +igc-color-picker::part(picker) { + --picker-elevation: var(--ig-elevation-4); + + margin-top: 0.5rem; +} \ No newline at end of file diff --git a/src/app/data-entries/color-picker/swatches/color-picker-swatches.component.ts b/src/app/data-entries/color-picker/swatches/color-picker-swatches.component.ts new file mode 100644 index 0000000000..e2d803fc53 --- /dev/null +++ b/src/app/data-entries/color-picker/swatches/color-picker-swatches.component.ts @@ -0,0 +1,31 @@ +import { Component, CUSTOM_ELEMENTS_SCHEMA, ViewChild, ElementRef, AfterViewInit } from '@angular/core'; +import { defineComponents, IgcColorPickerComponent } from 'igniteui-webcomponents'; + +defineComponents(IgcColorPickerComponent); + +@Component({ + selector: 'app-color-picker-swatches', + styleUrls: ['./color-picker-swatches.component.scss'], + templateUrl: './color-picker-swatches.component.html', + imports: [], + schemas: [CUSTOM_ELEMENTS_SCHEMA] +}) + +export class ColorPickerSwatchesComponent implements AfterViewInit { + public oneLineSwatches = ['#f44336', '#e91e63', '#9c27b0', '#3f51b5', '#2196f3', '#4caf50']; + + public multiLineSwatches = [ + '#f44336', '#e91e63', '#9c27b0', '#3f51b5', '#2196f3', '#4caf50', '#ffeb3b', '#ff9800', '#795548', '#607d8b', '#ffffff', '#000000', '#0000ff', '#00ff00', '#ff00ff', '#00ffff', '#ff0000', '#ffff00', '#ff00ff', '#00ffff', '#c0c0c0', '#808080', '#800000', '#808000' + ]; + + @ViewChild('colorPicker1', { static: true }) + colorPicker1!: ElementRef; + + @ViewChild('colorPicker2', { static: true }) + colorPicker2!: ElementRef; + + ngAfterViewInit() { + this.colorPicker1.nativeElement.toggle(); + this.colorPicker2.nativeElement.toggle(); + } +} diff --git a/src/app/data-entries/color-picker/tailwind-styling/color-picker-tailwind-styling.component.html b/src/app/data-entries/color-picker/tailwind-styling/color-picker-tailwind-styling.component.html new file mode 100644 index 0000000000..85e1cf2920 --- /dev/null +++ b/src/app/data-entries/color-picker/tailwind-styling/color-picker-tailwind-styling.component.html @@ -0,0 +1,62 @@ +
+
+
+
+

Theme Editor

+

Use the pickers to style the card.

+
+ +
+
+
+ + Card surface color + +
+
+ + Body & heading color + +
+
+ + Button & tag color + +
+
+ + Card edge color + +
+
+ + Upgrade to unlock + +
+
+ + + Design +

Color Picker in Practice

+

Pick colors above to see them applied live across every element of this card.

+
+ + +
+
+
+
+
diff --git a/src/app/data-entries/color-picker/tailwind-styling/color-picker-tailwind-styling.component.scss b/src/app/data-entries/color-picker/tailwind-styling/color-picker-tailwind-styling.component.scss new file mode 100644 index 0000000000..b76c19079b --- /dev/null +++ b/src/app/data-entries/color-picker/tailwind-styling/color-picker-tailwind-styling.component.scss @@ -0,0 +1,176 @@ +igc-color-picker::part(copy), +igc-color-picker::part(eye-dropper) { + --foreground: #c6451b; +} + +igc-color-picker::part(picker) { + --ig-input-group-border-color: #f95924; + --ig-input-group-hover-border-color: #f95924; + --ig-input-group-focused-border-color: #f95924; + + margin-top: 1.25rem; +} + +igc-color-picker::part(buttons) { + gap: 0rem; +} + +igc-color-picker { + --ig-color-picker-picker-elevation: none; +} + +.sample-container { + --ig-size: 2; + + display: flex; + height: fit-content; + max-width: 55rem; + margin-inline: auto; + padding-block-start: 0.5rem; +} + +.theme-editor { + --ig-font-family: "Aktiv Grotesk", sans-serif; + + width: 100%; + border-radius: 0.75rem; + border: 0.063rem solid; + padding: 1.5rem; + border-color: var(--ig-gray-200); + background: var(--ig-surface-500); +} + +.theme-editor-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 0.5rem 1rem; + border-bottom: 0.063rem solid; + border-color: var(--ig-gray-200); +} + +.theme-editor-header h2 { + font-size: 1rem; + line-height: 1.5rem; + font-weight: 600; + margin: 0; + color: var(--ig-gray-900); + letter-spacing: 0.009rem; +} + +.theme-editor-header p { + font-size: 0.875rem; + line-height: 1.25rem; + margin: 0.125rem 0 0; + color: var(--ig-gray-600); +} + +.theme-editor-header igx-icon { + --size: 1.5rem; +} + +.swatches { + display: flex; + flex-wrap: wrap; + gap: 1.5rem; + padding: 1.5rem 1rem 1rem; +} + +.swatch-item { + display: flex; + align-items: center; + gap: 0.5rem; + max-width: 8.5rem; + width: 100%; +} + +.swatch-item igc-color-picker { + --ig-color-picker-anchor-border-radius: 0.375rem; + --ig-color-picker-label-color: var(--ig-gray-900); +} + +.swatch-item igc-color-picker::part(label) { + font-size: 0.875rem; + line-height: 1.25rem; + font-weight: 500; +} + +igc-color-picker::part(anchor) { + --anchor-border-radius: 0.25rem; + --anchor-border-color: var(--ig-gray-600); + --swatch-preview-border-color: var(--ig-gray-300); +} + +.swatch-item.disabled igc-color-picker { + --ig-color-picker-label-color-disabled: var(--ig-gray-400); +} + +.swatch-item.disabled .swatch-hint { + color: var(--ig-gray-400); +} + +.swatch-hint { + font-size: 0.75rem; + line-height: 1rem; + color: var(--ig-gray-600); +} + +igx-card { + margin-block-start: 1rem; + border-radius: 0.5rem; + background: var(--preview-bg); + border: 0.063rem solid var(--preview-border); + box-shadow: var(--ig-elevation-4); +} + +.preview-chip { + --ig-size: var(--ig-size-large); + --ig-chip-background: color-mix(in srgb, var(--preview-accent) 25%, transparent); + --ig-chip-hover-background: color-mix(in srgb, var(--preview-accent) 75%, transparent); + --ig-chip-text-color: var(--preview-accent); +} + +.preview-primary, +.preview-secondary { + --ig-size: var(--ig-size-medium); + text-transform: capitalize; +} + +.preview-primary { + --background: var(--preview-accent); + --foreground: var(--preview-bg); + --hover-background: hsl(from var(--preview-accent) h s 40%); +} + +.preview-secondary { + --foreground: var(--preview-accent); + --hover-foreground: hsl(from var(--preview-accent) h s 40%); + --border-color: var(--preview-accent); + --hover-border-color: hsl(from var(--preview-accent) h s 40%); + min-width: unset; +} + +.preview-title, +.preview-text { + color: var(--preview-text); +} + +.preview-title { + font-size: 1rem; + line-height: 1.5rem; + font-weight: 600; + margin: 1rem 0 0.25rem; + letter-spacing: 0.009rem; +} + +.preview-text { + font-size: 0.875rem; + line-height: 1.25rem; + font-weight: 500; +} + +.preview-actions { + display: flex; + gap: 0.75rem; + margin-top: 1.25rem; +} diff --git a/src/app/data-entries/color-picker/tailwind-styling/color-picker-tailwind-styling.component.ts b/src/app/data-entries/color-picker/tailwind-styling/color-picker-tailwind-styling.component.ts new file mode 100644 index 0000000000..5223f3be76 --- /dev/null +++ b/src/app/data-entries/color-picker/tailwind-styling/color-picker-tailwind-styling.component.ts @@ -0,0 +1,60 @@ +import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { defineComponents, IgcColorPickerComponent } from 'igniteui-webcomponents'; +import { IgxCardComponent, IgxCardContentDirective } from 'igniteui-angular/card'; +import { IgxButtonDirective, IgxIconButtonDirective, IgxRippleDirective } from 'igniteui-angular/directives'; +import { IgxIconComponent } from 'igniteui-angular/icon'; +import { IgxChipComponent } from 'igniteui-angular/chips'; + +defineComponents(IgcColorPickerComponent); + +const defaults = { + background: '#1a314a', + text: '#e5ebf3', + accent: '#f9592a', + border: '#00142b' +}; + +@Component({ + selector: 'app-color-picker-tailwind-styling', + styleUrls: ['./color-picker-tailwind-styling.component.scss'], + templateUrl: './color-picker-tailwind-styling.component.html', + imports: [ + IgxCardComponent, + IgxCardContentDirective, + IgxButtonDirective, + IgxIconButtonDirective, + IgxRippleDirective, + IgxIconComponent, + IgxChipComponent + ], + schemas: [CUSTOM_ELEMENTS_SCHEMA] +}) +export class ColorPickerTailwindStylingComponent { + public background = defaults.background; + public text = defaults.text; + public accent = defaults.accent; + public border = defaults.border; + + public onBackgroundInput(event: Event): void { + this.background = (event as CustomEvent).detail; + } + + public onTextInput(event: Event): void { + this.text = (event as CustomEvent).detail; + } + + public onAccentInput(event: Event): void { + this.accent = (event as CustomEvent).detail; + } + + public onBorderInput(event: Event): void { + this.border = (event as CustomEvent).detail; + } + + public reset(): void { + this.background = defaults.background; + this.text = defaults.text; + this.accent = defaults.accent; + this.border = defaults.border; + } +} diff --git a/src/app/data-entries/color-picker/value/color-picker-value.component.html b/src/app/data-entries/color-picker/value/color-picker-value.component.html new file mode 100644 index 0000000000..6c4d826eda --- /dev/null +++ b/src/app/data-entries/color-picker/value/color-picker-value.component.html @@ -0,0 +1,3 @@ +
+ +
diff --git a/src/app/data-entries/color-picker/value/color-picker-value.component.scss b/src/app/data-entries/color-picker/value/color-picker-value.component.scss new file mode 100644 index 0000000000..3b5129b704 --- /dev/null +++ b/src/app/data-entries/color-picker/value/color-picker-value.component.scss @@ -0,0 +1,17 @@ +.sample-container { + --ig-size: 2; + + display: flex; + justify-content: center; + padding-block-start: 0.5rem; +} + +igc-color-picker::part(picker) { + --picker-elevation: var(--ig-elevation-4); + + margin-top: 0.5rem; +} + +:root { + overflow: auto; +} diff --git a/src/app/data-entries/color-picker/value/color-picker-value.component.ts b/src/app/data-entries/color-picker/value/color-picker-value.component.ts new file mode 100644 index 0000000000..310a701495 --- /dev/null +++ b/src/app/data-entries/color-picker/value/color-picker-value.component.ts @@ -0,0 +1,21 @@ +import { Component, CUSTOM_ELEMENTS_SCHEMA, ViewChild, ElementRef, AfterViewInit } from '@angular/core'; +import { defineComponents, IgcColorPickerComponent } from 'igniteui-webcomponents'; + +defineComponents(IgcColorPickerComponent); + +@Component({ + selector: 'app-color-picker-value', + styleUrls: ['./color-picker-value.component.scss'], + templateUrl: './color-picker-value.component.html', + imports: [], + schemas: [CUSTOM_ELEMENTS_SCHEMA] +}) + +export class ColorPickerValueComponent implements AfterViewInit { + @ViewChild('colorPicker', { static: true }) + colorPicker!: ElementRef; + + ngAfterViewInit() { + this.colorPicker.nativeElement.toggle(); + } +} diff --git a/src/app/data-entries/data-entries-routes-data.ts b/src/app/data-entries/data-entries-routes-data.ts index c12dffbf41..eb06f34909 100644 --- a/src/app/data-entries/data-entries-routes-data.ts +++ b/src/app/data-entries/data-entries-routes-data.ts @@ -29,6 +29,18 @@ export const dataEntriesRoutesData = { "checkbox-sample-3": { displayName: "Indeterminate Checkbox", parentName: "Checkbox" }, "checkbox-styling": { displayName: "Checkbox Styling", parentName: "Checkbox" }, "checkbox-tailwind-styling": { displayName: "Checkbox Tailwind Styling", parentName: "Checkbox" }, + "color-picker-overview": { displayName: "Overview", parentName: "Color Picker" }, + "color-picker-value": { displayName: "Value", parentName: "Color Picker" }, + "color-picker-input": { displayName: "Input Mode", parentName: "Color Picker" }, + "color-picker-format": { displayName: "Format", parentName: "Color Picker" }, + "color-picker-alpha": { displayName: "Alpha", parentName: "Color Picker" }, + "color-picker-swatches": { displayName: "Swatches", parentName: "Color Picker" }, + "color-picker-states": { displayName: "States", parentName: "Color Picker" }, + "color-picker-sizes": { displayName: "Sizes", parentName: "Color Picker" }, + "color-picker-input-sizes": { displayName: "Input Sizes", parentName: "Color Picker" }, + "color-picker-styling": { displayName: "Color Picker Styling", parentName: "Color Picker" }, + "color-picker-tailwind-styling": { displayName: "Color Picker Tailwind Styling", parentName: "Color Picker" }, + "color-picker-reactive-form": { displayName: "Color Picker in Reactive Form", parentName: "Color Picker" }, "dropdown-remote": { displayName: "Virtual Dropdown - Remote Data", parentName: "Dropdown" }, "dropdown-virtual": { displayName: "Virtual Dropdown", parentName: "Dropdown" }, "dropdown-menu": { displayName: "Dropdown as Menu", parentName: "Dropdown" }, diff --git a/src/app/data-entries/data-entries.routes.ts b/src/app/data-entries/data-entries.routes.ts index 8132650c35..5a7a06e8b8 100644 --- a/src/app/data-entries/data-entries.routes.ts +++ b/src/app/data-entries/data-entries.routes.ts @@ -28,6 +28,18 @@ import { CheckboxSample2Component } from './checkbox/checkbox-sample-2/checkbox- import { CheckboxSample3Component } from './checkbox/checkbox-sample-3/checkbox-sample-3.component'; import { CheckboxStylingComponent } from './checkbox/checkbox-styling/checkbox-styling.component'; import { CheckboxTailwindStylingComponent } from './checkbox/checkbox-tailwind-styling/checkbox-tailwind-styling.component'; +import { ColorPickerOverviewComponent } from './color-picker/overview/color-picker-overview.component'; +import { ColorPickerValueComponent } from './color-picker/value/color-picker-value.component'; +import { ColorPickerInputComponent } from './color-picker/input/color-picker-input.component'; +import { ColorPickerFormatComponent } from './color-picker/format/color-picker-format.component'; +import { ColorPickerAlphaComponent } from './color-picker/alpha/color-picker-alpha.component'; +import { ColorPickerSwatchesComponent } from './color-picker/swatches/color-picker-swatches.component'; +import { ColorPickerStatesComponent } from './color-picker/states/color-picker-states.component'; +import { ColorPickerSizesComponent } from './color-picker/sizes/color-picker-sizes.component'; +import { ColorPickerInputSizesComponent } from './color-picker/input-sizes/color-picker-input-sizes.component'; +import { ColorPickerStylingComponent } from './color-picker/styling/color-picker-styling.component'; +import { ColorPickerTailwindStylingComponent } from './color-picker/tailwind-styling/color-picker-tailwind-styling.component'; +import { ColorPickerReactiveFormComponent } from './color-picker/reactive-form/color-picker-reactive-form.component'; import { dataEntriesRoutesData } from './data-entries-routes-data'; import { DropDownRemoteComponent } from './dropdown/drop-down-remote-virtual/drop-down-remote.component'; import { DropDownVirtualComponent } from './dropdown/drop-down-virtual/drop-down-virtual.component'; @@ -233,6 +245,66 @@ export const DataEntriesRoutes: Routes = [ data: dataEntriesRoutesData['checkbox-tailwind-styling'], path: 'checkbox-tailwind-styling' }, + { + component: ColorPickerOverviewComponent, + data: dataEntriesRoutesData['color-picker-overview'], + path: 'color-picker-overview' + }, + { + component: ColorPickerValueComponent, + data: dataEntriesRoutesData['color-picker-value'], + path: 'color-picker-value' + }, + { + component: ColorPickerInputComponent, + data: dataEntriesRoutesData['color-picker-input'], + path: 'color-picker-input' + }, + { + component: ColorPickerFormatComponent, + data: dataEntriesRoutesData['color-picker-format'], + path: 'color-picker-format' + }, + { + component: ColorPickerAlphaComponent, + data: dataEntriesRoutesData['color-picker-alpha'], + path: 'color-picker-alpha' + }, + { + component: ColorPickerSwatchesComponent, + data: dataEntriesRoutesData['color-picker-swatches'], + path: 'color-picker-swatches' + }, + { + component: ColorPickerStatesComponent, + data: dataEntriesRoutesData['color-picker-states'], + path: 'color-picker-states' + }, + { + component: ColorPickerSizesComponent, + data: dataEntriesRoutesData['color-picker-sizes'], + path: 'color-picker-sizes' + }, + { + component: ColorPickerInputSizesComponent, + data: dataEntriesRoutesData['color-picker-input-sizes'], + path: 'color-picker-input-sizes' + }, + { + component: ColorPickerStylingComponent, + data: dataEntriesRoutesData['color-picker-styling'], + path: 'color-picker-styling' + }, + { + component: ColorPickerTailwindStylingComponent, + data: dataEntriesRoutesData['color-picker-tailwind-styling'], + path: 'color-picker-tailwind-styling' + }, + { + component: ColorPickerReactiveFormComponent, + data: dataEntriesRoutesData['color-picker-reactive-form'], + path: 'color-picker-reactive-form' + }, { component: DropdownMenuComponent, data: dataEntriesRoutesData['dropdown-menu'], From 25258e6cf46871173706259e8fab1b12d23dfe9b Mon Sep 17 00:00:00 2001 From: Ivan Minchev <61944284+IMinchev64@users.noreply.github.com> Date: Fri, 25 Sep 2026 19:41:16 +0300 Subject: [PATCH 22/22] feat(accordion): update accordion samples for new documentation (#3999) * feat(accordion): add programmatic expansion sample * feat(accordion): update accordion layout and styling * fix(accordion): add border to accordion for better visibility --- .../configs/AccordionConfigGenerator.ts | 6 ++ .../accordion-customization.component.html | 70 +++++++++++++++++++ .../accordion-customization.component.scss | 66 +++++++++++++++++ .../accordion-customization.component.ts | 52 ++++++++++++++ .../accordion-nested-scenario.component.html | 69 ++++++++++++++++++ .../accordion-nested-scenario.component.scss | 24 +++++++ .../accordion-nested-scenario.component.ts | 16 +++++ .../accordion-overview.component.html | 37 ++++++++++ .../accordion-overview.component.scss | 24 +++++++ .../accordion-overview.component.ts | 16 +++++ ...dion-programmatic-expansion.component.html | 40 +++++++++++ ...dion-programmatic-expansion.component.scss | 29 ++++++++ ...ordion-programmatic-expansion.component.ts | 14 ++++ .../accordion-styling.component.html | 35 ++++++++++ .../accordion-styling.component.scss | 50 +++++++++++++ .../accordion-styling.component.ts | 12 ++++ .../accordion-tailwind-styling.component.html | 35 ++++++++++ .../accordion-tailwind-styling.component.scss | 20 ++++++ .../accordion-tailwind-styling.component.ts | 12 ++++ src/app/layouts/layouts-routes-data.ts | 6 ++ src/app/layouts/layouts.routes.ts | 36 ++++++++++ 21 files changed, 669 insertions(+) create mode 100644 src/app/layouts/accordion/accordion-customization/accordion-customization.component.html create mode 100644 src/app/layouts/accordion/accordion-customization/accordion-customization.component.scss create mode 100644 src/app/layouts/accordion/accordion-customization/accordion-customization.component.ts create mode 100644 src/app/layouts/accordion/accordion-nested-scenario/accordion-nested-scenario.component.html create mode 100644 src/app/layouts/accordion/accordion-nested-scenario/accordion-nested-scenario.component.scss create mode 100644 src/app/layouts/accordion/accordion-nested-scenario/accordion-nested-scenario.component.ts create mode 100644 src/app/layouts/accordion/accordion-overview/accordion-overview.component.html create mode 100644 src/app/layouts/accordion/accordion-overview/accordion-overview.component.scss create mode 100644 src/app/layouts/accordion/accordion-overview/accordion-overview.component.ts create mode 100644 src/app/layouts/accordion/accordion-programmatic-expansion/accordion-programmatic-expansion.component.html create mode 100644 src/app/layouts/accordion/accordion-programmatic-expansion/accordion-programmatic-expansion.component.scss create mode 100644 src/app/layouts/accordion/accordion-programmatic-expansion/accordion-programmatic-expansion.component.ts create mode 100644 src/app/layouts/accordion/accordion-styling/accordion-styling.component.html create mode 100644 src/app/layouts/accordion/accordion-styling/accordion-styling.component.scss create mode 100644 src/app/layouts/accordion/accordion-styling/accordion-styling.component.ts create mode 100644 src/app/layouts/accordion/accordion-tailwind-styling/accordion-tailwind-styling.component.html create mode 100644 src/app/layouts/accordion/accordion-tailwind-styling/accordion-tailwind-styling.component.scss create mode 100644 src/app/layouts/accordion/accordion-tailwind-styling/accordion-tailwind-styling.component.ts diff --git a/live-editing/configs/AccordionConfigGenerator.ts b/live-editing/configs/AccordionConfigGenerator.ts index 58d7c2bca3..d35dece3ed 100644 --- a/live-editing/configs/AccordionConfigGenerator.ts +++ b/live-editing/configs/AccordionConfigGenerator.ts @@ -31,6 +31,12 @@ export class AccordionConfigGenerator implements IConfigGenerator { shortenComponentPathBy: '/layouts/accordion/' })); + configs.push(new Config({ + component: 'AccordionProgrammaticExpansionComponent', + appConfig: BaseAppConfig, + shortenComponentPathBy: '/layouts/accordion/' + })); + configs.push(new Config({ component: 'AccordionStyleComponent', additionalFiles: ["/src/app/layouts/accordion/accordion-style/layout.scss"], diff --git a/src/app/layouts/accordion/accordion-customization/accordion-customization.component.html b/src/app/layouts/accordion/accordion-customization/accordion-customization.component.html new file mode 100644 index 0000000000..f3d9ddfe51 --- /dev/null +++ b/src/app/layouts/accordion/accordion-customization/accordion-customization.component.html @@ -0,0 +1,70 @@ +
+
+ + + + Transportation@if (selectedCategories) {: {{ selectedCategories }}} + Choose how you want to travel + + +

Select one or more transportation options for your trip.

+
+ @for (category of categories; track category.type) { + {{ category.type }} + } +
+
+
+ + + + Budget: ${{ slider.lowerValue }} - ${{ slider.upperValue }} + Set the price range + + +

Adjust the minimum and maximum cost for available options.

+
+ ${{ slider.lowerValue }} + ${{ slider.upperValue }} +
+ +
+
+ + + + Minimum Rating@if (rating) {: {{ rating }}} + Filter by review score + + +

Choose the lowest rating you want to include in the results.

+
+ @for (ratingOption of ratingOptions; track ratingOption) { + + {{ ratingOption }} stars or more + + @for (star of [].constructor(ratingOption); track $index) { + star + } + + + } +
+
+
+ + + + Arrival Time{{ time }} + Set the latest arrival time + + +

Pick the latest acceptable arrival time for your trip.

+ + + +
+
+
+
+
diff --git a/src/app/layouts/accordion/accordion-customization/accordion-customization.component.scss b/src/app/layouts/accordion/accordion-customization/accordion-customization.component.scss new file mode 100644 index 0000000000..f2b6961adc --- /dev/null +++ b/src/app/layouts/accordion/accordion-customization/accordion-customization.component.scss @@ -0,0 +1,66 @@ +.accordion-sample { + width: 100%; + height: 100%; + overflow-y: auto; +} + +.accordion-content { + width: min(760px, 100%); + margin: 0 auto; + padding: 24px; + box-sizing: border-box; +} + +igx-accordion { + display: block; + border: 1px solid var(--ig-gray-300); + border-radius: 4px; +} + +.panel-description { + margin: 0 0 16px; + color: var(--ig-gray-700); +} + +.categories-container { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 8px 24px; + max-width: 520px; +} + +.category-option, +.rating-option { + margin: 4px 0; +} + +.range-summary { + display: flex; + justify-content: space-between; + max-width: 560px; + margin-bottom: 4px; + font-weight: 600; +} + +.cost-slider { + max-width: 560px; + margin: 8px 0 0; +} + +.rating-options { + display: grid; + gap: 8px; + max-width: 360px; +} + +.rating-control { + flex-direction: row; +} + +.time-input { + max-width: 260px; +} + +.size-small { + --ig-size: var(--ig-size-small); +} diff --git a/src/app/layouts/accordion/accordion-customization/accordion-customization.component.ts b/src/app/layouts/accordion/accordion-customization/accordion-customization.component.ts new file mode 100644 index 0000000000..82311cc43c --- /dev/null +++ b/src/app/layouts/accordion/accordion-customization/accordion-customization.component.ts @@ -0,0 +1,52 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { IgxAccordionComponent } from 'igniteui-angular/accordion'; +import { IgxCheckboxComponent } from 'igniteui-angular/checkbox'; +import { IgxExpansionPanelBodyComponent, IgxExpansionPanelComponent, IgxExpansionPanelDescriptionDirective, IgxExpansionPanelHeaderComponent, IgxExpansionPanelTitleDirective } from 'igniteui-angular/expansion-panel'; +import { IgxIconComponent } from 'igniteui-angular/icon'; +import { IgxRadioComponent } from 'igniteui-angular/radio'; +import { IgxSliderComponent, IgxSliderType } from 'igniteui-angular/slider'; +import { IgxLabelDirective } from 'igniteui-angular/input-group'; +import { IgxTimePickerComponent } from 'igniteui-angular/time-picker'; + +@Component({ + selector: 'app-accordion-customization', + styleUrls: ['./accordion-customization.component.scss'], + templateUrl: './accordion-customization.component.html', + changeDetection: ChangeDetectionStrategy.Eager, + imports: [FormsModule, IgxAccordionComponent, IgxExpansionPanelComponent, IgxExpansionPanelHeaderComponent, IgxExpansionPanelTitleDirective, IgxExpansionPanelDescriptionDirective, IgxExpansionPanelBodyComponent, IgxCheckboxComponent, IgxSliderComponent, IgxRadioComponent, IgxIconComponent, IgxTimePickerComponent, IgxLabelDirective] +}) +export class AccordionCustomizationComponent { + public readonly ratingOptions = [2, 3, 4, 5]; + public readonly sliderType = IgxSliderType; + public priceRange = new PriceRange(200, 800); + public rating = ''; + public arriveTime: Date | null = null; + + public categories = [ + { checked: false, type: 'Bike' }, + { checked: false, type: 'Motorcycle' }, + { checked: false, type: 'Car' }, + { checked: false, type: 'Taxi' }, + { checked: false, type: 'Public Transport' } + ]; + + public get selectedCategories(): string { + return this.categories + .filter(item => item.checked) + .map(item => item.type) + .join(', '); + } + + public get time(): string { + return this.arriveTime ? `: ${this.arriveTime.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}` : ''; + } +} + +class PriceRange { + constructor( + public lower: number, + public upper: number + ) { + } +} diff --git a/src/app/layouts/accordion/accordion-nested-scenario/accordion-nested-scenario.component.html b/src/app/layouts/accordion/accordion-nested-scenario/accordion-nested-scenario.component.html new file mode 100644 index 0000000000..7b66ad84dd --- /dev/null +++ b/src/app/layouts/accordion/accordion-nested-scenario/accordion-nested-scenario.component.html @@ -0,0 +1,69 @@ +
+
+
+ Single Expand +
+ + + + + Workspace Settings + Nested account, access, and billing options + + + + + + Profile + Name, photo, and contact details + + +

Update the public information shown to other workspace members.

+
+
+ + + + Security + Password and sign-in preferences + + +

Review active sessions, change your password, and configure sign-in requirements.

+
+
+ + + + Notifications + Email and product updates + + +

Choose the messages you receive for comments, assignments, and releases.

+
+
+
+
+
+ + + + Team Access + Members, roles, and permissions + + +

Invite teammates, assign roles, and review workspace permissions.

+
+
+ + + + Billing + Plan, invoices, and payment method + + +

Manage subscription details, billing contacts, and invoice delivery.

+
+
+
+
+
diff --git a/src/app/layouts/accordion/accordion-nested-scenario/accordion-nested-scenario.component.scss b/src/app/layouts/accordion/accordion-nested-scenario/accordion-nested-scenario.component.scss new file mode 100644 index 0000000000..7f946ce906 --- /dev/null +++ b/src/app/layouts/accordion/accordion-nested-scenario/accordion-nested-scenario.component.scss @@ -0,0 +1,24 @@ +.accordion-sample { + width: 100%; + height: 100%; + overflow-y: auto; +} + +.accordion-content { + width: min(760px, 100%); + margin: 0 auto; + padding: 24px; + box-sizing: border-box; +} + +.accordion-toolbar { + display: flex; + justify-content: flex-end; + margin-bottom: 12px; +} + +igx-accordion { + display: block; + border: 1px solid var(--ig-gray-300); + border-radius: 4px; +} diff --git a/src/app/layouts/accordion/accordion-nested-scenario/accordion-nested-scenario.component.ts b/src/app/layouts/accordion/accordion-nested-scenario/accordion-nested-scenario.component.ts new file mode 100644 index 0000000000..38cd02d135 --- /dev/null +++ b/src/app/layouts/accordion/accordion-nested-scenario/accordion-nested-scenario.component.ts @@ -0,0 +1,16 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { IgxAccordionComponent } from 'igniteui-angular/accordion'; +import { IgxExpansionPanelBodyComponent, IgxExpansionPanelComponent, IgxExpansionPanelDescriptionDirective, IgxExpansionPanelHeaderComponent, IgxExpansionPanelTitleDirective } from 'igniteui-angular/expansion-panel'; +import { IgxSwitchComponent } from 'igniteui-angular/switch'; + +@Component({ + selector: 'app-accordion-nested-scenario', + styleUrls: ['./accordion-nested-scenario.component.scss'], + templateUrl: './accordion-nested-scenario.component.html', + changeDetection: ChangeDetectionStrategy.Eager, + imports: [FormsModule, IgxSwitchComponent, IgxAccordionComponent, IgxExpansionPanelComponent, IgxExpansionPanelHeaderComponent, IgxExpansionPanelTitleDirective, IgxExpansionPanelDescriptionDirective, IgxExpansionPanelBodyComponent] +}) +export class AccordionNestedScenarioComponent { + public singleBranchExpand = false; +} diff --git a/src/app/layouts/accordion/accordion-overview/accordion-overview.component.html b/src/app/layouts/accordion/accordion-overview/accordion-overview.component.html new file mode 100644 index 0000000000..953f53c2f4 --- /dev/null +++ b/src/app/layouts/accordion/accordion-overview/accordion-overview.component.html @@ -0,0 +1,37 @@ +
+
+
+ Single Expand +
+ + + + + Account + Profile and security settings + + +

Update your profile details, password, and sign-in preferences.

+
+
+ + + Notifications + Email and product updates + + +

Choose which notifications you receive and how often they are delivered.

+
+
+ + + Billing + Payment and invoice settings + + +

Manage payment methods, billing contacts, and invoice delivery options.

+
+
+
+
+
diff --git a/src/app/layouts/accordion/accordion-overview/accordion-overview.component.scss b/src/app/layouts/accordion/accordion-overview/accordion-overview.component.scss new file mode 100644 index 0000000000..868bd0c158 --- /dev/null +++ b/src/app/layouts/accordion/accordion-overview/accordion-overview.component.scss @@ -0,0 +1,24 @@ +.accordion-sample { + width: 100%; + height: 100%; + overflow-y: auto; +} + +.accordion-content { + width: min(720px, 100%); + margin: 0 auto; + padding: 24px; + box-sizing: border-box; +} + +.accordion-toolbar { + display: flex; + justify-content: flex-end; + margin-bottom: 12px; +} + +igx-accordion { + display: block; + border: 1px solid var(--ig-gray-300); + border-radius: 4px; +} diff --git a/src/app/layouts/accordion/accordion-overview/accordion-overview.component.ts b/src/app/layouts/accordion/accordion-overview/accordion-overview.component.ts new file mode 100644 index 0000000000..440f9fd557 --- /dev/null +++ b/src/app/layouts/accordion/accordion-overview/accordion-overview.component.ts @@ -0,0 +1,16 @@ +import { Component, ChangeDetectionStrategy } from '@angular/core'; +import { IgxSwitchComponent } from 'igniteui-angular/switch'; +import { IgxAccordionComponent } from 'igniteui-angular/accordion'; +import { IgxExpansionPanelBodyComponent, IgxExpansionPanelComponent, IgxExpansionPanelDescriptionDirective, IgxExpansionPanelHeaderComponent, IgxExpansionPanelTitleDirective } from 'igniteui-angular/expansion-panel'; +import { FormsModule } from '@angular/forms'; + +@Component({ + selector: 'app-accordion-overview', + styleUrls: ['./accordion-overview.component.scss'], + templateUrl: './accordion-overview.component.html', + changeDetection: ChangeDetectionStrategy.Eager, + imports: [IgxSwitchComponent, FormsModule, IgxAccordionComponent, IgxExpansionPanelComponent, IgxExpansionPanelHeaderComponent, IgxExpansionPanelTitleDirective, IgxExpansionPanelDescriptionDirective, IgxExpansionPanelBodyComponent] +}) +export class AccordionOverviewComponent { + public singleBranchExpand = false; +} diff --git a/src/app/layouts/accordion/accordion-programmatic-expansion/accordion-programmatic-expansion.component.html b/src/app/layouts/accordion/accordion-programmatic-expansion/accordion-programmatic-expansion.component.html new file mode 100644 index 0000000000..3e16857cc5 --- /dev/null +++ b/src/app/layouts/accordion/accordion-programmatic-expansion/accordion-programmatic-expansion.component.html @@ -0,0 +1,40 @@ +
+
+
+ + +
+ + + + + Billing + Invoices and payment settings + + +

Review invoices, update payment methods, and manage billing contacts.

+
+
+ + + + Security + Password and access controls + + +

Configure password rules, multi-factor authentication, and recovery options.

+
+
+ + + + Notifications + Product updates and account alerts + + +

Choose which product updates and account alerts are sent to your team.

+
+
+
+
+
diff --git a/src/app/layouts/accordion/accordion-programmatic-expansion/accordion-programmatic-expansion.component.scss b/src/app/layouts/accordion/accordion-programmatic-expansion/accordion-programmatic-expansion.component.scss new file mode 100644 index 0000000000..11f32c5cb5 --- /dev/null +++ b/src/app/layouts/accordion/accordion-programmatic-expansion/accordion-programmatic-expansion.component.scss @@ -0,0 +1,29 @@ +.accordion-sample { + width: 100%; + height: 100%; + overflow-y: auto; +} + +.accordion-content { + width: min(720px, 100%); + margin: 0 auto; + padding: 24px; + box-sizing: border-box; +} + +.accordion-toolbar { + display: flex; + justify-content: flex-end; + gap: 8px; + margin-bottom: 12px; +} + +.action-button { + min-width: 96px; +} + +igx-accordion { + display: block; + border: 1px solid var(--ig-gray-300); + border-radius: 4px; +} diff --git a/src/app/layouts/accordion/accordion-programmatic-expansion/accordion-programmatic-expansion.component.ts b/src/app/layouts/accordion/accordion-programmatic-expansion/accordion-programmatic-expansion.component.ts new file mode 100644 index 0000000000..2c3ea01263 --- /dev/null +++ b/src/app/layouts/accordion/accordion-programmatic-expansion/accordion-programmatic-expansion.component.ts @@ -0,0 +1,14 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { IgxAccordionComponent } from 'igniteui-angular/accordion'; +import { IgxButtonDirective, IgxRippleDirective } from 'igniteui-angular/directives'; +import { IgxExpansionPanelBodyComponent, IgxExpansionPanelComponent, IgxExpansionPanelDescriptionDirective, IgxExpansionPanelHeaderComponent, IgxExpansionPanelTitleDirective } from 'igniteui-angular/expansion-panel'; + +@Component({ + selector: 'app-accordion-programmatic-expansion', + styleUrls: ['./accordion-programmatic-expansion.component.scss'], + templateUrl: './accordion-programmatic-expansion.component.html', + changeDetection: ChangeDetectionStrategy.Eager, + imports: [IgxButtonDirective, IgxRippleDirective, IgxAccordionComponent, IgxExpansionPanelComponent, IgxExpansionPanelHeaderComponent, IgxExpansionPanelTitleDirective, IgxExpansionPanelDescriptionDirective, IgxExpansionPanelBodyComponent] +}) +export class AccordionProgrammaticExpansionComponent { +} diff --git a/src/app/layouts/accordion/accordion-styling/accordion-styling.component.html b/src/app/layouts/accordion/accordion-styling/accordion-styling.component.html new file mode 100644 index 0000000000..62a0a50618 --- /dev/null +++ b/src/app/layouts/accordion/accordion-styling/accordion-styling.component.html @@ -0,0 +1,35 @@ +
+
+ + + + Getting Started + Setup and onboarding + + +

Find installation steps, project setup guidance, and resources for building your first application.

+
+
+ + + + Billing + Invoices and payment methods + + +

Review invoices, update payment methods, and manage billing contacts for your account.

+
+
+ + + + Security + Access and authentication + + +

Configure password rules, multi-factor authentication, and recovery options for your team.

+
+
+
+
+
diff --git a/src/app/layouts/accordion/accordion-styling/accordion-styling.component.scss b/src/app/layouts/accordion/accordion-styling/accordion-styling.component.scss new file mode 100644 index 0000000000..205bf6afb1 --- /dev/null +++ b/src/app/layouts/accordion/accordion-styling/accordion-styling.component.scss @@ -0,0 +1,50 @@ +@use "igniteui-angular/theming" as *; + +.accordion-sample { + width: 100%; + height: 100%; + overflow-y: auto; +} + +.accordion-content { + width: min(720px, 100%); + margin: 0 auto; + padding: 24px; + box-sizing: border-box; +} + +igx-accordion { + display: block; + border: 1px solid var(--ig-gray-300); + border-radius: 4px; +} + +$custom-panel-theme: expansion-panel-theme( + $header-background: var(--ig-gray-100), + $header-focus-background: var(--ig-primary-50), + $body-background: var(--ig-gray-50), + $body-color: var(--ig-gray-700), + $header-title-color: var(--ig-gray-900), + $header-description-color: var(--ig-gray-900), + $header-icon-color: var(--ig-primary-500), + $border-radius: 4px +); + +:host { + @include tokens($custom-panel-theme); +} + +::ng-deep { + .igx-expansion-panel--expanded .igx-expansion-panel__header-inner { + background-color: var(--ig-primary-50); + } + + .igx-expansion-panel--expanded .igx-expansion-panel__header-title, + .igx-expansion-panel--expanded .igx-expansion-panel__header-description { + color: var(--ig-primary-700); + } + + .igx-expansion-panel__header-title { + font-weight: 600; + } +} diff --git a/src/app/layouts/accordion/accordion-styling/accordion-styling.component.ts b/src/app/layouts/accordion/accordion-styling/accordion-styling.component.ts new file mode 100644 index 0000000000..e5958cb697 --- /dev/null +++ b/src/app/layouts/accordion/accordion-styling/accordion-styling.component.ts @@ -0,0 +1,12 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { IgxAccordionComponent } from 'igniteui-angular/accordion'; +import { IgxExpansionPanelBodyComponent, IgxExpansionPanelComponent, IgxExpansionPanelDescriptionDirective, IgxExpansionPanelHeaderComponent, IgxExpansionPanelTitleDirective } from 'igniteui-angular/expansion-panel'; + +@Component({ + selector: 'app-accordion-styling', + styleUrls: ['./accordion-styling.component.scss'], + templateUrl: './accordion-styling.component.html', + changeDetection: ChangeDetectionStrategy.Eager, + imports: [IgxAccordionComponent, IgxExpansionPanelComponent, IgxExpansionPanelHeaderComponent, IgxExpansionPanelTitleDirective, IgxExpansionPanelDescriptionDirective, IgxExpansionPanelBodyComponent] +}) +export class AccordionStylingComponent {} diff --git a/src/app/layouts/accordion/accordion-tailwind-styling/accordion-tailwind-styling.component.html b/src/app/layouts/accordion/accordion-tailwind-styling/accordion-tailwind-styling.component.html new file mode 100644 index 0000000000..655e1358eb --- /dev/null +++ b/src/app/layouts/accordion/accordion-tailwind-styling/accordion-tailwind-styling.component.html @@ -0,0 +1,35 @@ +
+
+ + + + Getting Started + Setup and onboarding + + +

Find installation steps, project setup guidance, and resources for building your first application.

+
+
+ + + + Billing + Invoices and payment methods + + +

Review invoices, update payment methods, and manage billing contacts for your account.

+
+
+ + + + Security + Access and authentication + + +

Configure password rules, multi-factor authentication, and recovery options for your team.

+
+
+
+
+
diff --git a/src/app/layouts/accordion/accordion-tailwind-styling/accordion-tailwind-styling.component.scss b/src/app/layouts/accordion/accordion-tailwind-styling/accordion-tailwind-styling.component.scss new file mode 100644 index 0000000000..70523e2fd8 --- /dev/null +++ b/src/app/layouts/accordion/accordion-tailwind-styling/accordion-tailwind-styling.component.scss @@ -0,0 +1,20 @@ +.accordion-tailwind-sample { + width: 100%; + height: 100%; + overflow-y: auto; +} + +::ng-deep { + .igx-expansion-panel--expanded .igx-expansion-panel__header-inner { + background-color: var(--ig-primary-50); + } + + .igx-expansion-panel--expanded .igx-expansion-panel__header-title, + .igx-expansion-panel--expanded .igx-expansion-panel__header-description { + color: var(--ig-primary-700); + } + + .igx-expansion-panel__header-title { + font-weight: 600; + } +} diff --git a/src/app/layouts/accordion/accordion-tailwind-styling/accordion-tailwind-styling.component.ts b/src/app/layouts/accordion/accordion-tailwind-styling/accordion-tailwind-styling.component.ts new file mode 100644 index 0000000000..0275ca542c --- /dev/null +++ b/src/app/layouts/accordion/accordion-tailwind-styling/accordion-tailwind-styling.component.ts @@ -0,0 +1,12 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { IgxAccordionComponent } from 'igniteui-angular/accordion'; +import { IgxExpansionPanelBodyComponent, IgxExpansionPanelComponent, IgxExpansionPanelDescriptionDirective, IgxExpansionPanelHeaderComponent, IgxExpansionPanelTitleDirective } from 'igniteui-angular/expansion-panel'; + +@Component({ + selector: 'app-accordion-tailwind-styling', + styleUrls: ['./accordion-tailwind-styling.component.scss'], + templateUrl: './accordion-tailwind-styling.component.html', + changeDetection: ChangeDetectionStrategy.Eager, + imports: [IgxAccordionComponent, IgxExpansionPanelComponent, IgxExpansionPanelHeaderComponent, IgxExpansionPanelTitleDirective, IgxExpansionPanelDescriptionDirective, IgxExpansionPanelBodyComponent] +}) +export class AccordionTailwindStylingComponent {} diff --git a/src/app/layouts/layouts-routes-data.ts b/src/app/layouts/layouts-routes-data.ts index 8890bf4c99..bd0097cd3e 100644 --- a/src/app/layouts/layouts-routes-data.ts +++ b/src/app/layouts/layouts-routes-data.ts @@ -1,9 +1,15 @@ /* eslint-disable quote-props */ export const layoutsRoutesData = { + 'accordion-customization': { displayName: 'Accordion Customization', parentName: 'Accordion' }, + 'accordion-nested-scenario': { displayName: 'Accordion Nested Scenario', parentName: 'Accordion' }, + 'accordion-overview': { displayName: 'Accordion Overview', parentName: 'Accordion' }, + 'accordion-styling': { displayName: 'Accordion Styling', parentName: 'Accordion' }, + 'accordion-tailwind-styling': { displayName: 'Accordion Tailwind Styling', parentName: 'Accordion' }, 'accordion-sample-1': { displayName: 'Accordion 1', parentName: 'Accordion' }, 'accordion-sample-2': { displayName: 'Accordion 2', parentName: 'Accordion' }, 'accordion-sample-3': { displayName: 'Accordion 3', parentName: 'Accordion' }, + 'accordion-programmatic-expansion': { displayName: 'Accordion Programmatic Expansion', parentName: 'Accordion' }, 'accordion-style': { displayName: 'Accordion Styling', parentName: 'Accordion' }, 'avatar-overview': { displayName: 'Avatar Overview', parentName: 'Avatar' }, 'avatar-variants': { displayName: 'Avatar Variants', parentName: 'Avatar' }, diff --git a/src/app/layouts/layouts.routes.ts b/src/app/layouts/layouts.routes.ts index 7385391ce8..6a21d5372d 100644 --- a/src/app/layouts/layouts.routes.ts +++ b/src/app/layouts/layouts.routes.ts @@ -77,8 +77,14 @@ import { View1Component } from './tabs/views/view1/view1.component'; import { View2Component } from './tabs/views/view2/view2.component'; import { View3Component } from './tabs/views/view3/view3.component'; import { AccordionSample1Component } from './accordion/accordion-sample-1/accordion-sample-1.component'; +import { AccordionCustomizationComponent } from './accordion/accordion-customization/accordion-customization.component'; +import { AccordionNestedScenarioComponent } from './accordion/accordion-nested-scenario/accordion-nested-scenario.component'; +import { AccordionOverviewComponent } from './accordion/accordion-overview/accordion-overview.component'; +import { AccordionStylingComponent } from './accordion/accordion-styling/accordion-styling.component'; +import { AccordionTailwindStylingComponent } from './accordion/accordion-tailwind-styling/accordion-tailwind-styling.component'; import { AccordionSample2Component } from './accordion/accordion-sample-2/accordion-sample-2.component'; import { AccordionSample3Component } from './accordion/accordion-sample-3/accordion-sample-3.component'; +import { AccordionProgrammaticExpansionComponent } from './accordion/accordion-programmatic-expansion/accordion-programmatic-expansion.component'; import { AccordionStyleComponent } from './accordion/accordion-style/accordion-style.component'; import {StepperLabelPositionAndOrientationSampleComponent } from './stepper/stepper-label-position-and-orientation-sample/stepper-label-position-and-orientation-sample.component'; @@ -91,6 +97,31 @@ import { StepperSampleReactiveFormsComponent } from './stepper/stepper-sample-re import { TileManagerComponent } from './tile-manager/tile-manager-sample/tile-manager.component'; export const LayoutsRoutes: Routes = [ + { + component: AccordionOverviewComponent, + data: layoutsRoutesData['accordion-overview'], + path: 'accordion-overview' + }, + { + component: AccordionCustomizationComponent, + data: layoutsRoutesData['accordion-customization'], + path: 'accordion-customization' + }, + { + component: AccordionNestedScenarioComponent, + data: layoutsRoutesData['accordion-nested-scenario'], + path: 'accordion-nested-scenario' + }, + { + component: AccordionStylingComponent, + data: layoutsRoutesData['accordion-styling'], + path: 'accordion-styling' + }, + { + component: AccordionTailwindStylingComponent, + data: layoutsRoutesData['accordion-tailwind-styling'], + path: 'accordion-tailwind-styling' + }, { component: AccordionSample1Component, data: layoutsRoutesData['accordion-sample-1'], @@ -106,6 +137,11 @@ export const LayoutsRoutes: Routes = [ data: layoutsRoutesData['accordion-sample-3'], path: 'accordion-sample-3' }, + { + component: AccordionProgrammaticExpansionComponent, + data: layoutsRoutesData['accordion-programmatic-expansion'], + path: 'accordion-programmatic-expansion' + }, { component: AccordionStyleComponent, data: layoutsRoutesData['accordion-style'],