From 4aee971d2ad479ad1ee89c1a4b25ad6d074a2a71 Mon Sep 17 00:00:00 2001 From: Simeon Simeonoff Date: Wed, 10 Jun 2020 11:26:45 +0300 Subject: [PATCH 01/53] feat(themes): add rudimentary support for the dock manager --- .../dock-manager/_dock-manager-theme.scss | 80 +++++++++++++++++++ .../src/lib/core/styles/themes/_index.scss | 5 ++ .../themes/schemas/dark/_dock-manager.scss | 54 +++++++++++++ .../styles/themes/schemas/dark/_index.scss | 7 ++ .../themes/schemas/light/_dock-manager.scss | 50 ++++++++++++ .../styles/themes/schemas/light/_index.scss | 5 ++ 6 files changed, 201 insertions(+) create mode 100644 projects/igniteui-angular/src/lib/core/styles/components/dock-manager/_dock-manager-theme.scss create mode 100644 projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_dock-manager.scss create mode 100644 projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss diff --git a/projects/igniteui-angular/src/lib/core/styles/components/dock-manager/_dock-manager-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/dock-manager/_dock-manager-theme.scss new file mode 100644 index 00000000000..63c29f4582a --- /dev/null +++ b/projects/igniteui-angular/src/lib/core/styles/components/dock-manager/_dock-manager-theme.scss @@ -0,0 +1,80 @@ +//// +/// @group themes +/// @access public +/// @author Simeon Simeonoff +/// @author Marin Popov +//// + +/// If only background color is specified, text/icon color will be assigned automatically to a contrasting color. +/// @param {Map} $palette [$default-palette] - The palette used as basis for styling the component. +/// @param {Map} $schema [$light-schema] - The schema used as basis for styling the component. +/// +/// @param {Color} primary-color [null] - +/// @param {Color} accent-color [null] - +/// @param {Color} text-color [null] - +/// @param {Color} border-color [null] - +/// @param {Color} button-text [null] - +/// @param {Color} splitter-background [null] - +/// @param {Color} flyout-shadow-color [null] - +/// @param {Color} joystick-icon-color-active [null] - +/// @param {Color} joystick-border-color [null] - +/// @param {Color} tab-background-active [null] - +/// @param {Color} pane-content-background [null] - +/// @param {Color} floating-pane-border-color [null] - +/// @param {Color} context-menu-color-active [null] - +/// @requires $default-palette +/// @requires $light-schema +/// @requires apply-palette +/// @requires text-contrast +/// @requires extend +/// +/// @example scss Change the background and icon colors in icon dock-managers +/// $my-dock-manager-theme: igc-dock-manager-theme(); +/// // Pass the theme to the igc-dock-manager component mixin +/// @include igx-css-vars($my-dock-manager-theme); +@function igc-dock-manager-theme( + $palette: $default-palette, + $schema: $light-schema, + + $primary-color: null, + $accent-color: null, + $text-color: null, + $border-color: null, + $button-text: null, + $splitter-background: null, + $flyout-shadow-color: null, + $joystick-icon-color-active: null, + $joystick-border-color: null, + $tab-background-active: null, + $pane-content-background: null, + $floating-pane-border-color: null, + $context-menu-color-active: null, +) { + $name: 'igc-dock-manager'; + $dock-manager-schema: (); + + @if map-has-key($schema, $name) { + $dock-manager-schema: map-get($schema, $name); + } @else { + $dock-manager-schema: $schema; + } + + $theme: apply-palette($dock-manager-schema, $palette); + + @return extend($theme, ( + name: $name, + primary-color: $primary-color, + accent-color: $accent-color, + text-color: $text-color, + border-color: $border-color, + button-text: $button-text, + splitter-background: $splitter-background, + flyout-shadow-color: $flyout-shadow-color, + joystick-icon-color-active: $joystick-icon-color-active, + joystick-border-color: $joystick-border-color, + tab-background-active: $tab-background-active, + pane-content-background: $pane-content-background, + floating-pane-border-color: $floating-pane-border-color, + context-menu-color-active: $context-menu-color-active, + )); +} diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/_index.scss b/projects/igniteui-angular/src/lib/core/styles/themes/_index.scss index 7c8bbe3ec33..968ae6d4b9d 100644 --- a/projects/igniteui-angular/src/lib/core/styles/themes/_index.scss +++ b/projects/igniteui-angular/src/lib/core/styles/themes/_index.scss @@ -25,6 +25,7 @@ @import '../components/date-range-picker/date-range-picker-theme'; @import '../components/dialog/dialog-theme'; @import '../components/divider/divider-theme'; +@import '../components/dock-manager/dock-manager-theme'; @import '../components/drop-down/drop-down-theme'; @import '../components/expansion-panel/expansion-panel-theme'; @import '../components/grid/grid-theme'; @@ -265,6 +266,10 @@ @include igx-divider(igx-divider-theme($palette, $schema)); } + @if not(index($exclude, 'igc-dock-manager')) { + @include igx-css-vars(igc-dock-manager-theme($palette, $schema)); + } + @if not(index($exclude, 'igx-drop-down')) { @include igx-drop-down(igx-drop-down-theme( $palette, diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_dock-manager.scss b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_dock-manager.scss new file mode 100644 index 00000000000..4b490a033ed --- /dev/null +++ b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_dock-manager.scss @@ -0,0 +1,54 @@ +@import '../light/dock-manager'; +//// +/// @group schemas +/// @access private +/// @author Simeon Simeonoff +//// + +/// Generates a dark dock-manager schema. +/// @type {Map} +/// @requires {function} extend +/// @prop {Color} primary-color [#111] - +/// @prop {Color} accent-color [#424242] - +/// @prop {Color} text-color [rgba(255, 255, 255, .7)] - +/// @prop {Color} border-color [#212121] - +/// @prop {Color} button-text [#fff] - +/// @prop {Color} splitter-background [#000] - +/// @prop {Color} flyout-shadow-color [rgba(0, 0, 0, .38)] - +/// @prop {Color} joystick-icon-color-active [#fff] - +/// @prop {Color} joystick-border-color [#424242] - +/// @prop {Color} tab-background-active [#212121] - +/// @prop {Color} pane-content-background [#212121] - +/// @prop {Color} floating-pane-border-color [rgba(0, 0, 0, .26)] - +/// @prop {Color} context-menu-color-active [#fff] - +/// @requires $_light-dock-manager +$_dark-dock-manager: extend( + $_light-dock-manager, ( + primary-color: #111, + accent-color: #424242, + text-color: rgba(255, 255, 255, .7), + border-color: #212121, + button-text: #fff, + splitter-background: #000, + flyout-shadow-color: rgba(0, 0, 0, .38), + joystick-icon-color-active: #fff, + joystick-border-color: #424242, + tab-background-active: #212121, + pane-content-background: #212121, + floating-pane-border-color: rgba(0, 0, 0, .26), + context-menu-color-active: #fff, + ) +); + +/// Generates a dark fluent dock-manager schema. +/// @type {Map} +/// @requires {function} extend +/// @requires $_fluent-dock-manager +$_dark-fluent-dock-manager: extend($_fluent-dock-manager); + +/// Generates a dark bootstrap dock-manager schema. +/// @type {Map} +/// @requires {function} extend +/// @requires $_bootstrap-dock-manager +$_dark-bootstrap-dock-manager: extend($_bootstrap-dock-manager); + diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_index.scss b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_index.scss index 55abd101b9b..70cdede8b33 100644 --- a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_index.scss +++ b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_index.scss @@ -20,6 +20,7 @@ @import './dialog'; @import './date-range-picker'; @import './divider'; +@import './dock-manager'; @import './drop-down'; @import './expansion-panel'; @import './grid'; @@ -66,6 +67,7 @@ /// @property {Map} igx-dialog [$_dark-dialog] /// @property {Map} igx-date-range-picker [$_dark-date-range-picker] /// @property {Map} igx-divider [$_dark-divider] +/// @property {Map} igc-dock-manager [$_dark-dock-manager] /// @property {Map} igx-drop-down [$_dark-drop-down] /// @property {Map} igx-expansion-panel [$_dark-expansion-panel] /// @property {Map} igx-grid [$_dark-grid] @@ -111,6 +113,7 @@ $dark-schema: ( igx-dialog: $_dark-dialog, igx-date-range: $_dark-date-range-picker, igx-divider: $_dark-divider, + igc-dock-manager: $_dark-dock-manager, igx-drop-down: $_dark-drop-down, igx-expansion-panel: $_dark-expansion-panel, igx-grid: $_dark-grid, @@ -159,6 +162,7 @@ $dark-schema: ( /// @property {map} igx-dialog [$_dark-fluent-dialog], /// @property {map} igx-date-range-picker [$_dark-fluent-date-range-picker], /// @property {map} igx-divider [$_dark-fluent-divider], +/// @property {map} igc-dock-manager [$_dark-fluent-dock-manager], /// @property {map} igx-drop-down [$_dark-fluent-drop-down], /// @property {map} igx-expansion-panel [$_dark-fluent-expansion-panel], /// @property {map} igx-grid [$_dark-fluent-grid], @@ -204,6 +208,7 @@ $dark-fluent-schema: ( igx-dialog: $_dark-fluent-dialog, igx-date-range: $_dark-fluent-date-range-picker, igx-divider: $_dark-fluent-divider, + igc-dock-manager: $_dark-fluent-dock-manager, igx-drop-down: $_dark-fluent-drop-down, igx-expansion-panel: $_dark-fluent-expansion-panel, igx-grid: $_dark-fluent-grid, @@ -252,6 +257,7 @@ $dark-fluent-schema: ( /// @property {map} igx-dialog [$_dark-bootstrap-dialog], /// @property {map} igx-date-range-picker [$_dark-bootstrap-date-range-picker], /// @property {map} igx-divider [$_dark-bootstrap-divider], +/// @property {map} igc-dock-manager [$_dark-bootstrap-dock-manager], /// @property {map} igx-drop-down [$_dark-bootstrap-drop-down], /// @property {map} igx-expansion-panel [$_dark-bootstrap-expansion-panel], /// @property {map} igx-grid [$_dark-bootstrap-grid], @@ -297,6 +303,7 @@ $dark-bootstrap-schema: ( igx-dialog: $_dark-bootstrap-dialog, igx-date-range: $_dark-bootstrap-date-range-picker, igx-divider: $_dark-bootstrap-divider, + igc-dock-manager: $_dark-bootstrap-dock-manager, igx-drop-down: $_dark-bootstrap-drop-down, igx-expansion-panel: $_dark-bootstrap-expansion-panel, igx-grid: $_dark-bootstrap-grid, diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss new file mode 100644 index 00000000000..358f98d0b68 --- /dev/null +++ b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss @@ -0,0 +1,50 @@ +//// +/// @group schemas +/// @access private +/// @author Simeon Simeonoff +//// + +/// Generates a light dock-manager schema. +/// @type {Map} +/// @prop {Color} primary-color [#E5E7E9] - +/// @prop {Color} accent-color [#fff] - +/// @prop {Color} text-color [rgba(0, 0, 0, .72)] - +/// @prop {Color} border-color [#F3F5F7] - +/// @prop {Color} button-text [rgba(0, 0, 0, .72)] - +/// @prop {Color} splitter-background [#D3D6D9] - +/// @prop {Color} flyout-shadow-color [rgba(0, 0, 0, .08)] - +/// @prop {Color} joystick-icon-color-active [#000] - +/// @prop {Color} joystick-border-color [#D3D6D9] - +/// @prop {Color} tab-background-active [#F3F5F7] - +/// @prop {Color} pane-content-background [#F3F5F7] - +/// @prop {Color} floating-pane-border-color [#fff] - +/// @prop {Color} context-menu-color-active [#000] - +$_light-dock-manager: ( + primary-color: #e5e7e9, + accent-color: #fff, + text-color: rgba(0, 0, 0, .72), + border-color: #f3f5f7, + button-text: rgba(0, 0, 0, .72), + splitter-background: #d3d6d9, + flyout-shadow-color: rgba(0, 0, 0, .08), + joystick-icon-color-active: #000, + joystick-border-color: #d3d6d9, + tab-background-active: #f3f5f7, + pane-content-background: #f3f5f7, + floating-pane-border-color: #fff, + context-menu-color-active: #000, +); + +/// Generates a fluent dock-manager schema. +/// @type {Map} +/// @requires {function} extend +/// @requires $_light-dock-manager +$_fluent-dock-manager: extend($_light-dock-manager); + +/// Generates a bootstrap dock-manager schema. +/// @type {Map} +/// @requires {function} extend +/// @requires $_light-dock-manager +/// @requires $_bootstrap-shape-dock-manager +$_bootstrap-dock-manager: extend($_light-dock-manager); + diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_index.scss b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_index.scss index 89dcd983175..bd3bfaea540 100644 --- a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_index.scss +++ b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_index.scss @@ -21,6 +21,7 @@ @import './dialog'; @import './date-range-picker'; @import './divider'; +@import './dock-manager'; @import './drop-down'; @import './expansion-panel'; @import './grid'; @@ -68,6 +69,7 @@ /// @property {Map} igx-dialog [$_light-dialog] /// @property {Map} igx-date-range-picker [$_light-date-range-picker ] /// @property {Map} igx-divider [$_light-divider] +/// @property {Map} igc-dock-manager [$_light-dock-manager] /// @property {Map} igx-drop-down [$_light-drop-down] /// @property {Map} igx-expansion-panel [$_light-expansion-panel] /// @property {Map} igx-grid [$_light-grid] @@ -113,6 +115,7 @@ $light-schema: ( igx-dialog: $_light-dialog, igx-date-range: $_light-date-range-picker, igx-divider: $_light-divider, + igc-dock-manager: $_light-dock-manager, igx-drop-down: $_light-drop-down, igx-expansion-panel: $_light-expansion-panel, igx-grid: $_light-grid, @@ -161,6 +164,7 @@ $light-fluent-schema: ( igx-dialog: $_fluent-dialog, igx-date-range: $_fluent-date-range-picker, igx-divider: $_fluent-divider, + igc-dock-manager: $_fluent-dock-manager, igx-drop-down: $_fluent-drop-down, igx-expansion-panel: $_fluent-expansion-panel, igx-grid: $_fluent-grid, @@ -209,6 +213,7 @@ $light-bootstrap-schema: ( igx-dialog: $_bootstrap-dialog, igx-date-range: $_bootstrap-date-range-picker, igx-divider: $_bootstrap-divider, + igc-dock-manager: $_bootstrap-dock-manager, igx-drop-down: $_bootstrap-drop-down, igx-expansion-panel: $_bootstrap-expansion-panel, igx-grid: $_bootstrap-grid, From 9dce31c28f15b33045264c105e4852e82e23d736 Mon Sep 17 00:00:00 2001 From: Simeon Simeonoff Date: Wed, 10 Jun 2020 11:30:25 +0300 Subject: [PATCH 02/53] refactor(theme): change the css var prefix --- .../styles/components/dock-manager/_dock-manager-theme.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/igniteui-angular/src/lib/core/styles/components/dock-manager/_dock-manager-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/dock-manager/_dock-manager-theme.scss index 63c29f4582a..7d4fade4a28 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/dock-manager/_dock-manager-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/dock-manager/_dock-manager-theme.scss @@ -62,7 +62,7 @@ $theme: apply-palette($dock-manager-schema, $palette); @return extend($theme, ( - name: $name, + name: 'igc', primary-color: $primary-color, accent-color: $accent-color, text-color: $text-color, From b7f3a780fb70879ab7a18523b1e8ffebd73bc28b Mon Sep 17 00:00:00 2001 From: Simeon Simeonoff Date: Wed, 10 Jun 2020 16:03:02 +0300 Subject: [PATCH 03/53] refactor(themes): add sassdoc descriptions and all props for the dockmgr --- .../dock-manager/_dock-manager-theme.scss | 77 ++++++++---------- .../themes/schemas/dark/_dock-manager.scss | 40 +++++----- .../themes/schemas/light/_dock-manager.scss | 78 ++++++++++++++----- 3 files changed, 112 insertions(+), 83 deletions(-) diff --git a/projects/igniteui-angular/src/lib/core/styles/components/dock-manager/_dock-manager-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/dock-manager/_dock-manager-theme.scss index 7d4fade4a28..d1c2d21e0d3 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/dock-manager/_dock-manager-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/dock-manager/_dock-manager-theme.scss @@ -9,19 +9,38 @@ /// @param {Map} $palette [$default-palette] - The palette used as basis for styling the component. /// @param {Map} $schema [$light-schema] - The schema used as basis for styling the component. /// -/// @param {Color} primary-color [null] - -/// @param {Color} accent-color [null] - -/// @param {Color} text-color [null] - -/// @param {Color} border-color [null] - -/// @param {Color} button-text [null] - -/// @param {Color} splitter-background [null] - -/// @param {Color} flyout-shadow-color [null] - -/// @param {Color} joystick-icon-color-active [null] - -/// @param {Color} joystick-border-color [null] - -/// @param {Color} tab-background-active [null] - -/// @param {Color} pane-content-background [null] - -/// @param {Color} floating-pane-border-color [null] - -/// @param {Color} context-menu-color-active [null] - +/// @param {Color} $accent-color [null] - Sets the pinned header background color, the joystick background and border colors, as well as the context menu background color. +/// @param {Color} $border-color [null] - Sets the global border color in the dock manager. Also sets the pane content background and the context menu active background colors. +/// @param {Color} $button-text [null] - Sets the button text color. +/// @param {Color} $context-menu-background [null] - Sets the background color for context menus. +/// @param {Color} $context-menu-background-active [null] - Sets the background color for active context menus. +/// @param {Color} $context-menu-color [null] - Sets the text color for context menus. +/// @param {Color} $context-menu-color-active [null] - Sets the text color for active context menus. +/// @param {Color} $dock-background [null] - Sets the background color of the dock manager. +/// @param {Color} $dock-text [null] - Sets the text color of the dock manager. +/// @param {Color} $floating-pane-border-color [null] - Sets the border color for floating panes. +/// @param {Color} $flyout-shadow-color [null] - Sets the flyout shadow color. +/// @param {Color} $joystick-background [null] - Sets the background color of the joystick. +/// @param {Color} $joystick-background-active [null] - Sets the background color of the joysticks. +/// @param {Color} $joystick-border-color [null] - Sets the border color of the joystick. +/// @param {Color} $joystick-icon-color [null] - Sets the color for the joystick icons. +/// @param {Color} $joystick-icon-color-active [null] - Sets the color of the active joystick icons. +/// @param {Color} $pane-content-background [null] - Sets the background color of the content panes. +/// @param {Color} $pane-content-text [null] - Sets the text color of the content panes. +/// @param {Color} $pane-header-background [null] - Sets the background color for pane headers. +/// @param {Color} $pane-header-text [null] - Sets the text color for pane headers. +/// @param {Color} $pinned-header-background [null] - Sets the background colors of pinned headers. +/// @param {Color} $pinned-header-text [null] - Sets the text colors of pinned headers. +/// @param {Color} $primary-color [null] - Sets the base dock manager color as well as the pane headers and tabs background colors. +/// @param {Color} $splitter-background [null] - Sets the background color for the splitters. +/// @param {Color} $splitter-handle [null] - Sets the background color for the splitter handles. +/// @param {Color} $tab-background [null] - Sets the background color for tabs. +/// @param {Color} $tab-background-active [null] - Sets the background color for active tabs. +/// @param {Color} $tab-border-color [null] - Sets the border color for tabs. +/// @param {Color} $tab-border-color-active [null] - Sets the border color for active tabs. +/// @param {Color} $tab-text [null] - Sets the text color for tabs. +/// @param {Color} $tab-text-active [null] - Sets the text color for active tabs. +/// @param {Color} $text-color [null] - Sets the text color for most elements in the dock manager. Used as the default joystick icon color. /// @requires $default-palette /// @requires $light-schema /// @requires apply-palette @@ -35,20 +54,7 @@ @function igc-dock-manager-theme( $palette: $default-palette, $schema: $light-schema, - - $primary-color: null, - $accent-color: null, - $text-color: null, - $border-color: null, - $button-text: null, - $splitter-background: null, - $flyout-shadow-color: null, - $joystick-icon-color-active: null, - $joystick-border-color: null, - $tab-background-active: null, - $pane-content-background: null, - $floating-pane-border-color: null, - $context-menu-color-active: null, + $rest... ) { $name: 'igc-dock-manager'; $dock-manager-schema: (); @@ -61,20 +67,5 @@ $theme: apply-palette($dock-manager-schema, $palette); - @return extend($theme, ( - name: 'igc', - primary-color: $primary-color, - accent-color: $accent-color, - text-color: $text-color, - border-color: $border-color, - button-text: $button-text, - splitter-background: $splitter-background, - flyout-shadow-color: $flyout-shadow-color, - joystick-icon-color-active: $joystick-icon-color-active, - joystick-border-color: $joystick-border-color, - tab-background-active: $tab-background-active, - pane-content-background: $pane-content-background, - floating-pane-border-color: $floating-pane-border-color, - context-menu-color-active: $context-menu-color-active, - )); + @return extend($theme, (name: 'igc'), keywords($rest)); } diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_dock-manager.scss b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_dock-manager.scss index 4b490a033ed..319a80a0378 100644 --- a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_dock-manager.scss +++ b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_dock-manager.scss @@ -8,35 +8,35 @@ /// Generates a dark dock-manager schema. /// @type {Map} /// @requires {function} extend -/// @prop {Color} primary-color [#111] - -/// @prop {Color} accent-color [#424242] - -/// @prop {Color} text-color [rgba(255, 255, 255, .7)] - -/// @prop {Color} border-color [#212121] - -/// @prop {Color} button-text [#fff] - -/// @prop {Color} splitter-background [#000] - -/// @prop {Color} flyout-shadow-color [rgba(0, 0, 0, .38)] - -/// @prop {Color} joystick-icon-color-active [#fff] - -/// @prop {Color} joystick-border-color [#424242] - -/// @prop {Color} tab-background-active [#212121] - -/// @prop {Color} pane-content-background [#212121] - -/// @prop {Color} floating-pane-border-color [rgba(0, 0, 0, .26)] - -/// @prop {Color} context-menu-color-active [#fff] - +/// @prop {Color} accent-color [#424242] - Sets the pinned header background color, the joystick background and border colors, as well as the context menu background color. +/// @prop {Color} border-color [#212121] - Sets the global border color in the dock manager. Also sets the pane content background and the context menu active background colors. +/// @prop {Color} button-text [#fff] - Sets the button text color. +/// @prop {Color} context-menu-color-active [#fff] - Sets the text color for active context menus. +/// @prop {Color} floating-pane-border-color [rgba(0, 0, 0, .26)] - Sets the border color for floating panes. +/// @prop {Color} flyout-shadow-color [rgba(0, 0, 0, .38)] - Sets the border color for floating panes. +/// @prop {Color} joystick-border-color [#424242] - Sets the border color of the joystick. +/// @prop {Color} joystick-icon-color-active [#fff] - Sets the color of the active joystick icons. +/// @prop {Color} pane-content-background [#212121] - Sets the background color of the content panes. +/// @prop {Color} primary-color [#111] - Sets the base dock manager color as well as the pane headers and tabs background colors. +/// @prop {Color} splitter-background [#000] - Sets the background color for the splitters. +/// @prop {Color} tab-background-active [#212121] - Sets the background color for active tabs. +/// @prop {Color} text-color [rgba(255, 255, 255, .7)] - Sets the text color for most elements in the dock manager. Used as the default joystick icon color. /// @requires $_light-dock-manager $_dark-dock-manager: extend( $_light-dock-manager, ( - primary-color: #111, accent-color: #424242, - text-color: rgba(255, 255, 255, .7), border-color: #212121, button-text: #fff, - splitter-background: #000, + context-menu-color-active: #fff, + floating-pane-border-color: rgba(0, 0, 0, .26), flyout-shadow-color: rgba(0, 0, 0, .38), - joystick-icon-color-active: #fff, joystick-border-color: #424242, - tab-background-active: #212121, + joystick-icon-color-active: #fff, pane-content-background: #212121, - floating-pane-border-color: rgba(0, 0, 0, .26), - context-menu-color-active: #fff, + primary-color: #111, + splitter-background: #000, + tab-background-active: #212121, + text-color: rgba(255, 255, 255, .7), ) ); diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss index 358f98d0b68..cf38c5e88aa 100644 --- a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss +++ b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss @@ -6,33 +6,71 @@ /// Generates a light dock-manager schema. /// @type {Map} -/// @prop {Color} primary-color [#E5E7E9] - -/// @prop {Color} accent-color [#fff] - -/// @prop {Color} text-color [rgba(0, 0, 0, .72)] - -/// @prop {Color} border-color [#F3F5F7] - -/// @prop {Color} button-text [rgba(0, 0, 0, .72)] - -/// @prop {Color} splitter-background [#D3D6D9] - -/// @prop {Color} flyout-shadow-color [rgba(0, 0, 0, .08)] - -/// @prop {Color} joystick-icon-color-active [#000] - -/// @prop {Color} joystick-border-color [#D3D6D9] - -/// @prop {Color} tab-background-active [#F3F5F7] - -/// @prop {Color} pane-content-background [#F3F5F7] - -/// @prop {Color} floating-pane-border-color [#fff] - -/// @prop {Color} context-menu-color-active [#000] - +/// @prop {Color} accent-color [#fff] - Sets the pinned header background color, the joystick background and border colors, as well as the context menu background color. +/// @prop {Color} border-color [#F3F5F7] - Sets the global border color in the dock manager. Also sets the pane content background and the context menu active background colors. +/// @prop {Color} button-text [rgba(0, 0, 0, .72)] - Sets the button text color. +/// @prop {Color} context-menu-background [null] - Sets the background color for context menus. +/// @prop {Color} context-menu-background-active [null] - Sets the background color for active context menus. +/// @prop {Color} context-menu-color [null] - Sets the text color for context menus. +/// @prop {Color} context-menu-color-active [#000] - Sets the text color for active context menus. +/// @prop {Color} dock-background [null] - Sets the background color of the dock manager. +/// @prop {Color} dock-text [null] - Sets the text color of the dock manager. +/// @prop {Color} floating-pane-border-color [#fff] - Sets the border color for floating panes. +/// @prop {Color} flyout-shadow-color [rgba(0, 0, 0, .08)] - Sets the flyout shadow color. +/// @prop {Color} joystick-background [null] - Sets the background color of the joystick. +/// @prop {Color} joystick-background-active [null] - Sets the background color of the joysticks. +/// @prop {Color} joystick-border-color [#D3D6D9] - Sets the border color of the joystick. +/// @prop {Color} joystick-icon-color [#D3D6D9] - Sets the color for the joystick icons. +/// @prop {Color} joystick-icon-color-active [#000] - Sets the color of the active joystick icons. +/// @prop {Color} pane-content-background [#F3F5F7] - Sets the background color of the content panes. +/// @prop {Color} pane-content-text [null] - Sets the text color of the content panes. +/// @prop {Color} pane-header-background [null] - Sets the background color for pane headers. +/// @prop {Color} pane-header-text [null] - Sets the text color for pane headers. +/// @prop {Color} pinned-header-background [null] - Sets the background colors of pinned headers. +/// @prop {Color} pinned-header-text [null] - Sets the text colors of pinned headers. +/// @prop {Color} primary-color [#E5E7E9] - Sets the base dock manager color as well as the pane headers and tabs background colors. +/// @prop {Color} splitter-background [#d3d6d9] - Sets the background color for the splitters. +/// @prop {Color} splitter-handle [null] - Sets the background color for the splitter handles. +/// @prop {Color} tab-background [null] - Sets the background color for tabs. +/// @prop {Color} tab-background-active [#F3F5F7] - Sets the background color for active tabs. +/// @prop {Color} tab-border-color [null] - Sets the border color for tabs. +/// @prop {Color} tab-border-color-active [null] - Sets the border color for active tabs. +/// @prop {Color} tab-text [null] - Sets the text color for tabs. +/// @prop {Color} tab-text-active [null] - Sets the text color for active tabs. +/// @prop {Color} text-color [rgba(0, 0, 0, .72)] - Sets the text color for most elements in the dock manager. Used as the default joystick icon color. $_light-dock-manager: ( - primary-color: #e5e7e9, accent-color: #fff, - text-color: rgba(0, 0, 0, .72), border-color: #f3f5f7, button-text: rgba(0, 0, 0, .72), - splitter-background: #d3d6d9, + context-menu-background-active: null, + context-menu-background: null, + context-menu-color-active: #000, + context-menu-color: null, + dock-background: null, + dock-text: null, + floating-pane-border-color: #fff, flyout-shadow-color: rgba(0, 0, 0, .08), - joystick-icon-color-active: #000, + joystick-background-active: null, + joystick-background: null, joystick-border-color: #d3d6d9, - tab-background-active: #f3f5f7, + joystick-icon-color: #d3d6d9, + joystick-icon-color-active: #000, pane-content-background: #f3f5f7, - floating-pane-border-color: #fff, - context-menu-color-active: #000, + pane-content-text: null, + pane-header-background: null, + pane-header-text: null, + pinned-header-background: null, + pinned-header-text: null, + primary-color: #e5e7e9, + splitter-background: #d3d6d9, + splitter-handle: null, + tab-background-active: #f3f5f7, + tab-background: null, + tab-border-color-active: null, + tab-border-color: null, + tab-text-active: null, + tab-text: null, + text-color: rgba(0, 0, 0, .72), ); /// Generates a fluent dock-manager schema. From f20b8978b87561681ea82609f25ad82d6056d294 Mon Sep 17 00:00:00 2001 From: Simeon Simeonoff Date: Fri, 12 Jun 2020 13:20:49 +0300 Subject: [PATCH 04/53] refactor(dock-manager): add typography mixin --- .../dock-manager/_dock-manager-theme.scss | 14 ++++++ .../core/styles/typography/_typography.scss | 44 ++++++++++--------- 2 files changed, 37 insertions(+), 21 deletions(-) diff --git a/projects/igniteui-angular/src/lib/core/styles/components/dock-manager/_dock-manager-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/dock-manager/_dock-manager-theme.scss index d1c2d21e0d3..e8d50ac4a1a 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/dock-manager/_dock-manager-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/dock-manager/_dock-manager-theme.scss @@ -69,3 +69,17 @@ @return extend($theme, (name: 'igc'), keywords($rest)); } + + +/// Adds typography styles for the dock manager component. +/// @access private +/// @group typography +/// @requires {mixin} igx-type-style +@mixin igx-dock-manager-typography() { + $scope: if(is-root(), ':root', '&'); + + #{$scope} { + @include css-vars-from-theme((font-family: inherit), 'igc'); + } +} + diff --git a/projects/igniteui-angular/src/lib/core/styles/typography/_typography.scss b/projects/igniteui-angular/src/lib/core/styles/typography/_typography.scss index 55ed8b182e1..2e3b59eb376 100644 --- a/projects/igniteui-angular/src/lib/core/styles/typography/_typography.scss +++ b/projects/igniteui-angular/src/lib/core/styles/typography/_typography.scss @@ -10,32 +10,33 @@ @import '../components/button/button-theme'; @import '../components/calendar/calendar-theme'; @import '../components/card/card-theme'; +@import '../components/charts/data-chart-theme'; +@import '../components/charts/financial-chart-theme'; +@import '../components/charts/funnel-chart-theme'; +@import '../components/charts/gauge-theme'; +@import '../components/charts/graph-theme'; +@import '../components/charts/shape-chart-theme'; @import '../components/checkbox/checkbox-theme'; @import '../components/chip/chip-theme'; @import '../components/column-hiding/column-hiding-theme'; +@import '../components/date-range-picker/date-range-picker-theme'; @import '../components/dialog/dialog-theme'; +@import '../components/dock-manager/dock-manager-theme'; @import '../components/drop-down/drop-down-theme'; -@import '../components/date-range-picker/date-range-picker-theme'; @import '../components/expansion-panel/expansion-panel-theme'; @import '../components/grid/excel-filtering-theme'; @import '../components/input/input-group-theme'; +@import '../components/list/list-theme'; @import '../components/navbar/navbar-theme'; @import '../components/navdrawer/navdrawer-theme'; -@import '../components/list/list-theme'; @import '../components/radio/radio-theme'; -@import '../components/snackbar/snackbar-theme'; @import '../components/slider/slider-theme'; +@import '../components/snackbar/snackbar-theme'; @import '../components/switch/switch-theme'; @import '../components/tabs/tabs-theme'; @import '../components/time-picker/time-picker-theme'; @import '../components/toast/toast-theme'; @import '../components/tooltip/tooltip-theme'; -@import '../components/charts/data-chart-theme'; -@import '../components/charts/financial-chart-theme'; -@import '../components/charts/graph-theme'; -@import '../components/charts/shape-chart-theme'; -@import '../components/charts/funnel-chart-theme'; -@import '../components/charts/gauge-theme'; /// Adds typography styles for h1-h6, paragraph and creates /// custom typography class selectors. The produces styles @@ -101,36 +102,37 @@ } // Call the individual component styles with the type scale - @include igx-button-typography($type-scale); - @include igx-bottom-nav-typography($type-scale); + @include _excel-filtering-typography($type-scale); @include igx-banner-typography($type-scale); + @include igx-bottom-nav-typography($type-scale); + @include igx-button-typography($type-scale); @include igx-calendar-typography($type-scale); @include igx-card-typography($type-scale); @include igx-checkbox-typography($type-scale); @include igx-chip-typography($type-scale); @include igx-column-hiding-typography($type-scale); + @include igx-data-chart-typography($type-scale); + @include igx-date-range-typography($type-scale); @include igx-dialog-typography($type-scale); + @include igx-dock-manager-typography(); @include igx-drop-down-typography($type-scale); - @include igx-date-range-typography($type-scale); @include igx-expansion-panel-typography($type-scale); - @include _excel-filtering-typography($type-scale); + @include igx-financial-chart-typography($type-scale); + @include igx-funnel-chart-typography($type-scale); + @include igx-gauge-typography(); + @include igx-graph-typography(); @include igx-input-group-typography($type-scale); + @include igx-list-typography($type-scale); @include igx-navbar-typography($type-scale); @include igx-navdrawer-typography($type-scale); - @include igx-list-typography($type-scale); @include igx-radio-typography($type-scale); + @include igx-shape-chart-typography($type-scale); + @include igx-slider-typography($type-scale); @include igx-snackbar-typography($type-scale); @include igx-switch-typography($type-scale); - @include igx-slider-typography($type-scale); @include igx-tabs-typography($type-scale); @include igx-time-picker-typography($type-scale); @include igx-toast-typography($type-scale); @include igx-tooltip-typography($type-scale); - @include igx-data-chart-typography($type-scale); - @include igx-financial-chart-typography($type-scale); - @include igx-graph-typography(); - @include igx-shape-chart-typography($type-scale); - @include igx-funnel-chart-typography($type-scale); - @include igx-gauge-typography(); } } From dc4f0c8f6033a5db2237ccac58c5e656f040adaa Mon Sep 17 00:00:00 2001 From: Simeon Simeonoff Date: Fri, 12 Jun 2020 17:50:13 +0300 Subject: [PATCH 05/53] fix(category-chart): fix typography style references --- .../core/styles/components/charts/_category-chart-theme.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/projects/igniteui-angular/src/lib/core/styles/components/charts/_category-chart-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/charts/_category-chart-theme.scss index e49234b6ac5..e9d0ec2bd95 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/charts/_category-chart-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/charts/_category-chart-theme.scss @@ -282,8 +282,8 @@ $title-styles: igx-type-scale-category($type-scale, $title); $subtitle-styles: igx-type-scale-category($type-scale, $subtitle); - $x-axis-label-styles: igx-type-scale-category($type-scale, $x-axis-label); - $x-axis-title-styles: igx-type-scale-category($type-scale, $x-axis-title); + $x-axis-label-styles: igx-type-scale-category($type-scale, $x-axis-label-text-style); + $x-axis-title-styles: igx-type-scale-category($type-scale, $x-axis-title-text-style); $y-axis-label-styles: igx-type-scale-category($type-scale, $y-axis-label-text-style); $y-axis-title-styles: igx-type-scale-category($type-scale, $y-axis-title-text-style); From e0f3d6eb0efa91e8d376c6b41f3fb0bbabc8206e Mon Sep 17 00:00:00 2001 From: Simeon Simeonoff Date: Fri, 12 Jun 2020 17:57:52 +0300 Subject: [PATCH 06/53] fix(typography): add removed checkbox typography --- .../src/lib/core/styles/typography/_typography.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/projects/igniteui-angular/src/lib/core/styles/typography/_typography.scss b/projects/igniteui-angular/src/lib/core/styles/typography/_typography.scss index 19cc9fc361f..49ea3667492 100644 --- a/projects/igniteui-angular/src/lib/core/styles/typography/_typography.scss +++ b/projects/igniteui-angular/src/lib/core/styles/typography/_typography.scss @@ -97,6 +97,7 @@ @include igx-calendar-typography($type-scale); @include igx-card-typography($type-scale); @include igx-category-chart-typography($type-scale); + @include igx-checkbox-typography($type-scale); @include igx-chip-typography($type-scale); @include igx-column-hiding-typography($type-scale); @include igx-data-chart-typography($type-scale); From 994262a6e87f0f238cadeca2215a17c470c2cfa9 Mon Sep 17 00:00:00 2001 From: Stefan Ivanov Date: Tue, 16 Jun 2020 15:09:26 +0300 Subject: [PATCH 07/53] Light themes fluent and bootstrap --- .../themes/schemas/light/_dock-manager.scss | 53 ++++++++++++++++++- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss index cf38c5e88aa..b50c85cd962 100644 --- a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss +++ b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss @@ -77,12 +77,61 @@ $_light-dock-manager: ( /// @type {Map} /// @requires {function} extend /// @requires $_light-dock-manager -$_fluent-dock-manager: extend($_light-dock-manager); +$_fluent-dock-manager: extend( + $_light-dock-manager, ( + dock-background: #fff, + button-text: rgba(0, 0, 0, .74), + context-menu-background-active: #EBEBEB, + context-menu-color-active: rgba(0, 0, 0, .74), + context-menu-color: rgba(0, 0, 0, .74), + floating-pane-border-color: #BDBDBD, + joystick-background-active: #EBEBEB, + joystick-border-color: #BDBDBD, + joystick-icon-color: rgba(0, 0, 0, .74), + joystick-icon-color-active: rgba(0, 0, 0, .74), + pane-content-background: #fff, + primary-color: #fff, + splitter-background: #f2f2f2, + splitter-handle: #ccc, + tab-background-active: #fff, + tab-background: #fff, + tab-border-color-active: #fff, + tab-border-color: #fff, + tab-text-active: #2b579a, + tab-text: rgba(0, 0, 0, .62), + text-color: rgba(0, 0, 0, .74), + ) +); /// Generates a bootstrap dock-manager schema. /// @type {Map} /// @requires {function} extend /// @requires $_light-dock-manager /// @requires $_bootstrap-shape-dock-manager -$_bootstrap-dock-manager: extend($_light-dock-manager); +$_bootstrap-dock-manager: extend( + $_light-dock-manager, ( + dock-background: #f8f9fa, + button-text: #007bff, + context-menu-background-active: #007bff, + context-menu-color-active: #fff, + context-menu-color: #007bff, + floating-pane-border-color: #E0E0E0, + joystick-background-active: #007bff, + joystick-border-color: #E0E0E0, + joystick-icon-color: #007bff, + joystick-icon-color-active: #fff, + pane-content-background: #fff, + pinned-header-background: #f8f9fa, + primary-color: #f8f9fa, + splitter-background: #e9ecef, + splitter-handle: #bdc6d0, + tab-background-active: #fff, + tab-background: #fff, + tab-border-color-active: rgba(0, 0, 0, .12), + tab-border-color: #fff, + tab-text-active: rgba(0, 0, 0, .74), + tab-text: #007bff, + text-color: rgba(0, 0, 0, .74), + ) +); From 050239dd4d8b11d9d3fa97a4a6cee924746e776b Mon Sep 17 00:00:00 2001 From: Stefan Ivanov Date: Tue, 16 Jun 2020 18:30:03 +0300 Subject: [PATCH 08/53] Adding dark fluent and bootstrap themes and making a fix to the light ones. Closes #7578 --- .../themes/schemas/dark/_dock-manager.scss | 60 ++++++++++++++++++- .../themes/schemas/light/_dock-manager.scss | 6 +- 2 files changed, 62 insertions(+), 4 deletions(-) diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_dock-manager.scss b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_dock-manager.scss index 319a80a0378..57b7f7682e7 100644 --- a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_dock-manager.scss +++ b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_dock-manager.scss @@ -44,11 +44,67 @@ $_dark-dock-manager: extend( /// @type {Map} /// @requires {function} extend /// @requires $_fluent-dock-manager -$_dark-fluent-dock-manager: extend($_fluent-dock-manager); +$_dark-fluent-dock-manager: extend( + $_fluent-dock-manager, ( + border-color: #222, + button-text: #fff, + context-menu-background-active: #111, + context-menu-color-active: #fff, + context-menu-background: #333, + context-menu-color: #fff, + dock-background: #2a2a2a, + floating-pane-border-color: rgba(0, 0, 0, 0), + joystick-background-active: #111, + joystick-background: #333, + joystick-border-color: rgba(0, 0, 0, 0), + joystick-icon-color: #fff, + joystick-icon-color-active: #fff, + pane-content-background: #222, + pinned-header-background: #2a2a2a, + primary-color: #2a2a2a, + splitter-background: #151515, + splitter-handle: #000, + tab-background-active: #222, + tab-background: #222, + tab-border-color-active: #222, + tab-border-color: #222, + tab-text-active: #217346, + tab-text: #fff, + text-color: #fff, + ) +); /// Generates a dark bootstrap dock-manager schema. /// @type {Map} /// @requires {function} extend /// @requires $_bootstrap-dock-manager -$_dark-bootstrap-dock-manager: extend($_bootstrap-dock-manager); +$_dark-bootstrap-dock-manager: extend( + $_bootstrap-dock-manager, ( + border-color: #242939, + button-text: #007bff, + context-menu-background-active: #007bff, + context-menu-color-active: #fff, + context-menu-background: #222, + context-menu-color: #007bff, + dock-background: #111, + floating-pane-border-color: rgba(255, 255, 255, .12), + joystick-background-active: #007bff, + joystick-background: #222, + joystick-border-color: rgba(255, 255, 255, .12), + joystick-icon-color: #007bff, + joystick-icon-color-active: #fff, + pane-content-background: #242939, + pinned-header-background: #111, + primary-color: #111, + splitter-background: #1a1e29, + splitter-handle: #000, + tab-background-active: #242939, + tab-background: #242939, + tab-border-color-active: rgba(255, 255, 255, .12), + tab-border-color: #242939, + tab-text-active: rgba(255, 255, 255, .74), + tab-text: #007bff, + text-color: #fff, + ) +); diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss index b50c85cd962..3f2417c6982 100644 --- a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss +++ b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss @@ -79,11 +79,12 @@ $_light-dock-manager: ( /// @requires $_light-dock-manager $_fluent-dock-manager: extend( $_light-dock-manager, ( - dock-background: #fff, + border-color: #fff, button-text: rgba(0, 0, 0, .74), context-menu-background-active: #EBEBEB, context-menu-color-active: rgba(0, 0, 0, .74), context-menu-color: rgba(0, 0, 0, .74), + dock-background: #fff, floating-pane-border-color: #BDBDBD, joystick-background-active: #EBEBEB, joystick-border-color: #BDBDBD, @@ -110,11 +111,12 @@ $_fluent-dock-manager: extend( /// @requires $_bootstrap-shape-dock-manager $_bootstrap-dock-manager: extend( $_light-dock-manager, ( - dock-background: #f8f9fa, + border-color: #fff, button-text: #007bff, context-menu-background-active: #007bff, context-menu-color-active: #fff, context-menu-color: #007bff, + dock-background: #f8f9fa, floating-pane-border-color: #E0E0E0, joystick-background-active: #007bff, joystick-border-color: #E0E0E0, From b3eab5edb835d0e2b2fa33ada5370f3f52252c12 Mon Sep 17 00:00:00 2001 From: Stefan Ivanov Date: Fri, 19 Jun 2020 15:42:02 +0300 Subject: [PATCH 09/53] Initial update to themes to use palettes --- .../themes/schemas/dark/_dock-manager.scss | 16 ++- .../themes/schemas/light/_dock-manager.scss | 133 ++++++++++++++---- 2 files changed, 114 insertions(+), 35 deletions(-) diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_dock-manager.scss b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_dock-manager.scss index 57b7f7682e7..dd922bc612e 100644 --- a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_dock-manager.scss +++ b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_dock-manager.scss @@ -46,6 +46,10 @@ $_dark-dock-manager: extend( /// @requires $_fluent-dock-manager $_dark-fluent-dock-manager: extend( $_fluent-dock-manager, ( + active-color: ( + igx-color: primary, + ), + background-color: #2a2a2a, border-color: #222, button-text: #fff, context-menu-background-active: #111, @@ -53,22 +57,24 @@ $_dark-fluent-dock-manager: extend( context-menu-background: #333, context-menu-color: #fff, dock-background: #2a2a2a, - floating-pane-border-color: rgba(0, 0, 0, 0), + floating-pane-border-color: transparent, joystick-background-active: #111, joystick-background: #333, - joystick-border-color: rgba(0, 0, 0, 0), + joystick-border-color: transparent, joystick-icon-color: #fff, joystick-icon-color-active: #fff, pane-content-background: #222, + pane-header-backround: #2a2a2a, pinned-header-background: #2a2a2a, - primary-color: #2a2a2a, splitter-background: #151515, splitter-handle: #000, tab-background-active: #222, tab-background: #222, tab-border-color-active: #222, tab-border-color: #222, - tab-text-active: #217346, + tab-text-active: ( + igx-color: primary, + ), tab-text: #fff, text-color: #fff, ) @@ -94,6 +100,7 @@ $_dark-bootstrap-dock-manager: extend( joystick-icon-color: #007bff, joystick-icon-color-active: #fff, pane-content-background: #242939, + pane-header-background: #111, pinned-header-background: #111, primary-color: #111, splitter-background: #1a1e29, @@ -107,4 +114,3 @@ $_dark-bootstrap-dock-manager: extend( text-color: #fff, ) ); - diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss index 3f2417c6982..df1ea6de72c 100644 --- a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss +++ b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss @@ -40,8 +40,14 @@ /// @prop {Color} text-color [rgba(0, 0, 0, .72)] - Sets the text color for most elements in the dock manager. Used as the default joystick icon color. $_light-dock-manager: ( accent-color: #fff, + active-color: ( + igx-color: primary, + ), + background-color: #e5e7e9, border-color: #f3f5f7, - button-text: rgba(0, 0, 0, .72), + button-text: ( + igx-color: (grays, 800), + ), context-menu-background-active: null, context-menu-background: null, context-menu-color-active: #000, @@ -61,7 +67,6 @@ $_light-dock-manager: ( pane-header-text: null, pinned-header-background: null, pinned-header-text: null, - primary-color: #e5e7e9, splitter-background: #d3d6d9, splitter-handle: null, tab-background-active: #f3f5f7, @@ -70,7 +75,9 @@ $_light-dock-manager: ( tab-border-color: null, tab-text-active: null, tab-text: null, - text-color: rgba(0, 0, 0, .72), + text-color: ( + igx-color: (grays, 800), + ), ); /// Generates a fluent dock-manager schema. @@ -79,28 +86,81 @@ $_light-dock-manager: ( /// @requires $_light-dock-manager $_fluent-dock-manager: extend( $_light-dock-manager, ( - border-color: #fff, - button-text: rgba(0, 0, 0, .74), - context-menu-background-active: #EBEBEB, - context-menu-color-active: rgba(0, 0, 0, .74), - context-menu-color: rgba(0, 0, 0, .74), - dock-background: #fff, - floating-pane-border-color: #BDBDBD, - joystick-background-active: #EBEBEB, - joystick-border-color: #BDBDBD, - joystick-icon-color: rgba(0, 0, 0, .74), - joystick-icon-color-active: rgba(0, 0, 0, .74), - pane-content-background: #fff, - primary-color: #fff, - splitter-background: #f2f2f2, + active-color: ( + igx-color: primary, + ), + background-color: ( + igx-color: surface, + ), + border-color: ( + igx-color: surface, + ), + button-text: ( + igx-color: (grays, 800), + ), + context-menu-background-active: ( + igx-color: (grays, 200), + hexrgba: (), + ), + context-menu-color-active: ( + igx-color: (grays, 800), + ), + context-menu-color: ( + igx-color: (grays, 800), + ), + dock-background: ( + igx-color: surface, + ), + floating-pane-border-color: ( + igx-color: (grays, 400), + hexrgba: (), + ), + joystick-background-active: ( + igx-color: (grays, 200), + hexrgba: (), + ), + joystick-border-color: ( + igx-color: (grays, 400), + hexrgba: (), + ), + joystick-icon-color: ( + igx-color: (grays, 800), + ), + joystick-icon-color-active: ( + igx-color: (grays, 800), + ), + pane-content-background: ( + igx-color: surface, + ), + pane-header-background: ( + igx-color: surface, + ), + splitter-background: ( + igx-color: (grays, 100), + hexrgba: (), + ), splitter-handle: #ccc, - tab-background-active: #fff, - tab-background: #fff, - tab-border-color-active: #fff, - tab-border-color: #fff, - tab-text-active: #2b579a, - tab-text: rgba(0, 0, 0, .62), - text-color: rgba(0, 0, 0, .74), + tab-background-active: ( + igx-color: surface, + ), + tab-background: ( + igx-color: surface, + ), + tab-border-color-active: ( + igx-color: surface, + ), + tab-border-color: ( + igx-color: surface, + ), + tab-text-active: ( + igx-color: primary, + ), + tab-text: ( + igx-color: (grays, 700) + ), + text-color: ( + igx-color: (grays, 800) + ), ) ); @@ -112,18 +172,29 @@ $_fluent-dock-manager: extend( $_bootstrap-dock-manager: extend( $_light-dock-manager, ( border-color: #fff, - button-text: #007bff, - context-menu-background-active: #007bff, + button-text: ( + igx-color: primary, + ), + context-menu-background-active: ( + igx-color: primary, + ), context-menu-color-active: #fff, - context-menu-color: #007bff, + context-menu-color: ( + igx-color: primary, + ), dock-background: #f8f9fa, floating-pane-border-color: #E0E0E0, - joystick-background-active: #007bff, + joystick-background-active: ( + igx-color: primary, + ), joystick-border-color: #E0E0E0, - joystick-icon-color: #007bff, + joystick-icon-color: ( + igx-color: primary, + ), joystick-icon-color-active: #fff, pane-content-background: #fff, pinned-header-background: #f8f9fa, + pane-header-background: #f8f9fa, primary-color: #f8f9fa, splitter-background: #e9ecef, splitter-handle: #bdc6d0, @@ -132,7 +203,9 @@ $_bootstrap-dock-manager: extend( tab-border-color-active: rgba(0, 0, 0, .12), tab-border-color: #fff, tab-text-active: rgba(0, 0, 0, .74), - tab-text: #007bff, + tab-text: ( + igx-color: primary, + ), text-color: rgba(0, 0, 0, .74), ) ); From 3c0b33053a5a73f77256c457cb64d166bf021731 Mon Sep 17 00:00:00 2001 From: Stefan Ivanov Date: Fri, 19 Jun 2020 16:44:27 +0300 Subject: [PATCH 10/53] Light themes completed --- .../themes/schemas/light/_dock-manager.scss | 46 ++++++++++++++----- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss index df1ea6de72c..7592910ccbe 100644 --- a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss +++ b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss @@ -171,42 +171,66 @@ $_fluent-dock-manager: extend( /// @requires $_bootstrap-shape-dock-manager $_bootstrap-dock-manager: extend( $_light-dock-manager, ( - border-color: #fff, + border-color: ( + igx-color: surface + ), button-text: ( igx-color: primary, ), context-menu-background-active: ( igx-color: primary, ), - context-menu-color-active: #fff, + context-menu-color-active: ( + igx-color: surface + ), context-menu-color: ( igx-color: primary, ), dock-background: #f8f9fa, - floating-pane-border-color: #E0E0E0, + floating-pane-border-color: ( + igx-color: (grays, 300), + hexrgba: (), + ), joystick-background-active: ( igx-color: primary, ), - joystick-border-color: #E0E0E0, + joystick-border-color: ( + igx-color: (grays, 300), + hexrgba: (), + ), joystick-icon-color: ( igx-color: primary, ), joystick-icon-color-active: #fff, - pane-content-background: #fff, + pane-content-background: ( + igx-color: surface + ), pinned-header-background: #f8f9fa, pane-header-background: #f8f9fa, primary-color: #f8f9fa, splitter-background: #e9ecef, splitter-handle: #bdc6d0, - tab-background-active: #fff, - tab-background: #fff, - tab-border-color-active: rgba(0, 0, 0, .12), - tab-border-color: #fff, - tab-text-active: rgba(0, 0, 0, .74), + tab-background-active: ( + igx-color: surface + ), + tab-background: ( + igx-color: surface + ), + tab-border-color-active: ( + igx-color: (grays, 300) + ), + tab-border-color: ( + igx-color: surface + ), + tab-text-active: ( + igx-color: (grays, 800) + ), tab-text: ( igx-color: primary, ), - text-color: rgba(0, 0, 0, .74), + text-color: ( + igx-color: (grays, 800) + ), ) ); From d0090f4caa276453a9495392be55d598a108e650 Mon Sep 17 00:00:00 2001 From: Stefan Ivanov Date: Fri, 19 Jun 2020 19:32:12 +0300 Subject: [PATCH 11/53] Optimizing sass for dark themes --- .../themes/schemas/dark/_dock-manager.scss | 37 +++---------------- .../themes/schemas/light/_dock-manager.scss | 9 +---- 2 files changed, 7 insertions(+), 39 deletions(-) diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_dock-manager.scss b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_dock-manager.scss index dd922bc612e..1282eb14ca3 100644 --- a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_dock-manager.scss +++ b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_dock-manager.scss @@ -24,13 +24,17 @@ /// @requires $_light-dock-manager $_dark-dock-manager: extend( $_light-dock-manager, ( - accent-color: #424242, + accent-color: ( + igx-color: (grays, 400), + ), border-color: #212121, button-text: #fff, context-menu-color-active: #fff, floating-pane-border-color: rgba(0, 0, 0, .26), flyout-shadow-color: rgba(0, 0, 0, .38), - joystick-border-color: #424242, + joystick-border-color: ( + igx-color: (grays, 400), + ), joystick-icon-color-active: #fff, pane-content-background: #212121, primary-color: #111, @@ -46,11 +50,7 @@ $_dark-dock-manager: extend( /// @requires $_fluent-dock-manager $_dark-fluent-dock-manager: extend( $_fluent-dock-manager, ( - active-color: ( - igx-color: primary, - ), background-color: #2a2a2a, - border-color: #222, button-text: #fff, context-menu-background-active: #111, context-menu-color-active: #fff, @@ -63,18 +63,10 @@ $_dark-fluent-dock-manager: extend( joystick-border-color: transparent, joystick-icon-color: #fff, joystick-icon-color-active: #fff, - pane-content-background: #222, pane-header-backround: #2a2a2a, pinned-header-background: #2a2a2a, splitter-background: #151515, splitter-handle: #000, - tab-background-active: #222, - tab-background: #222, - tab-border-color-active: #222, - tab-border-color: #222, - tab-text-active: ( - igx-color: primary, - ), tab-text: #fff, text-color: #fff, ) @@ -86,31 +78,14 @@ $_dark-fluent-dock-manager: extend( /// @requires $_bootstrap-dock-manager $_dark-bootstrap-dock-manager: extend( $_bootstrap-dock-manager, ( - border-color: #242939, - button-text: #007bff, - context-menu-background-active: #007bff, - context-menu-color-active: #fff, context-menu-background: #222, - context-menu-color: #007bff, dock-background: #111, - floating-pane-border-color: rgba(255, 255, 255, .12), - joystick-background-active: #007bff, joystick-background: #222, - joystick-border-color: rgba(255, 255, 255, .12), - joystick-icon-color: #007bff, - joystick-icon-color-active: #fff, - pane-content-background: #242939, pane-header-background: #111, pinned-header-background: #111, primary-color: #111, splitter-background: #1a1e29, splitter-handle: #000, - tab-background-active: #242939, - tab-background: #242939, - tab-border-color-active: rgba(255, 255, 255, .12), - tab-border-color: #242939, - tab-text-active: rgba(255, 255, 255, .74), - tab-text: #007bff, text-color: #fff, ) ); diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss index 7592910ccbe..469b0758b4d 100644 --- a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss +++ b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss @@ -86,9 +86,6 @@ $_light-dock-manager: ( /// @requires $_light-dock-manager $_fluent-dock-manager: extend( $_light-dock-manager, ( - active-color: ( - igx-color: primary, - ), background-color: ( igx-color: surface, ), @@ -180,23 +177,19 @@ $_bootstrap-dock-manager: extend( context-menu-background-active: ( igx-color: primary, ), - context-menu-color-active: ( - igx-color: surface - ), + context-menu-color-active: #fff, context-menu-color: ( igx-color: primary, ), dock-background: #f8f9fa, floating-pane-border-color: ( igx-color: (grays, 300), - hexrgba: (), ), joystick-background-active: ( igx-color: primary, ), joystick-border-color: ( igx-color: (grays, 300), - hexrgba: (), ), joystick-icon-color: ( igx-color: primary, From a3af8fd2f5646df3fc0fa56f99ef74379b474763 Mon Sep 17 00:00:00 2001 From: Stefan Ivanov Date: Mon, 22 Jun 2020 11:29:22 +0300 Subject: [PATCH 12/53] Adding accent color to fix an issue with icon button background in dark themes --- .../src/lib/core/styles/themes/schemas/dark/_dock-manager.scss | 2 ++ 1 file changed, 2 insertions(+) diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_dock-manager.scss b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_dock-manager.scss index 1282eb14ca3..f6d9c37ea91 100644 --- a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_dock-manager.scss +++ b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_dock-manager.scss @@ -50,6 +50,7 @@ $_dark-dock-manager: extend( /// @requires $_fluent-dock-manager $_dark-fluent-dock-manager: extend( $_fluent-dock-manager, ( + accent-color: #111, background-color: #2a2a2a, button-text: #fff, context-menu-background-active: #111, @@ -78,6 +79,7 @@ $_dark-fluent-dock-manager: extend( /// @requires $_bootstrap-dock-manager $_dark-bootstrap-dock-manager: extend( $_bootstrap-dock-manager, ( + accent-color: #111, context-menu-background: #222, dock-background: #111, joystick-background: #222, From 92d41ef263429b252af8be97289d1f4d89c3b531 Mon Sep 17 00:00:00 2001 From: Stefan Ivanov Date: Thu, 25 Jun 2020 15:58:53 +0300 Subject: [PATCH 13/53] Closes #7541 --- .../themes/schemas/dark/_dock-manager.scss | 205 ++++++++++++++---- .../themes/schemas/light/_dock-manager.scss | 108 ++++++--- 2 files changed, 250 insertions(+), 63 deletions(-) diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_dock-manager.scss b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_dock-manager.scss index f6d9c37ea91..55d01be6e2b 100644 --- a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_dock-manager.scss +++ b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_dock-manager.scss @@ -26,21 +26,52 @@ $_dark-dock-manager: extend( $_light-dock-manager, ( accent-color: ( igx-color: (grays, 400), + hexrgba: #000, + ), + primary-color: ( + igx-color: (grays, 200), + hexrgba: #000, + ), + border-color: ( + igx-color: surface, + ), + button-text: ( + igx-contrast-color: surface, + ), + context-menu-color-active: ( + igx-contrast-color: surface, + ), + floating-pane-border-color: ( + igx-color: (grays, 100), + hexrgba: #000, ), - border-color: #212121, - button-text: #fff, - context-menu-color-active: #fff, - floating-pane-border-color: rgba(0, 0, 0, .26), flyout-shadow-color: rgba(0, 0, 0, .38), + joystick-background-active: ( + igx-color: surface, + ), joystick-border-color: ( igx-color: (grays, 400), + hexrgba: #000, + ), + joystick-icon-color: ( + igx-contrast-color: surface, + ), + joystick-icon-color-active: ( + igx-contrast-color: surface, + ), + pane-content-background: ( + igx-color: surface, + ), + splitter-background: ( + igx-color: (grays, 100), + hexrgba: #000, + ), + tab-background-active: ( + igx-color: surface, + ), + text-color: ( + igx-color: (grays, 800), ), - joystick-icon-color-active: #fff, - pane-content-background: #212121, - primary-color: #111, - splitter-background: #000, - tab-background-active: #212121, - text-color: rgba(255, 255, 255, .7), ) ); @@ -50,26 +81,82 @@ $_dark-dock-manager: extend( /// @requires $_fluent-dock-manager $_dark-fluent-dock-manager: extend( $_fluent-dock-manager, ( - accent-color: #111, - background-color: #2a2a2a, - button-text: #fff, - context-menu-background-active: #111, - context-menu-color-active: #fff, - context-menu-background: #333, - context-menu-color: #fff, - dock-background: #2a2a2a, + accent-color: ( + igx-color: surface, + rgba: 0.5, + hexrgba: #000, + ), + primary-color: ( + igx-color: surface, + rgba: 0.85, + hexrgba: #000, + ), + button-text: ( + igx-contrast-color: surface, + ), + context-menu-background-active: ( + igx-color: surface, + rgba: 0.5, + hexrgba: #000, + ), + context-menu-color-active: ( + igx-contrast-color: surface, + ), + context-menu-background: ( + igx-color: (grays, 400), + hexrgba: #000, + ), + context-menu-color: ( + igx-contrast-color: surface, + ), + dock-background: ( + igx-color: surface, + rgba: 0.85, + hexrgba: #000, + ), floating-pane-border-color: transparent, - joystick-background-active: #111, - joystick-background: #333, + joystick-background-active: ( + igx-color: surface, + rgba: 0.5, + hexrgba: #000, + ), + joystick-background: ( + igx-color: (grays, 400), + hexrgba: #000, + ), joystick-border-color: transparent, - joystick-icon-color: #fff, - joystick-icon-color-active: #fff, - pane-header-backround: #2a2a2a, - pinned-header-background: #2a2a2a, - splitter-background: #151515, - splitter-handle: #000, - tab-text: #fff, - text-color: #fff, + joystick-icon-color: ( + igx-contrast-color: surface, + ), + joystick-icon-color-active: ( + igx-contrast-color: surface, + ), + pane-header-backround: ( + igx-color: surface, + rgba: 0.85, + hexrgba: #000, + ), + pinned-header-background: ( + igx-color: surface, + rgba: 0.85, + hexrgba: #000, + ), + splitter-background: ( + igx-color: surface, + rgba: 0.7, + hexrgba: #000, + ), + splitter-handle: ( + igx-color: surface, + rgba: 0.2, + hexrgba: #000, + ), + tab-text: ( + igx-contrast-color: surface, + ), + text-color: ( + igx-contrast-color: surface, + ), ) ); @@ -79,15 +166,57 @@ $_dark-fluent-dock-manager: extend( /// @requires $_bootstrap-dock-manager $_dark-bootstrap-dock-manager: extend( $_bootstrap-dock-manager, ( - accent-color: #111, - context-menu-background: #222, - dock-background: #111, - joystick-background: #222, - pane-header-background: #111, - pinned-header-background: #111, - primary-color: #111, - splitter-background: #1a1e29, - splitter-handle: #000, - text-color: #fff, + accent-color: ( + igx-color: surface, + rgba: 0.33, + hexrgba: #000, + ), + primary-color: ( + igx-color: surface, + rgba: 0.33, + hexrgba: #000, + ), + context-menu-background: ( + igx-color: surface, + rgba: 0.66, + hexrgba: #000, + ), + context-menu-color-active: ( + igx-contrast-color: surface, + ), + dock-background: ( + igx-color: surface, + rgba: 0.33, + hexrgba: #000, + ), + joystick-background: ( + igx-color: surface, + rgba: 0.66, + hexrgba: #000, + ), + joystick-icon-color-active: ( + igx-contrast-color: surface, + ), + pane-header-background: ( + igx-color: surface, + rgba: 0.33, + hexrgba: #000, + ), + pinned-header-background: ( + igx-color: surface, + rgba: 0.33, + hexrgba: #000, + ), + splitter-background: ( + igx-color: (grays,300), + hexrgba: #000, + ), + splitter-handle: ( + igx-color: (grays,50), + hexrgba: #000, + ), + text-color: ( + igx-contrast-color: surface, + ), ) ); diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss index 469b0758b4d..5a88258db37 100644 --- a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss +++ b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss @@ -39,37 +39,61 @@ /// @prop {Color} tab-text-active [null] - Sets the text color for active tabs. /// @prop {Color} text-color [rgba(0, 0, 0, .72)] - Sets the text color for most elements in the dock manager. Used as the default joystick icon color. $_light-dock-manager: ( - accent-color: #fff, + accent-color: null, active-color: ( igx-color: primary, ), - background-color: #e5e7e9, - border-color: #f3f5f7, + primary-color: null, + border-color: ( + igx-color: (primary, 100), + rgba: 0.1, + hexrgba: (), + ), button-text: ( igx-color: (grays, 800), ), context-menu-background-active: null, context-menu-background: null, - context-menu-color-active: #000, + context-menu-color-active: ( + igx-contrast-color: surface, + ), context-menu-color: null, dock-background: null, dock-text: null, - floating-pane-border-color: #fff, + floating-pane-border-color: ( + igx-color: surface, + ), flyout-shadow-color: rgba(0, 0, 0, .08), joystick-background-active: null, joystick-background: null, - joystick-border-color: #d3d6d9, - joystick-icon-color: #d3d6d9, - joystick-icon-color-active: #000, - pane-content-background: #f3f5f7, + joystick-border-color: ( + igx-color: (grays, 300), + ), + joystick-icon-color: ( + igx-color: (grays, 600), + ), + joystick-icon-color-active: ( + igx-contrast-color: surface, + ), + pane-content-background: ( + igx-color: (primary, 100), + rgba: 0.1, + hexrgba: (), + ), pane-content-text: null, pane-header-background: null, pane-header-text: null, pinned-header-background: null, pinned-header-text: null, - splitter-background: #d3d6d9, + splitter-background: ( + igx-color: (grays, 300), + ), splitter-handle: null, - tab-background-active: #f3f5f7, + tab-background-active: ( + igx-color: (primary, 100), + rgba: 0.1, + hexrgba: (), + ), tab-background: null, tab-border-color-active: null, tab-border-color: null, @@ -86,8 +110,9 @@ $_light-dock-manager: ( /// @requires $_light-dock-manager $_fluent-dock-manager: extend( $_light-dock-manager, ( - background-color: ( - igx-color: surface, + primary-color: ( + igx-color: (grays, 50), + hexrgba: (), ), border-color: ( igx-color: surface, @@ -106,7 +131,8 @@ $_fluent-dock-manager: extend( igx-color: (grays, 800), ), dock-background: ( - igx-color: surface, + igx-color: (grays, 50), + hexrgba: (), ), floating-pane-border-color: ( igx-color: (grays, 400), @@ -130,13 +156,22 @@ $_fluent-dock-manager: extend( igx-color: surface, ), pane-header-background: ( - igx-color: surface, + igx-color: (grays, 50), + hexrgba: (), + ), + pinned-header-background: ( + igx-color: (grays, 50), + hexrgba: (), ), splitter-background: ( igx-color: (grays, 100), hexrgba: (), ), - splitter-handle: #ccc, + splitter-handle: ( + igx-color: (grays, 400), + rgba: 0.2, + hexrgba: (), + ), tab-background-active: ( igx-color: surface, ), @@ -168,8 +203,12 @@ $_fluent-dock-manager: extend( /// @requires $_bootstrap-shape-dock-manager $_bootstrap-dock-manager: extend( $_light-dock-manager, ( + primary-color: ( + igx-color: (grays, 100), + hexrgba: (), + ), border-color: ( - igx-color: surface + igx-color: surface, ), button-text: ( igx-color: primary, @@ -177,11 +216,16 @@ $_bootstrap-dock-manager: extend( context-menu-background-active: ( igx-color: primary, ), - context-menu-color-active: #fff, + context-menu-color-active: ( + igx-color: surface, + ), context-menu-color: ( igx-color: primary, ), - dock-background: #f8f9fa, + dock-background: ( + igx-color: (grays, 100), + hexrgba: (), + ), floating-pane-border-color: ( igx-color: (grays, 300), ), @@ -194,15 +238,29 @@ $_bootstrap-dock-manager: extend( joystick-icon-color: ( igx-color: primary, ), - joystick-icon-color-active: #fff, + joystick-icon-color-active: ( + igx-color: surface, + ), pane-content-background: ( igx-color: surface ), - pinned-header-background: #f8f9fa, - pane-header-background: #f8f9fa, - primary-color: #f8f9fa, - splitter-background: #e9ecef, - splitter-handle: #bdc6d0, + pinned-header-background: ( + igx-color: (grays, 100), + hexrgba: (), + ), + pane-header-background: ( + igx-color: (grays, 100), + hexrgba: (), + ), + splitter-background: ( + igx-color: (grays,200), + hexrgba: (), + ), + splitter-handle: ( + igx-color: (grays,400), + rgba: 0.2, + hexrgba: (), + ), tab-background-active: ( igx-color: surface ), From f336a44c23f98752c0f948cffa407c7c7c3339b2 Mon Sep 17 00:00:00 2001 From: Simeon Simeonoff Date: Fri, 26 Jun 2020 16:40:54 +0300 Subject: [PATCH 14/53] style(themes): dock manager linting errors --- .../themes/schemas/dark/_dock-manager.scss | 32 +++++++++---------- .../themes/schemas/light/_dock-manager.scss | 10 +++--- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_dock-manager.scss b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_dock-manager.scss index 55d01be6e2b..0bdd765b504 100644 --- a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_dock-manager.scss +++ b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_dock-manager.scss @@ -83,12 +83,12 @@ $_dark-fluent-dock-manager: extend( $_fluent-dock-manager, ( accent-color: ( igx-color: surface, - rgba: 0.5, + rgba: .5, hexrgba: #000, ), primary-color: ( igx-color: surface, - rgba: 0.85, + rgba: .85, hexrgba: #000, ), button-text: ( @@ -96,7 +96,7 @@ $_dark-fluent-dock-manager: extend( ), context-menu-background-active: ( igx-color: surface, - rgba: 0.5, + rgba: .5, hexrgba: #000, ), context-menu-color-active: ( @@ -111,13 +111,13 @@ $_dark-fluent-dock-manager: extend( ), dock-background: ( igx-color: surface, - rgba: 0.85, + rgba: .85, hexrgba: #000, ), floating-pane-border-color: transparent, joystick-background-active: ( igx-color: surface, - rgba: 0.5, + rgba: .5, hexrgba: #000, ), joystick-background: ( @@ -133,22 +133,22 @@ $_dark-fluent-dock-manager: extend( ), pane-header-backround: ( igx-color: surface, - rgba: 0.85, + rgba: .85, hexrgba: #000, ), pinned-header-background: ( igx-color: surface, - rgba: 0.85, + rgba: .85, hexrgba: #000, ), splitter-background: ( igx-color: surface, - rgba: 0.7, + rgba: .7, hexrgba: #000, ), splitter-handle: ( igx-color: surface, - rgba: 0.2, + rgba: .2, hexrgba: #000, ), tab-text: ( @@ -168,17 +168,17 @@ $_dark-bootstrap-dock-manager: extend( $_bootstrap-dock-manager, ( accent-color: ( igx-color: surface, - rgba: 0.33, + rgba: .33, hexrgba: #000, ), primary-color: ( igx-color: surface, - rgba: 0.33, + rgba: .33, hexrgba: #000, ), context-menu-background: ( igx-color: surface, - rgba: 0.66, + rgba: .66, hexrgba: #000, ), context-menu-color-active: ( @@ -186,12 +186,12 @@ $_dark-bootstrap-dock-manager: extend( ), dock-background: ( igx-color: surface, - rgba: 0.33, + rgba: .33, hexrgba: #000, ), joystick-background: ( igx-color: surface, - rgba: 0.66, + rgba: .66, hexrgba: #000, ), joystick-icon-color-active: ( @@ -199,12 +199,12 @@ $_dark-bootstrap-dock-manager: extend( ), pane-header-background: ( igx-color: surface, - rgba: 0.33, + rgba: .33, hexrgba: #000, ), pinned-header-background: ( igx-color: surface, - rgba: 0.33, + rgba: .33, hexrgba: #000, ), splitter-background: ( diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss index 5a88258db37..b9fde2359f8 100644 --- a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss +++ b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss @@ -46,7 +46,7 @@ $_light-dock-manager: ( primary-color: null, border-color: ( igx-color: (primary, 100), - rgba: 0.1, + rgba: .1, hexrgba: (), ), button-text: ( @@ -77,7 +77,7 @@ $_light-dock-manager: ( ), pane-content-background: ( igx-color: (primary, 100), - rgba: 0.1, + rgba: .1, hexrgba: (), ), pane-content-text: null, @@ -91,7 +91,7 @@ $_light-dock-manager: ( splitter-handle: null, tab-background-active: ( igx-color: (primary, 100), - rgba: 0.1, + rgba: .1, hexrgba: (), ), tab-background: null, @@ -169,7 +169,7 @@ $_fluent-dock-manager: extend( ), splitter-handle: ( igx-color: (grays, 400), - rgba: 0.2, + rgba: .2, hexrgba: (), ), tab-background-active: ( @@ -258,7 +258,7 @@ $_bootstrap-dock-manager: extend( ), splitter-handle: ( igx-color: (grays,400), - rgba: 0.2, + rgba: .2, hexrgba: (), ), tab-background-active: ( From 42bc9a4052ef94ea148a91a711b459b49b15e068 Mon Sep 17 00:00:00 2001 From: Aleksandyr Date: Thu, 2 Jul 2020 10:51:25 +0300 Subject: [PATCH 15/53] feat(cell): expose default formatting for bool types Closes #7224 --- projects/igniteui-angular/src/lib/grids/cell.component.html | 4 +++- .../src/lib/grids/tree-grid/tree-cell.component.html | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/projects/igniteui-angular/src/lib/grids/cell.component.html b/projects/igniteui-angular/src/lib/grids/cell.component.html index 0aa8c34c8c0..e9a52a57075 100644 --- a/projects/igniteui-angular/src/lib/grids/cell.component.html +++ b/projects/igniteui-angular/src/lib/grids/cell.component.html @@ -6,7 +6,9 @@ [value]="formatter ? formatter(value) : column.dataType === 'number' ? (value | igxdecimal: grid.locale) : column.dataType === 'date' ? (value | igxdate: grid.locale) : value" [row]="rowData" [column]="this.column.field" [containerClass]="'igx-grid__td-text'" [metadata]="searchMetadata" class="igx-grid__td-text">{{ formatter ? formatter(value) : column.dataType === 'number' ? (value | igxdecimal: - grid.locale) : column.dataType === 'date' ? (value | igxdate: grid.locale) : value }} + grid.locale) : column.dataType === 'date' ? (value | igxdate: grid.locale) : column.dataType === 'boolean' ? "" : value }} + {{value ? 'check' : 'close'}} + diff --git a/projects/igniteui-angular/src/lib/grids/tree-grid/tree-cell.component.html b/projects/igniteui-angular/src/lib/grids/tree-grid/tree-cell.component.html index 5b66eb7b820..cb96a001d9c 100644 --- a/projects/igniteui-angular/src/lib/grids/tree-grid/tree-cell.component.html +++ b/projects/igniteui-angular/src/lib/grids/tree-grid/tree-cell.component.html @@ -6,7 +6,8 @@ [value]="formatter ? formatter(value) : column.dataType === 'number' ? (value | igxdecimal: grid.locale) : column.dataType === 'date' ? (value | igxdate: grid.locale) : value" [row]="rowData" [column]="this.column.field" [containerClass]="'igx-grid__td-text'" [metadata]="searchMetadata" class="igx-grid__td-text">{{ formatter ? formatter(value) : column.dataType === 'number' ? (value | igxdecimal: - grid.locale) : column.dataType === 'date' ? (value | igxdate: grid.locale) : value }} + grid.locale) : column.dataType === 'date' ? (value | igxdate: grid.locale) : column.dataType === 'boolean' ? "" : value }} + {{value ? 'check' : 'close'}} From 8cfa9f3ec5675a587e5880a8bb60e0ad3a51a66d Mon Sep 17 00:00:00 2001 From: Simeon Simeonoff Date: Fri, 3 Jul 2020 11:33:22 +0300 Subject: [PATCH 16/53] refactor(themes): update dock manager color props --- .../components/dock-manager/_dock-manager-theme.scss | 2 +- .../core/styles/themes/schemas/dark/_dock-manager.scss | 8 ++++---- .../core/styles/themes/schemas/light/_dock-manager.scss | 9 +++++---- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/projects/igniteui-angular/src/lib/core/styles/components/dock-manager/_dock-manager-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/dock-manager/_dock-manager-theme.scss index e8d50ac4a1a..d088072566a 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/dock-manager/_dock-manager-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/dock-manager/_dock-manager-theme.scss @@ -31,7 +31,7 @@ /// @param {Color} $pane-header-text [null] - Sets the text color for pane headers. /// @param {Color} $pinned-header-background [null] - Sets the background colors of pinned headers. /// @param {Color} $pinned-header-text [null] - Sets the text colors of pinned headers. -/// @param {Color} $primary-color [null] - Sets the base dock manager color as well as the pane headers and tabs background colors. +/// @param {Color} $background-color [null] - Sets the base dock manager color as well as the pane headers and tabs background colors. /// @param {Color} $splitter-background [null] - Sets the background color for the splitters. /// @param {Color} $splitter-handle [null] - Sets the background color for the splitter handles. /// @param {Color} $tab-background [null] - Sets the background color for tabs. diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_dock-manager.scss b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_dock-manager.scss index 0bdd765b504..3dbb9b4fa70 100644 --- a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_dock-manager.scss +++ b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_dock-manager.scss @@ -17,7 +17,7 @@ /// @prop {Color} joystick-border-color [#424242] - Sets the border color of the joystick. /// @prop {Color} joystick-icon-color-active [#fff] - Sets the color of the active joystick icons. /// @prop {Color} pane-content-background [#212121] - Sets the background color of the content panes. -/// @prop {Color} primary-color [#111] - Sets the base dock manager color as well as the pane headers and tabs background colors. +/// @prop {Color} background-color [#111] - Sets the base dock manager color as well as the pane headers and tabs background colors. /// @prop {Color} splitter-background [#000] - Sets the background color for the splitters. /// @prop {Color} tab-background-active [#212121] - Sets the background color for active tabs. /// @prop {Color} text-color [rgba(255, 255, 255, .7)] - Sets the text color for most elements in the dock manager. Used as the default joystick icon color. @@ -28,7 +28,7 @@ $_dark-dock-manager: extend( igx-color: (grays, 400), hexrgba: #000, ), - primary-color: ( + background-color: ( igx-color: (grays, 200), hexrgba: #000, ), @@ -86,7 +86,7 @@ $_dark-fluent-dock-manager: extend( rgba: .5, hexrgba: #000, ), - primary-color: ( + background-color: ( igx-color: surface, rgba: .85, hexrgba: #000, @@ -171,7 +171,7 @@ $_dark-bootstrap-dock-manager: extend( rgba: .33, hexrgba: #000, ), - primary-color: ( + background-color: ( igx-color: surface, rgba: .33, hexrgba: #000, diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss index b9fde2359f8..2f1c874d751 100644 --- a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss +++ b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss @@ -7,6 +7,7 @@ /// Generates a light dock-manager schema. /// @type {Map} /// @prop {Color} accent-color [#fff] - Sets the pinned header background color, the joystick background and border colors, as well as the context menu background color. +/// @prop {Color} active-color [igx-color: 'primary'] - Sets the active text and border colors for tabs, panes, and menus. /// @prop {Color} border-color [#F3F5F7] - Sets the global border color in the dock manager. Also sets the pane content background and the context menu active background colors. /// @prop {Color} button-text [rgba(0, 0, 0, .72)] - Sets the button text color. /// @prop {Color} context-menu-background [null] - Sets the background color for context menus. @@ -28,7 +29,7 @@ /// @prop {Color} pane-header-text [null] - Sets the text color for pane headers. /// @prop {Color} pinned-header-background [null] - Sets the background colors of pinned headers. /// @prop {Color} pinned-header-text [null] - Sets the text colors of pinned headers. -/// @prop {Color} primary-color [#E5E7E9] - Sets the base dock manager color as well as the pane headers and tabs background colors. +/// @prop {Color} background-color [#E5E7E9] - Sets the base dock manager color as well as the pane headers and tabs background colors. /// @prop {Color} splitter-background [#d3d6d9] - Sets the background color for the splitters. /// @prop {Color} splitter-handle [null] - Sets the background color for the splitter handles. /// @prop {Color} tab-background [null] - Sets the background color for tabs. @@ -43,7 +44,7 @@ $_light-dock-manager: ( active-color: ( igx-color: primary, ), - primary-color: null, + background-color: null, border-color: ( igx-color: (primary, 100), rgba: .1, @@ -110,7 +111,7 @@ $_light-dock-manager: ( /// @requires $_light-dock-manager $_fluent-dock-manager: extend( $_light-dock-manager, ( - primary-color: ( + background-color: ( igx-color: (grays, 50), hexrgba: (), ), @@ -203,7 +204,7 @@ $_fluent-dock-manager: extend( /// @requires $_bootstrap-shape-dock-manager $_bootstrap-dock-manager: extend( $_light-dock-manager, ( - primary-color: ( + background-color: ( igx-color: (grays, 100), hexrgba: (), ), From f53dc9ec9a5eaf2e3153006624c419702c2c6e95 Mon Sep 17 00:00:00 2001 From: Simeon Simeonoff Date: Fri, 3 Jul 2020 16:50:29 +0300 Subject: [PATCH 17/53] docs(themes): document the dock-manager schemas --- .../themes/schemas/dark/_dock-manager.scss | 146 +++++++------ .../themes/schemas/light/_dock-manager.scss | 204 ++++++++++-------- 2 files changed, 200 insertions(+), 150 deletions(-) diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_dock-manager.scss b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_dock-manager.scss index 3dbb9b4fa70..0e781709581 100644 --- a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_dock-manager.scss +++ b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_dock-manager.scss @@ -8,215 +8,237 @@ /// Generates a dark dock-manager schema. /// @type {Map} /// @requires {function} extend -/// @prop {Color} accent-color [#424242] - Sets the pinned header background color, the joystick background and border colors, as well as the context menu background color. -/// @prop {Color} border-color [#212121] - Sets the global border color in the dock manager. Also sets the pane content background and the context menu active background colors. -/// @prop {Color} button-text [#fff] - Sets the button text color. -/// @prop {Color} context-menu-color-active [#fff] - Sets the text color for active context menus. -/// @prop {Color} floating-pane-border-color [rgba(0, 0, 0, .26)] - Sets the border color for floating panes. +/// @prop {Color} accent-color [igx-color: ('grays', 400), hexrgba: #000] - Sets the pinned header background color, the joystick background and border colors, as well as the context menu background color. +/// @prop {Color} background-color [igx-color: ('grays', 200), hexrgba: #000] - Sets the base dock manager color as well as the pane headers and tabs background colors. +/// @prop {Color} border-color [igx-color: 'surface'] - Sets the global border color in the dock manager. Also sets the pane content background and the context menu active background colors. +/// @prop {Color} button-text [igx-contrast-color: 'surface'] - Sets the button text color. +/// @prop {Color} floating-pane-border-color [igx-color: ('grays', 100), hexrgba: #000] - Sets the border color for floating panes. /// @prop {Color} flyout-shadow-color [rgba(0, 0, 0, .38)] - Sets the border color for floating panes. -/// @prop {Color} joystick-border-color [#424242] - Sets the border color of the joystick. -/// @prop {Color} joystick-icon-color-active [#fff] - Sets the color of the active joystick icons. -/// @prop {Color} pane-content-background [#212121] - Sets the background color of the content panes. -/// @prop {Color} background-color [#111] - Sets the base dock manager color as well as the pane headers and tabs background colors. -/// @prop {Color} splitter-background [#000] - Sets the background color for the splitters. -/// @prop {Color} tab-background-active [#212121] - Sets the background color for active tabs. -/// @prop {Color} text-color [rgba(255, 255, 255, .7)] - Sets the text color for most elements in the dock manager. Used as the default joystick icon color. +/// @prop {Color} joystick-background-active [igx-color: 'surface'] - Sets the background color of the joysticks. +/// @prop {Color} joystick-border-color [igx-color: ('grays', 400), hexrgba: #000] - Sets the border color of the joystick. +/// @prop {Color} joystick-icon-color [igx-contrast-color: 'surface'] - Sets the color for the joystick icons. +/// @prop {Color} pane-content-background [igx-color: 'surface'] - Sets the background color of the content panes. +/// @prop {Color} splitter-background [igx-clor: ('grays', 100), hexrgba: #000] - Sets the background color for the splitters. +/// @prop {Color} tab-background-active [igx-color: 'surface'] - Sets the background color for active tabs. /// @requires $_light-dock-manager $_dark-dock-manager: extend( $_light-dock-manager, ( accent-color: ( - igx-color: (grays, 400), + igx-color: ('grays', 400), hexrgba: #000, ), background-color: ( - igx-color: (grays, 200), + igx-color: ('grays', 200), hexrgba: #000, ), border-color: ( - igx-color: surface, + igx-color: 'surface', ), button-text: ( - igx-contrast-color: surface, - ), - context-menu-color-active: ( - igx-contrast-color: surface, + igx-contrast-color: 'surface', ), floating-pane-border-color: ( - igx-color: (grays, 100), + igx-color: ('grays', 100), hexrgba: #000, ), flyout-shadow-color: rgba(0, 0, 0, .38), joystick-background-active: ( - igx-color: surface, + igx-color: 'surface', ), joystick-border-color: ( - igx-color: (grays, 400), + igx-color: ('grays', 400), hexrgba: #000, ), joystick-icon-color: ( - igx-contrast-color: surface, - ), - joystick-icon-color-active: ( - igx-contrast-color: surface, + igx-contrast-color: 'surface', ), pane-content-background: ( - igx-color: surface, + igx-color: 'surface', ), splitter-background: ( - igx-color: (grays, 100), + igx-color: ('grays', 100), hexrgba: #000, ), tab-background-active: ( - igx-color: surface, - ), - text-color: ( - igx-color: (grays, 800), + igx-color: 'surface', ), ) ); /// Generates a dark fluent dock-manager schema. /// @type {Map} +/// @prop {Color} accent-color [igx-color: 'surface', rgba: .5, hexrgba: #000] - Sets the pinned header background color, the joystick background and border colors, as well as the context menu background color. +/// @prop {Color} background-color [igx-color: 'surface', rgba: .85, hexrgba: #000] - Sets the base dock manager color as well as the pane headers and tabs background colors. +/// @prop {Color} button-text [igx-contrast-color: 'surface'] - Sets the button text color. +/// @prop {Color} context-menu-background-active [igx-color: 'surface', rgba: .5, hexrgba: #000] - Sets the background color for active context menus. +/// @prop {Color} context-menu-color-active [igx-contrast-color: 'surface'] - Sets the text color for active context menus. +/// @prop {Color} context-menu-background [igx-color: ('grays', 400), hexrgba: #000] - Sets the background color for context menus. +/// @prop {Color} context-menu-color [igx-contrast-color: 'surface'] - Sets the text color for context menus. +/// @prop {Color} dock-background [igx-color: 'surface', rgba: .85, hexrgba: #000] - Sets the background color of the dock manager. +/// @prop {Color} floating-pane-border-color [transparent] - Sets the border color for floating panes. +/// @prop {Color} joystick-background-active [igx-color: 'surface', rgba: .5, hexrgba: #000] - Sets the background color of the joysticks. +/// @prop {Color} joystick-background [igx-color: ('grays', 400), hexrgba: #000] - Sets the background color of the joystick. +/// @prop {Color} joystick-border-color [transparent] - Sets the border color of the joystick. +/// @prop {Color} joystick-icon-color [igx-contrast-color: 'surface'] - Sets the color for the joystick icons. +/// @prop {Color} joystick-icon-color-active [igx-contrast-color: 'surface'] - Sets the color of the active joystick icons. +/// @prop {Color} pane-header-background [igx-color: 'surface', rgba: .33, hexrgba: #000] - Sets the background color for pane headers. +/// @prop {Color} pinned-header-background [igx-color: 'surface', rgba: .85, hexrgba: #000] - Sets the background colors of pinned headers. +/// @prop {Color} splitter-background [igx-color: 'surface', rgba: .7, hexrgba: #000] - Sets the background color for the splitters. +/// @prop {Color} splitter-handle [igx-color: 'surface', rgba: .2, hexrgba: #000] - Sets the background color for the splitter handles. +/// @prop {Color} tab-text [igx-contrast-color: 'surface'] - Sets the text color for tabs. +/// @prop {Color} text-color [igx-contrast-color: 'surface'] - Sets the text color for most elements in the dock manager. Used as the default joystick icon color. /// @requires {function} extend /// @requires $_fluent-dock-manager $_dark-fluent-dock-manager: extend( $_fluent-dock-manager, ( accent-color: ( - igx-color: surface, + igx-color: 'surface', rgba: .5, hexrgba: #000, ), background-color: ( - igx-color: surface, + igx-color: 'surface', rgba: .85, hexrgba: #000, ), button-text: ( - igx-contrast-color: surface, + igx-contrast-color: 'surface', ), context-menu-background-active: ( - igx-color: surface, + igx-color: 'surface', rgba: .5, hexrgba: #000, ), context-menu-color-active: ( - igx-contrast-color: surface, + igx-contrast-color: 'surface', ), context-menu-background: ( - igx-color: (grays, 400), + igx-color: ('grays', 400), hexrgba: #000, ), context-menu-color: ( - igx-contrast-color: surface, + igx-contrast-color: 'surface', ), dock-background: ( - igx-color: surface, + igx-color: 'surface', rgba: .85, hexrgba: #000, ), floating-pane-border-color: transparent, joystick-background-active: ( - igx-color: surface, + igx-color: 'surface', rgba: .5, hexrgba: #000, ), joystick-background: ( - igx-color: (grays, 400), + igx-color: ('grays', 400), hexrgba: #000, ), joystick-border-color: transparent, joystick-icon-color: ( - igx-contrast-color: surface, + igx-contrast-color: 'surface', ), joystick-icon-color-active: ( - igx-contrast-color: surface, + igx-contrast-color: 'surface', ), pane-header-backround: ( - igx-color: surface, + igx-color: 'surface', rgba: .85, hexrgba: #000, ), pinned-header-background: ( - igx-color: surface, + igx-color: 'surface', rgba: .85, hexrgba: #000, ), splitter-background: ( - igx-color: surface, + igx-color: 'surface', rgba: .7, hexrgba: #000, ), splitter-handle: ( - igx-color: surface, + igx-color: 'surface', rgba: .2, hexrgba: #000, ), tab-text: ( - igx-contrast-color: surface, + igx-contrast-color: 'surface', ), text-color: ( - igx-contrast-color: surface, + igx-contrast-color: 'surface', ), ) ); /// Generates a dark bootstrap dock-manager schema. /// @type {Map} +/// @prop {Color} accent-color [igx-color: 'surface', rgba: .33, hexrgba: ()] - Sets the pinned header background color, the joystick background and border colors, as well as the context menu background color. +/// @prop {Color} background-color [igx-color: 'surface', rgba: .33, hexrgba: ()] - Sets the base dock manager color as well as the pane headers and tabs background colors. +/// @prop {Color} context-menu-background [igx-color: 'surface', rgba: .66, hexrgba: ()] - Sets the background color for context menus. +/// @prop {Color} context-menu-color-active [igx-context-color: 'surface'] - Sets the text color for active context menus. +/// @prop {Color} dock-background [igx-color: 'surface', rgba: .33, hexrgba: ()] - Sets the background color of the dock manager. +/// @prop {Color} joystick-background [igx-color: 'surface', rgba: .66, hexrgba: ()] - Sets the background color of the joystick. +/// @prop {Color} joystick-icon-color-active [igx-context-color: 'surface'] - Sets the color of the active joystick icons. +/// @prop {Color} pane-header-background [igx-color: 'surface', rgba: .33, hexrgba: ()] - Sets the background color for pane headers. +/// @prop {Color} pinned-header-background [igx-color: 'surface', rgba: .33, hexrgba: ()] - Sets the background colors of pinned headers. +/// @prop {Color} splitter-background [igx-color: ('grays', 300), hexrgba: ()] - Sets the background color for the splitters. +/// @prop {Color} splitter-handle [igx-color: ('grays', 50), hexrgba: ()] - Sets the background color for the splitter handles. +/// @prop {Color} text-color [igx-contrast-color: 'surface'] - Sets the text color for most elements in the dock manager. Used as the default joystick icon color. /// @requires {function} extend /// @requires $_bootstrap-dock-manager $_dark-bootstrap-dock-manager: extend( $_bootstrap-dock-manager, ( accent-color: ( - igx-color: surface, + igx-color: 'surface', rgba: .33, hexrgba: #000, ), background-color: ( - igx-color: surface, + igx-color: 'surface', rgba: .33, hexrgba: #000, ), context-menu-background: ( - igx-color: surface, + igx-color: 'surface', rgba: .66, hexrgba: #000, ), context-menu-color-active: ( - igx-contrast-color: surface, + igx-contrast-color: 'surface', ), dock-background: ( - igx-color: surface, + igx-color: 'surface', rgba: .33, hexrgba: #000, ), joystick-background: ( - igx-color: surface, + igx-color: 'surface', rgba: .66, hexrgba: #000, ), joystick-icon-color-active: ( - igx-contrast-color: surface, + igx-contrast-color: 'surface', ), pane-header-background: ( - igx-color: surface, + igx-color: 'surface', rgba: .33, hexrgba: #000, ), pinned-header-background: ( - igx-color: surface, + igx-color: 'surface', rgba: .33, hexrgba: #000, ), splitter-background: ( - igx-color: (grays,300), + igx-color: ('grays', 300), hexrgba: #000, ), splitter-handle: ( - igx-color: (grays,50), + igx-color: ('grays', 50), hexrgba: #000, ), text-color: ( - igx-contrast-color: surface, + igx-contrast-color: 'surface', ), ) ); diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss index 2f1c874d751..73316e659a0 100644 --- a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss +++ b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_dock-manager.scss @@ -6,39 +6,39 @@ /// Generates a light dock-manager schema. /// @type {Map} -/// @prop {Color} accent-color [#fff] - Sets the pinned header background color, the joystick background and border colors, as well as the context menu background color. +/// @prop {Color} accent-color [null] - Sets the pinned header background color, the joystick background and border colors, as well as the context menu background color. /// @prop {Color} active-color [igx-color: 'primary'] - Sets the active text and border colors for tabs, panes, and menus. -/// @prop {Color} border-color [#F3F5F7] - Sets the global border color in the dock manager. Also sets the pane content background and the context menu active background colors. -/// @prop {Color} button-text [rgba(0, 0, 0, .72)] - Sets the button text color. -/// @prop {Color} context-menu-background [null] - Sets the background color for context menus. +/// @prop {Color} background-color [null] - Sets the base dock manager color as well as the pane headers and tabs background colors. +/// @prop {Color} border-color [igx-color: ('primary', 100), rgba: .1, hexrgba: ()] - Sets the global border color in the dock manager. Also sets the pane content background and the context menu active background colors. +/// @prop {Color} button-text [igx-color: ('grays', 800)] - Sets the button text color. /// @prop {Color} context-menu-background-active [null] - Sets the background color for active context menus. +/// @prop {Color} context-menu-background [null] - Sets the background color for context menus. +/// @prop {Color} context-menu-color-active [igx-contrast-color: 'surface'] - Sets the text color for active context menus. /// @prop {Color} context-menu-color [null] - Sets the text color for context menus. -/// @prop {Color} context-menu-color-active [#000] - Sets the text color for active context menus. /// @prop {Color} dock-background [null] - Sets the background color of the dock manager. /// @prop {Color} dock-text [null] - Sets the text color of the dock manager. -/// @prop {Color} floating-pane-border-color [#fff] - Sets the border color for floating panes. +/// @prop {Color} floating-pane-border-color [igx-color: 'surface'] - Sets the border color for floating panes. /// @prop {Color} flyout-shadow-color [rgba(0, 0, 0, .08)] - Sets the flyout shadow color. /// @prop {Color} joystick-background [null] - Sets the background color of the joystick. /// @prop {Color} joystick-background-active [null] - Sets the background color of the joysticks. -/// @prop {Color} joystick-border-color [#D3D6D9] - Sets the border color of the joystick. -/// @prop {Color} joystick-icon-color [#D3D6D9] - Sets the color for the joystick icons. -/// @prop {Color} joystick-icon-color-active [#000] - Sets the color of the active joystick icons. -/// @prop {Color} pane-content-background [#F3F5F7] - Sets the background color of the content panes. +/// @prop {Color} joystick-border-color [igx-color: ('grays', 300)] - Sets the border color of the joystick. +/// @prop {Color} joystick-icon-color [igx-color: ('grays', 600)] - Sets the color for the joystick icons. +/// @prop {Color} joystick-icon-color-active [igx-contrast-color: 'surface'] - Sets the color of the active joystick icons. +/// @prop {Color} pane-content-background [igx-color: ('primary', 100), rgba: .1, hexrgba: ()] - Sets the background color of the content panes. /// @prop {Color} pane-content-text [null] - Sets the text color of the content panes. /// @prop {Color} pane-header-background [null] - Sets the background color for pane headers. /// @prop {Color} pane-header-text [null] - Sets the text color for pane headers. /// @prop {Color} pinned-header-background [null] - Sets the background colors of pinned headers. /// @prop {Color} pinned-header-text [null] - Sets the text colors of pinned headers. -/// @prop {Color} background-color [#E5E7E9] - Sets the base dock manager color as well as the pane headers and tabs background colors. -/// @prop {Color} splitter-background [#d3d6d9] - Sets the background color for the splitters. +/// @prop {Color} splitter-background [igx-color: ('grays', 300)] - Sets the background color for the splitters. /// @prop {Color} splitter-handle [null] - Sets the background color for the splitter handles. +/// @prop {Color} tab-background-active [igx-color: ('primary', 100), rgba: .1, hexrgba: ()] - Sets the background color for active tabs. /// @prop {Color} tab-background [null] - Sets the background color for tabs. -/// @prop {Color} tab-background-active [#F3F5F7] - Sets the background color for active tabs. /// @prop {Color} tab-border-color [null] - Sets the border color for tabs. /// @prop {Color} tab-border-color-active [null] - Sets the border color for active tabs. /// @prop {Color} tab-text [null] - Sets the text color for tabs. /// @prop {Color} tab-text-active [null] - Sets the text color for active tabs. -/// @prop {Color} text-color [rgba(0, 0, 0, .72)] - Sets the text color for most elements in the dock manager. Used as the default joystick icon color. +/// @prop {Color} text-color [igx-color: ('grays', 800)] - Sets the text color for most elements in the dock manager. Used as the default joystick icon color. $_light-dock-manager: ( accent-color: null, active-color: ( @@ -46,38 +46,38 @@ $_light-dock-manager: ( ), background-color: null, border-color: ( - igx-color: (primary, 100), + igx-color: ('primary', 100), rgba: .1, hexrgba: (), ), button-text: ( - igx-color: (grays, 800), + igx-color: ('grays', 800), ), context-menu-background-active: null, context-menu-background: null, context-menu-color-active: ( - igx-contrast-color: surface, + igx-contrast-color: 'surface', ), context-menu-color: null, dock-background: null, dock-text: null, floating-pane-border-color: ( - igx-color: surface, + igx-color: 'surface', ), flyout-shadow-color: rgba(0, 0, 0, .08), joystick-background-active: null, joystick-background: null, joystick-border-color: ( - igx-color: (grays, 300), + igx-color: ('grays', 300), ), joystick-icon-color: ( - igx-color: (grays, 600), + igx-color: ('grays', 600), ), joystick-icon-color-active: ( - igx-contrast-color: surface, + igx-contrast-color: 'surface', ), pane-content-background: ( - igx-color: (primary, 100), + igx-color: ('primary', 100), rgba: .1, hexrgba: (), ), @@ -87,11 +87,11 @@ $_light-dock-manager: ( pinned-header-background: null, pinned-header-text: null, splitter-background: ( - igx-color: (grays, 300), + igx-color: ('grays', 300), ), splitter-handle: null, tab-background-active: ( - igx-color: (primary, 100), + igx-color: ('primary', 100), rgba: .1, hexrgba: (), ), @@ -101,187 +101,215 @@ $_light-dock-manager: ( tab-text-active: null, tab-text: null, text-color: ( - igx-color: (grays, 800), + igx-color: ('grays', 800), ), ); /// Generates a fluent dock-manager schema. /// @type {Map} +/// @prop {Color} background-color [igx-color: ('grays', 50), hexrgba: ()] - Sets the base dock manager color as well as the pane headers and tabs background colors. +/// @prop {Color} border-color [igx-color: 'surface'] - Sets the global border color in the dock manager. Also sets the pane content background and the context menu active background colors. +/// @prop {Color} context-menu-background-active [igx-color: ('grays', 200), hexrgba: ()] - Sets the background color for active context menus. +/// @prop {Color} context-menu-color-active [igx-color: ('grays', 800)] - Sets the text color for active context menus. +/// @prop {Color} context-menu-color [igx-color: ('grays', 800)] - Sets the text color for active context menus. +/// @prop {Color} dock-background [igx-color: ('grays', 50), hexrgba: ()] - Sets the background color of the dock manager. +/// @prop {Color} floating-pane-border-color [igx-color: ('grays', 400), hexrgba: ()] - Sets the border color for floating panes. +/// @prop {Color} joystick-background-active [igx-color: ('grays', 200), hexrgba: ()] - Sets the background color of the joysticks. +/// @prop {Color} joystick-border-color [igx-color: ('grays', 400), hexrgba: ()] - Sets the border color of the joystick. +/// @prop {Color} joystick-icon-color [igx-color: ('grays', 800)] - Sets the color for the joystick icons. +/// @prop {Color} joystick-icon-color-active [igx-color: ('grays', 800)] - Sets the color of the active joystick icons. +/// @prop {Color} pane-content-background [igx-color: 'surface'] - Sets the background color of the content panes. +/// @prop {Color} pane-header-background [igx-color: ('grays', 50), hexrgba: ()] - Sets the background color for pane headers. +/// @prop {Color} splitter-background [igx-color: ('grays', 100), hexrgba: ()] - Sets the background color for the splitters. +/// @prop {Color} splitter-handle [igx-color: ('grays', 400), rgba: .2, hexrgba: ()] - Sets the background color for the splitter handles. +/// @prop {Color} tab-background-active [igx-color: 'surface'] - Sets the background color for active tabs. +/// @prop {Color} tab-background [igx-color: 'surface'] - Sets the background color for tabs. +/// @prop {Color} tab-border-color [igx-color: 'surface'] - Sets the border color for tabs. +/// @prop {Color} tab-border-color-active [igx-color: 'surface'] - Sets the border color for active tabs. +/// @prop {Color} tab-text-active [igx-color: 'surface'] - Sets the text color for active tabs. +/// @prop {Color} tab-text [igx-color: ('grays', 700)] - Sets the text color for tabs. /// @requires {function} extend /// @requires $_light-dock-manager $_fluent-dock-manager: extend( - $_light-dock-manager, ( + $_light-dock-manager, + ( background-color: ( - igx-color: (grays, 50), + igx-color: ('grays', 50), hexrgba: (), ), border-color: ( - igx-color: surface, - ), - button-text: ( - igx-color: (grays, 800), + igx-color: 'surface', ), context-menu-background-active: ( - igx-color: (grays, 200), + igx-color: ('grays', 200), hexrgba: (), ), context-menu-color-active: ( - igx-color: (grays, 800), + igx-color: ('grays', 800), ), context-menu-color: ( - igx-color: (grays, 800), + igx-color: ('grays', 800), ), dock-background: ( - igx-color: (grays, 50), + igx-color: ('grays', 50), hexrgba: (), ), floating-pane-border-color: ( - igx-color: (grays, 400), + igx-color: ('grays', 400), hexrgba: (), ), joystick-background-active: ( - igx-color: (grays, 200), + igx-color: ('grays', 200), hexrgba: (), ), joystick-border-color: ( - igx-color: (grays, 400), + igx-color: ('grays', 400), hexrgba: (), ), joystick-icon-color: ( - igx-color: (grays, 800), + igx-color: ('grays', 800), ), joystick-icon-color-active: ( - igx-color: (grays, 800), + igx-color: ('grays', 800), ), pane-content-background: ( - igx-color: surface, + igx-color: 'surface', ), pane-header-background: ( - igx-color: (grays, 50), + igx-color: ('grays', 50), hexrgba: (), ), pinned-header-background: ( - igx-color: (grays, 50), + igx-color: ('grays', 50), hexrgba: (), ), splitter-background: ( - igx-color: (grays, 100), + igx-color: ('grays', 100), hexrgba: (), ), splitter-handle: ( - igx-color: (grays, 400), + igx-color: ('grays', 400), rgba: .2, hexrgba: (), ), tab-background-active: ( - igx-color: surface, + igx-color: 'surface', ), tab-background: ( - igx-color: surface, + igx-color: 'surface', ), tab-border-color-active: ( - igx-color: surface, + igx-color: 'surface', ), tab-border-color: ( - igx-color: surface, + igx-color: 'surface', ), tab-text-active: ( - igx-color: primary, + igx-color: 'primary', ), tab-text: ( - igx-color: (grays, 700) - ), - text-color: ( - igx-color: (grays, 800) + igx-color: ('grays', 700) ), ) ); /// Generates a bootstrap dock-manager schema. /// @type {Map} +/// @prop {Color} background-color [igx-color: ('grays', 100), hexrgba: ()] - Sets the base dock manager color as well as the pane headers and tabs background colors. +/// @prop {Color} border-color [igx-color: 'surface'] - Sets the global border color in the dock manager. Also sets the pane content background and the context menu active background colors. +/// @prop {Color} button-text [igx-color: 'primary'] - Sets the button text color. +/// @prop {Color} context-menu-background-active [igx-color: 'primary'] - Sets the background color for active context menus. +/// @prop {Color} context-menu-color-active [igx-color: 'surface'] - Sets the text color for active context menus. +/// @prop {Color} context-menu-color [igx-color: 'primary'] - Sets the text color for context menus. +/// @prop {Color} dock-background [igx-color: ('grays', 100), hexrgba: ()] - Sets the background color of the dock manager. +/// @prop {Color} floating-pane-border-color [igx-color: ('grays', 300)] - Sets the border color for floating panes. +/// @prop {Color} joystick-background-active [igx-color: 'primary'] - Sets the background color of the joysticks. +/// @prop {Color} joystick-icon-color [igx-color: 'primary'] - Sets the color for the joystick icons. +/// @prop {Color} pane-content-background [igx-color: 'surface'] - Sets the background color of the content panes. +/// @prop {Color} pane-header-background [igx-color: ('grays', 100), hexrgba: ()] - Sets the background color for pane headers. +/// @prop {Color} pinned-header-background [igx-color: ('grays', 100), hexrgba: ()] - Sets the background colors of pinned headers. +/// @prop {Color} splitter-background [igx-color: ('grays', 200), hexrgba: ()] - Sets the background color for the splitters. +/// @prop {Color} splitter-handle [igx-color: ('grays', 400), rgba: .2, hexrgba: ()] - Sets the background color for the splitter handles. +/// @prop {Color} tab-background-active [igx-color: 'surface'] - Sets the background color for active tabs. +/// @prop {Color} tab-background [igx-color: 'surface'] - Sets the background color for tabs. +/// @prop {Color} tab-border-color-active [igx-color: ('grays', 300)] - Sets the border color for active tabs. +/// @prop {Color} tab-border-color [igx-color: 'surface'] - Sets the border color for tabs. +/// @prop {Color} tab-text-active [igx-color: ('grays', 800)] - Sets the text color for active tabs. +/// @prop {Color} tab-text [igx-color: 'primary'] - Sets the text color for tabs. /// @requires {function} extend /// @requires $_light-dock-manager -/// @requires $_bootstrap-shape-dock-manager $_bootstrap-dock-manager: extend( - $_light-dock-manager, ( + $_light-dock-manager, + ( background-color: ( - igx-color: (grays, 100), + igx-color: ('grays', 100), hexrgba: (), ), border-color: ( - igx-color: surface, + igx-color: 'surface', ), button-text: ( - igx-color: primary, + igx-color: 'primary', ), context-menu-background-active: ( - igx-color: primary, + igx-color: 'primary', ), context-menu-color-active: ( - igx-color: surface, + igx-color: 'surface', ), context-menu-color: ( - igx-color: primary, + igx-color: 'primary', ), dock-background: ( - igx-color: (grays, 100), + igx-color: ('grays', 100), hexrgba: (), ), floating-pane-border-color: ( - igx-color: (grays, 300), + igx-color: ('grays', 300), ), joystick-background-active: ( - igx-color: primary, - ), - joystick-border-color: ( - igx-color: (grays, 300), + igx-color: 'primary', ), joystick-icon-color: ( - igx-color: primary, - ), - joystick-icon-color-active: ( - igx-color: surface, + igx-color: 'primary', ), pane-content-background: ( - igx-color: surface + igx-color: 'surface', ), - pinned-header-background: ( - igx-color: (grays, 100), + pane-header-background: ( + igx-color: ('grays', 100), hexrgba: (), ), - pane-header-background: ( - igx-color: (grays, 100), + pinned-header-background: ( + igx-color: ('grays', 100), hexrgba: (), ), splitter-background: ( - igx-color: (grays,200), + igx-color: ('grays', 200), hexrgba: (), ), splitter-handle: ( - igx-color: (grays,400), + igx-color: ('grays', 400), rgba: .2, hexrgba: (), ), tab-background-active: ( - igx-color: surface + igx-color: 'surface', ), tab-background: ( - igx-color: surface + igx-color: 'surface', ), tab-border-color-active: ( - igx-color: (grays, 300) + igx-color: ('grays', 300) ), tab-border-color: ( - igx-color: surface + igx-color: 'surface', ), tab-text-active: ( - igx-color: (grays, 800) + igx-color: ('grays', 800) ), tab-text: ( - igx-color: primary, - ), - text-color: ( - igx-color: (grays, 800) + igx-color: 'primary', ), ) ); From d5145131d1557dfbd05546f47585a126e9c12014 Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Tue, 7 Jul 2020 09:49:00 +0300 Subject: [PATCH 18/53] feat(calendar): emit events on user actions #7039 --- .../src/lib/calendar/calendar-base.ts | 37 +++- .../lib/calendar/calendar.component.spec.ts | 20 +- .../src/lib/calendar/calendar.component.ts | 19 ++ .../src/lib/calendar/month-picker-base.ts | 20 +- .../month-picker.component.spec.ts | 4 +- .../month-picker/month-picker.component.ts | 26 ++- .../src/lib/calendar/navigation.service.ts | 185 ------------------ .../calendar-views/calendar-views.sample.html | 6 +- .../calendar-views/calendar-views.sample.ts | 11 +- src/app/calendar/calendar.sample.html | 2 +- src/app/calendar/calendar.sample.ts | 15 +- 11 files changed, 139 insertions(+), 206 deletions(-) delete mode 100644 projects/igniteui-angular/src/lib/calendar/navigation.service.ts diff --git a/projects/igniteui-angular/src/lib/calendar/calendar-base.ts b/projects/igniteui-angular/src/lib/calendar/calendar-base.ts index a5f33a315c4..e63c3e49e6e 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar-base.ts +++ b/projects/igniteui-angular/src/lib/calendar/calendar-base.ts @@ -4,6 +4,7 @@ import { ControlValueAccessor } from '@angular/forms'; import { DateRangeDescriptor } from '../core/dates'; import { Subject } from 'rxjs'; import { isDate } from '../core/utils'; +import { CalendarView } from './month-picker-base'; /** * Sets the selction type - single, multi or range. @@ -20,6 +21,11 @@ export enum ScrollMonth { NONE = 'none' } +export interface IViewDateChangeEventArgs { + previousValue: Date; + currentValue: Date; +} + /** @hidden @internal */ @Directive({ selector: '[igxCalendarBase]', @@ -168,7 +174,8 @@ export class IgxCalendarBaseDirective implements ControlValueAccessor { * Sets the date that will be presented in the default view when the component renders. */ public set viewDate(value: Date) { - this._viewDate = this.getDateOnly(value); + const date = this.getDateOnly(value).setDate(1); + this._viewDate = new Date(date); } /** @@ -240,6 +247,34 @@ export class IgxCalendarBaseDirective implements ControlValueAccessor { @Output() public onSelection = new EventEmitter(); + /** + * Emits an event when the month in view is changed. + * ```html + * + * ``` + * ```typescript + * public viewDateChanged(event: IViewDateChangeEventArgs) { + * let newDate = event.newViewDate; + * } + * ``` + */ + @Output() + public onViewDateChanged = new EventEmitter(); + + /** + * Emits an event when the active view is changed. + * ```html + * + * ``` + * ```typescript + * public activeViewChanged(event: CalendarView) { + * let activeView = event; + * } + * ``` + */ + @Output() + public onActiveViewChanged = new EventEmitter(); + /** * @hidden */ diff --git a/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts b/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts index ef402ed028e..2e8ed531649 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts +++ b/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts @@ -252,8 +252,8 @@ describe('IgxCalendar - ', () => { expect(calendar.formatOptions).toEqual(jasmine.objectContaining(defaultOptions)); expect(calendar.formatViews).toEqual(jasmine.objectContaining(defaultViews)); expect(headerYear.nativeElement.textContent.trim()).toMatch('2018'); - expect(headerWeekday.nativeElement.textContent.trim()).toMatch('Mon'); - expect(headerDate.nativeElement.textContent.trim()).toMatch('Sep 17'); + expect(headerWeekday.nativeElement.textContent.trim()).toMatch('Sat'); + expect(headerDate.nativeElement.textContent.trim()).toMatch('Sep 1'); expect(bodyYear.nativeElement.textContent.trim()).toMatch('2018'); expect(bodyMonth.nativeElement.textContent.trim()).toMatch('Sep'); @@ -267,8 +267,8 @@ describe('IgxCalendar - ', () => { expect(calendar.formatOptions).toEqual(jasmine.objectContaining(Object.assign(defaultOptions, formatOptions))); expect(calendar.formatViews).toEqual(jasmine.objectContaining(Object.assign(defaultViews, formatViews))); expect(headerYear.nativeElement.textContent.trim()).toMatch('18'); - expect(headerWeekday.nativeElement.textContent.trim()).toMatch('Mon'); - expect(headerDate.nativeElement.textContent.trim()).toMatch('September 17'); + expect(headerWeekday.nativeElement.textContent.trim()).toMatch('Sat'); + expect(headerDate.nativeElement.textContent.trim()).toMatch('September 1'); expect(bodyYear.nativeElement.textContent.trim()).toMatch('18'); expect(bodyMonth.nativeElement.textContent.trim()).toMatch('September'); @@ -283,8 +283,8 @@ describe('IgxCalendar - ', () => { expect(calendar.formatOptions).toEqual(jasmine.objectContaining(Object.assign(defaultOptions, formatOptions))); expect(calendar.formatViews).toEqual(jasmine.objectContaining(Object.assign(defaultViews, formatViews))); expect(headerYear.nativeElement.textContent.trim()).toMatch('2018'); - expect(headerWeekday.nativeElement.textContent.trim()).toMatch('Mon'); - expect(headerDate.nativeElement.textContent.trim()).toMatch('September 17'); + expect(headerWeekday.nativeElement.textContent.trim()).toMatch('Sat'); + expect(headerDate.nativeElement.textContent.trim()).toMatch('September 1'); expect(bodyYear.nativeElement.textContent.trim()).toMatch('2018'); expect(bodyMonth.nativeElement.textContent.trim()).toMatch('8'); }); @@ -305,8 +305,8 @@ describe('IgxCalendar - ', () => { fixture.detectChanges(); expect(headerYear.nativeElement.textContent.trim()).toMatch('2018'); - expect(headerWeekday.nativeElement.textContent.trim()).toMatch('Mon'); - expect(headerDate.nativeElement.textContent.trim()).toMatch('Sep 17'); + expect(headerWeekday.nativeElement.textContent.trim()).toMatch('Sat'); + expect(headerDate.nativeElement.textContent.trim()).toMatch('Sep 1'); expect(bodyYear.nativeElement.textContent.trim()).toMatch('2018'); expect(bodyMonth.nativeElement.textContent.trim()).toMatch('Sep'); expect(bodyWeekday.nativeElement.textContent.trim()).toMatch('Sun'); @@ -319,8 +319,8 @@ describe('IgxCalendar - ', () => { bodyWeekday = dom.query(By.css(HelperTestFunctions.WEEKSTART_LABEL_CSSCLASS)); expect(calendar.locale).toEqual(locale); expect(headerYear.nativeElement.textContent.trim()).toMatch('18'); - expect(headerWeekday.nativeElement.textContent.trim()).toMatch('lun.,'); - expect(headerDate.nativeElement.textContent.trim()).toMatch('17 sept.'); + expect(headerWeekday.nativeElement.textContent.trim()).toMatch('sam.,'); + expect(headerDate.nativeElement.textContent.trim()).toMatch('1 sept.'); expect(bodyYear.nativeElement.textContent.trim()).toMatch('18'); expect(bodyMonth.nativeElement.textContent.trim()).toMatch('sept.'); expect(bodyWeekday.nativeElement.textContent.trim()).toMatch('Dim.'); diff --git a/projects/igniteui-angular/src/lib/calendar/calendar.component.ts b/projects/igniteui-angular/src/lib/calendar/calendar.component.ts index 68b25a9c35d..3964e201c42 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/calendar.component.ts @@ -466,9 +466,13 @@ export class IgxCalendarComponent extends IgxMonthPickerBaseDirective implements * @internal */ public previousMonth(isKeydownTrigger = false) { + const previousValue = this.viewDate; this.viewDate = this.calendarModel.getPrevMonth(this.viewDate); this.animationAction = ScrollMonth.PREV; this.isKeydownTrigger = isKeydownTrigger; + requestAnimationFrame(() => { + this.onViewDateChanged.emit({ previousValue, currentValue: this.viewDate }); + }); } /** @@ -478,9 +482,13 @@ export class IgxCalendarComponent extends IgxMonthPickerBaseDirective implements * @internal */ public nextMonth(isKeydownTrigger = false) { + const previousValue = this.viewDate; this.viewDate = this.calendarModel.getNextMonth(this.viewDate); this.animationAction = ScrollMonth.NEXT; this.isKeydownTrigger = isKeydownTrigger; + requestAnimationFrame(() => { + this.onViewDateChanged.emit({ previousValue, currentValue: this.viewDate }); + }); } /** @@ -609,7 +617,9 @@ export class IgxCalendarComponent extends IgxMonthPickerBaseDirective implements if (day) { this.daysView.daysNavService.focusNextDate(day.nativeElement, args.key, true); } + this.onViewDateChanged.emit({previousValue, currentValue: this.viewDate}); }; + const previousValue = this.viewDate; this.viewDate = this.nextDate; } @@ -618,12 +628,15 @@ export class IgxCalendarComponent extends IgxMonthPickerBaseDirective implements * @intenal */ public changeMonth(event: Date) { + const previousValue = this.viewDate; this.viewDate = this.calendarModel.getFirstViewDate(event, 'month', this.activeViewIdx); this.activeView = CalendarView.DEFAULT; requestAnimationFrame(() => { const elem = this.monthsBtns.find((e: ElementRef, idx: number) => idx === this.activeViewIdx); if (elem) { elem.nativeElement.focus(); } + this.onViewDateChanged.emit({previousValue, currentValue: this.viewDate}); + this.onActiveViewChanged.emit(this.activeView); }); } @@ -637,6 +650,7 @@ export class IgxCalendarComponent extends IgxMonthPickerBaseDirective implements requestAnimationFrame(() => { this.monthsView.date = args; this.focusMonth(event.target); + this.onActiveViewChanged.emit(this.activeView); }); } @@ -813,6 +827,7 @@ export class IgxCalendarComponent extends IgxMonthPickerBaseDirective implements const isPageDown = event.key === 'PageDown'; const step = isPageDown ? 1 : -1; + const previousValue = this.viewDate; this.viewDate = this.calendarModel.timedelta(this.viewDate, 'year', step); this.animationAction = isPageDown ? ScrollMonth.NEXT : ScrollMonth.PREV; @@ -849,6 +864,10 @@ export class IgxCalendarComponent extends IgxMonthPickerBaseDirective implements if (dayItem && dayItem.isFocusable) { dayItem.nativeElement.focus(); } }; } + + requestAnimationFrame(() => { + this.onViewDateChanged.emit({previousValue, currentValue: this.viewDate}); + }); } /** diff --git a/projects/igniteui-angular/src/lib/calendar/month-picker-base.ts b/projects/igniteui-angular/src/lib/calendar/month-picker-base.ts index 55aa507770e..323e7623f29 100644 --- a/projects/igniteui-angular/src/lib/calendar/month-picker-base.ts +++ b/projects/igniteui-angular/src/lib/calendar/month-picker-base.ts @@ -1,5 +1,5 @@ import { IgxCalendarBaseDirective } from './calendar-base'; -import { HostBinding, Directive, ViewChildren, ElementRef, QueryList } from '@angular/core'; +import { HostBinding, Directive, ViewChildren, ElementRef, QueryList, Input } from '@angular/core'; import { KEYS } from '../core/utils'; /** @@ -36,8 +36,12 @@ export class IgxMonthPickerBaseDirective extends IgxCalendarBaseDirective { public yearsBtns: QueryList; + @Input() /** * Gets the current active view. + * ```typescript + * this.activeView = calendar.activeView; + * ``` */ public get activeView(): CalendarView { return this._activeView; @@ -45,6 +49,12 @@ export class IgxMonthPickerBaseDirective extends IgxCalendarBaseDirective { /** * Sets the current active view. + * ```html + * + * ``` + * ```typescript + * calendar.activeView = CalendarView.YEAR; + * ``` */ public set activeView(val: CalendarView) { this._activeView = val; @@ -73,6 +83,7 @@ export class IgxMonthPickerBaseDirective extends IgxCalendarBaseDirective { * @hidden */ public changeYear(event: Date) { + const previousValue = this.viewDate; this.viewDate = this.calendarModel.getFirstViewDate(event, 'month', this.activeViewIdx); this.activeView = CalendarView.DEFAULT; @@ -80,6 +91,8 @@ export class IgxMonthPickerBaseDirective extends IgxCalendarBaseDirective { if (this.yearsBtns && this.yearsBtns.length) { this.yearsBtns.find((e: ElementRef, idx: number) => idx === this.activeViewIdx).nativeElement.focus(); } + this.onViewDateChanged.emit({ previousValue, currentValue: this.viewDate }); + this.onActiveViewChanged.emit(this.activeView); }); } @@ -87,8 +100,11 @@ export class IgxMonthPickerBaseDirective extends IgxCalendarBaseDirective { * @hidden */ public activeViewDecade(activeViewIdx = 0): void { - this._activeView = CalendarView.DECADE; + this.activeView = CalendarView.DECADE; this.activeViewIdx = activeViewIdx; + requestAnimationFrame(() => { + this.onActiveViewChanged.emit(this.activeView); + }); } /** diff --git a/projects/igniteui-angular/src/lib/calendar/month-picker/month-picker.component.spec.ts b/projects/igniteui-angular/src/lib/calendar/month-picker/month-picker.component.spec.ts index e4a55e10867..c5b0b3285e2 100644 --- a/projects/igniteui-angular/src/lib/calendar/month-picker/month-picker.component.spec.ts +++ b/projects/igniteui-angular/src/lib/calendar/month-picker/month-picker.component.spec.ts @@ -89,7 +89,7 @@ describe('IgxMonthPicker', () => { expect(monthPicker.locale).toEqual('fr'); expect(monthPicker.formatOptions.year).toEqual('2-digit'); expect(monthPicker.value.getDate()).toEqual(today.getDate()); - expect(monthPicker.viewDate.getDate()).toEqual(today.getDate()); + expect(monthPicker.viewDate.getDate()).toEqual(1); }); it('should properly set formatOptions and formatViews', () => { @@ -173,7 +173,7 @@ describe('IgxMonthPicker', () => { expect(monthPicker.onSelection.emit).toHaveBeenCalled(); expect(currentMonth.nativeElement.textContent.trim()).toEqual('Mar'); - const nextDay = new Date(2019, 2, 7); + const nextDay = new Date(2019, 2, 1); expect(fixture.componentInstance.model.getDate()).toEqual(nextDay.getDate()); }); diff --git a/projects/igniteui-angular/src/lib/calendar/month-picker/month-picker.component.ts b/projects/igniteui-angular/src/lib/calendar/month-picker/month-picker.component.ts index fc85c9fe830..5d225244143 100644 --- a/projects/igniteui-angular/src/lib/calendar/month-picker/month-picker.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/month-picker/month-picker.component.ts @@ -121,6 +121,7 @@ export class IgxMonthPickerComponent extends IgxMonthPickerBaseDirective { requestAnimationFrame(() => { if (this.dacadeView) { this.dacadeView.el.nativeElement.focus(); } + this.onActiveViewChanged.emit(this.activeView); }); } @@ -140,10 +141,15 @@ export class IgxMonthPickerComponent extends IgxMonthPickerBaseDirective { */ public nextYear() { this.yearAction = 'next'; + const previousValue = this.viewDate; this.viewDate = this.calendarModel.getNextYear(this.viewDate); this.selectDate(this.viewDate); this.onSelection.emit(this.selectedDates); + + requestAnimationFrame(() => { + this.onViewDateChanged.emit({ previousValue, currentValue: this.viewDate }); + }); } /** @@ -163,10 +169,15 @@ export class IgxMonthPickerComponent extends IgxMonthPickerBaseDirective { */ public previousYear() { this.yearAction = 'prev'; + const previousValue = this.viewDate; this.viewDate = this.calendarModel.getPrevYear(this.viewDate); this.selectDate(this.viewDate); this.onSelection.emit(this.selectedDates); + + requestAnimationFrame(() => { + this.onViewDateChanged.emit({ previousValue, currentValue: this.viewDate }); + }); } /** @@ -185,6 +196,7 @@ export class IgxMonthPickerComponent extends IgxMonthPickerBaseDirective { * @hidden */ public selectYear(event: Date) { + const previousValue = this.viewDate; this.viewDate = new Date(event.getFullYear(), event.getMonth(), event.getDate()); this.activeView = CalendarView.DEFAULT; @@ -193,6 +205,8 @@ export class IgxMonthPickerComponent extends IgxMonthPickerBaseDirective { requestAnimationFrame(() => { if (this.yearsBtn) { this.yearsBtn.nativeElement.focus(); } + this.onViewDateChanged.emit({ previousValue, currentValue: this.viewDate }); + this.onActiveViewChanged.emit(this.activeView); }); } @@ -207,7 +221,7 @@ export class IgxMonthPickerComponent extends IgxMonthPickerBaseDirective { /** * Selects a date. * ```typescript - * this.monPicker.selectDate(new Date(`2018-06-12`)); + * this.monthPicker.selectDate(new Date(`2018-06-12`)); * ``` */ public selectDate(value: Date) { @@ -238,7 +252,12 @@ export class IgxMonthPickerComponent extends IgxMonthPickerBaseDirective { public onKeydownPageUp(event: KeyboardEvent) { event.preventDefault(); this.yearAction = 'prev'; + const previousValue = this.viewDate; this.viewDate = this.calendarModel.getPrevYear(this.viewDate); + + requestAnimationFrame(() => { + this.onViewDateChanged.emit({ previousValue, currentValue: this.viewDate }); + }); } /** @@ -248,7 +267,12 @@ export class IgxMonthPickerComponent extends IgxMonthPickerBaseDirective { public onKeydownPageDown(event: KeyboardEvent) { event.preventDefault(); this.yearAction = 'next'; + const previousValue = this.viewDate; this.viewDate = this.calendarModel.getNextYear(this.viewDate); + + requestAnimationFrame(() => { + this.onViewDateChanged.emit({ previousValue, currentValue: this.viewDate }); + }); } /** diff --git a/projects/igniteui-angular/src/lib/calendar/navigation.service.ts b/projects/igniteui-angular/src/lib/calendar/navigation.service.ts deleted file mode 100644 index 432955121b3..00000000000 --- a/projects/igniteui-angular/src/lib/calendar/navigation.service.ts +++ /dev/null @@ -1,185 +0,0 @@ -import { Injectable } from '@angular/core'; -import { IgxDayItemComponent } from './days-view/day-item.component'; -import { IgxDaysViewComponent } from './days-view/days-view.component'; -import { ScrollMonth } from './calendar-base'; - -enum Direction { - Up = 'ArrowUp', - Down = 'ArrowDown', - Left = 'ArrowLeft', - Right = 'ArrowRight', -} - -const ARROW = 'Arrow'; - -/** - * @hidden - * This service should be decoupled from the days View Component and it should become global for the whole calendar navigation. - */ -@Injectable() -export class IgxDaysViewNavigationService { - public monthView: IgxDaysViewComponent; - /** - * Implements kb navigation in all MoveDirections. nextDate and nextMonthView naming convention is used for both previous/next - * @hidden - */ - public focusNextDate(target: HTMLElement, key: string, nextView = false) { - if (target.childElementCount === 0) { target = target.parentElement; } - if (key.indexOf('Arrow') === -1) { key = ARROW.concat(key); } - const monthView = this.monthView; - const node = monthView.dates.find((date) => date.nativeElement === target); - let dates = monthView.dates.toArray(), - day: IgxDayItemComponent, step, i, nextDate: Date; - const index = dates.indexOf(node); - - if (!node) { return; } - - // focus item in current month - switch (key) { - case Direction.Left: { - step = -1; - nextDate = this.timedelta(node.date.date, step); - for (i = index; i > 0; i--) { - day = nextView ? dates[i] : dates[i - 1]; - nextDate = day.date.date; - if (day.date.isPrevMonth) { - break; - } - if (day && day.isFocusable) { - day.nativeElement.focus(); - return; - } - } - break; - } - case Direction.Right: { - step = 1; - nextDate = this.timedelta(node.date.date, step); - for (i = index; i < dates.length - 1; i++) { - day = nextView ? dates[i] : dates[i + 1]; - nextDate = day.date.date; - if (day.date.isNextMonth) { - break; - } - if (day && day.isFocusable) { - day.nativeElement.focus(); - return; - } - } - break; - } - case Direction.Up: { - step = -7; - nextDate = this.timedelta(node.date.date, step); - for (i = index; i - 7 > -1; i -= 7) { - day = nextView ? dates[i] : dates[i - 7]; - nextDate = day.date.date; - if (day.date.isPrevMonth) { - break; - } - if (day && day.isFocusable) { - day.nativeElement.focus(); - return; - } - } - break; - } - case Direction.Down: { - step = 7; - nextDate = this.timedelta(node.date.date, step); - for (i = index; i + 7 < 42; i += 7) { - day = nextView ? dates[i] : dates[i + 7]; - nextDate = day.date.date; - if (day.date.isNextMonth) { - break; - } - if (day && day.isFocusable) { - day.nativeElement.focus(); - return; - } - } - break; - } - } - - // focus item in prev/next visible month - const nextMonthView = step > 0 ? monthView.nextMonthView : monthView.prevMonthView; - if (nextMonthView) { - dates = nextMonthView.dates.toArray(); - day = dates.find((item) => item.date.date.getTime() === nextDate.getTime()); - - if (day && day.isFocusable) { - day.nativeElement.focus(); - return; - } - nextMonthView.daysNavService.focusNextDate(day.nativeElement, key); - } - - // if iterating in the visible prev/next moths above found a day that is not focusable, ie is disabled, hidden, etc - // then it is needed to recalculate the next day, which is going to be part of the prev/next months - if (day && !day.isFocusable) { - day = dates[i + step]; - if (!day) { - nextDate = this.timedelta(node.date.date, step + i - index); - } - } - - // focus item in prev/next month, which is currently out of view - let dayIsNextMonth: boolean; // determine what we need to check for next date - if it belongs to prev or next month - if (day) { dayIsNextMonth = step > 0 ? day.date.isNextMonth : day.date.isPrevMonth; } - if (monthView.changeDaysView && !nextMonthView && ((day && dayIsNextMonth) || !day)) { - const monthAction = step > 0 ? ScrollMonth.NEXT : ScrollMonth.PREV; - monthView.onViewChanging.emit({monthAction: monthAction, key: key, nextDate: nextDate}); - } - } - - /** - * Focuses first focusable day in the month. Will go to next visible month, if no day in the first month is focusable - * @hidden - */ - public focusHomeDate() { - let monthView = this.monthView; - while (!this.focusFirstDay(monthView) && monthView.nextMonthView) { - monthView = monthView.nextMonthView; - } - } - - /** - * Focuses last focusable day in the month. Will go to previous visible month, if no day in the first month is focusable - * @hidden - */ - public focusEndDate() { - let monthView = this.monthView; - while (!this.focusLastDay(monthView) && monthView.prevMonthView) { - monthView = monthView.prevMonthView; - } - } - - private timedelta(date: Date, units: number): Date { - const ret = new Date(date); - ret.setDate(ret.getDate() + units); - return ret; - } - - private focusFirstDay(monthView: IgxDaysViewComponent): boolean { - const dates = monthView.dates.filter(d => d.isCurrentMonth); - for (let i = 0; i < dates.length; i++) { - if (dates[i].isFocusable) { - dates[i].nativeElement.focus(); - return true; - } - } - return false; - } - - private focusLastDay(monthView: IgxDaysViewComponent): boolean { - const dates = monthView.dates.filter(d => d.isCurrentMonth); - for (let i = dates.length - 1; i >= 0; i--) { - if (dates[i].isFocusable) { - dates[i].nativeElement.focus(); - return true; - } - } - return false; - } -} diff --git a/src/app/calendar-views/calendar-views.sample.html b/src/app/calendar-views/calendar-views.sample.html index 611bb6d48b0..d3e5b293e21 100644 --- a/src/app/calendar-views/calendar-views.sample.html +++ b/src/app/calendar-views/calendar-views.sample.html @@ -10,9 +10,11 @@

Month Picker

[formatViews]="formatViews" [formatOptions]="formatOptions" [locale]="localeDe" - (onSelection)="onSelection($event)"> + (onSelection)="onSelection($event)" + (onViewDateChanged)="onViewDateChanged($event)" + (onActiveViewChanged)="onActiveViewChanged($event)" > - + {{ date1 }} diff --git a/src/app/calendar-views/calendar-views.sample.ts b/src/app/calendar-views/calendar-views.sample.ts index d771d262c96..cdf43c90530 100644 --- a/src/app/calendar-views/calendar-views.sample.ts +++ b/src/app/calendar-views/calendar-views.sample.ts @@ -3,7 +3,8 @@ import { IgxCalendarComponent, DateRangeType, IgxDaysViewComponent, - IgxMonthPickerComponent + IgxMonthPickerComponent, + CalendarView } from 'igniteui-angular'; @Component({ @@ -99,4 +100,12 @@ export class CalendarViewsSampleComponent implements OnInit { this.daysView.deselectDate(new Date(2019, 1, 13)); // this.daysView.deselectDate([new Date(2019, 1, 13), new Date(2019, 1, 14)]); } + + public onViewDateChanged(event: Date) { + const date = event; + console.log(date); + } + + public onActiveViewChanged(event: CalendarView) { + } } diff --git a/src/app/calendar/calendar.sample.html b/src/app/calendar/calendar.sample.html index f61ed677203..88558788b7c 100644 --- a/src/app/calendar/calendar.sample.html +++ b/src/app/calendar/calendar.sample.html @@ -24,7 +24,7 @@

Default Calendar

- + diff --git a/src/app/calendar/calendar.sample.ts b/src/app/calendar/calendar.sample.ts index 937ad84d53c..405d10cc295 100644 --- a/src/app/calendar/calendar.sample.ts +++ b/src/app/calendar/calendar.sample.ts @@ -1,5 +1,7 @@ import { Component, OnInit, ViewChild } from '@angular/core'; -import { IgxCalendarComponent, DateRangeDescriptor, DateRangeType } from 'igniteui-angular'; +import { IgxCalendarComponent, DateRangeType, CalendarView } from 'igniteui-angular'; +import { IViewDateChangeEventArgs } from '../../../projects/igniteui-angular/src/lib/calendar/calendar-base'; +import { CalendarView } from '../../../projects/igniteui-angular/src/lib/calendar/public_api'; @Component({ selector: 'app-calendar-sample', @@ -36,6 +38,17 @@ export class CalendarSampleComponent implements OnInit { this.calendar.hideOutsideDays = !this.calendar.hideOutsideDays; } + public onSelection(event: Date) { + const date = event; + } + + public onViewDateChanged(event: IViewDateChangeEventArgs) { + console.log(event); + } + + public onActiveViewChanged(event: CalendarView) { + } + public setSelection(args: string) { this.calendar.selection = args; } From add8fc9f66db79cea79e1de977036b09de7445f8 Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Tue, 7 Jul 2020 10:20:21 +0300 Subject: [PATCH 19/53] test(calendar): respect viewDate is always 1 #7039 --- .../igniteui-angular/src/lib/calendar/README.md | 14 ++++++++++++-- .../src/lib/calendar/month-picker/README.md | 12 +++++++++++- .../month-picker/month-picker.component.spec.ts | 2 +- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/projects/igniteui-angular/src/lib/calendar/README.md b/projects/igniteui-angular/src/lib/calendar/README.md index 4a978e202fd..29da0cad44d 100644 --- a/projects/igniteui-angular/src/lib/calendar/README.md +++ b/projects/igniteui-angular/src/lib/calendar/README.md @@ -133,7 +133,7 @@ The calendar header will not be rendered when the selection is either `multi` or - `viewDate: Date` -Controls the year/month that will be presented in the default view when the calendar renders. By default it is the current year/month. +Controls the year/month that will be presented in the default view when the calendar renders. By default it is the first day of the current year/month. - `value: Date | Date[]` @@ -173,7 +173,17 @@ Controls the visibility of the dates that do not belong to the current month. - `onSelection(): Date | Date[]` Event fired when a value is selected through UI interaction. -Returns the selected value (depending on the type of selection). +Emits the selected value (depending on the type of selection). + +- `onViewDateChanged(): IViewDateChangeEventArgs` + +Event fired after the the month/year presented in the view is changed. +Emits an object containing the previous and current value of the `viewDate` property. + +- `onActiveViewChanged(): CalendarView` + +Event fired after the active view is changed. +Emits an CalendarView enum, indicating the `activeView` property value. ### Methods diff --git a/projects/igniteui-angular/src/lib/calendar/month-picker/README.md b/projects/igniteui-angular/src/lib/calendar/month-picker/README.md index afc9b262096..3dbed313ca0 100644 --- a/projects/igniteui-angular/src/lib/calendar/month-picker/README.md +++ b/projects/igniteui-angular/src/lib/calendar/month-picker/README.md @@ -88,7 +88,7 @@ The default value is `en`. - `viewDate: Date` -Controls the year/month that will be presented in the default view when the month picker renders. By default it is the current year/month. +Controls the year/month that will be presented in the default view when the month picker renders. By default it is the first day of the current year/month. - `value: Date` @@ -121,3 +121,13 @@ The default values are listed below. Event fired when a value is selected through UI interaction. Returns the selected value (depending on the type of selection). + +- `onViewDateChanged(): IViewDateChangeEventArgs` + +Event fired after the the month/year presented in the view is changed. +Emits an object containing the previous and current value of the `viewDate` property. + +- `onActiveViewChanged(): CalendarView` + +Event fired after the active view is changed. +Emits an CalendarView enum, indicating the `activeView` property value. diff --git a/projects/igniteui-angular/src/lib/calendar/month-picker/month-picker.component.spec.ts b/projects/igniteui-angular/src/lib/calendar/month-picker/month-picker.component.spec.ts index c5b0b3285e2..f44ee167970 100644 --- a/projects/igniteui-angular/src/lib/calendar/month-picker/month-picker.component.spec.ts +++ b/projects/igniteui-angular/src/lib/calendar/month-picker/month-picker.component.spec.ts @@ -76,7 +76,7 @@ describe('IgxMonthPicker', () => { }; expect(monthPicker.value).toBeUndefined(); - expect(monthPicker.viewDate.getDate()).toEqual(instance.viewDate.getDate()); + expect(monthPicker.viewDate.getDate()).toEqual(1); expect(monthPicker.locale).toEqual('en'); const today = new Date(Date.now()); From 037a14641c934cb9aa7c3e9a4c3e577571683ab7 Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Tue, 7 Jul 2020 17:25:26 +0300 Subject: [PATCH 20/53] feat(calendar): emit event from animationDon #7039 --- .../src/lib/calendar/calendar.component.html | 6 +-- .../src/lib/calendar/calendar.component.ts | 39 ++++++++-------- .../src/lib/calendar/month-picker-base.ts | 12 ++--- .../month-picker/month-picker.component.html | 7 +-- .../month-picker/month-picker.component.ts | 45 +++++++++---------- 5 files changed, 53 insertions(+), 56 deletions(-) diff --git a/projects/igniteui-angular/src/lib/calendar/calendar.component.html b/projects/igniteui-angular/src/lib/calendar/calendar.component.html index eb77d8c740b..73b895eac7f 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar.component.html +++ b/projects/igniteui-angular/src/lib/calendar/calendar.component.html @@ -22,7 +22,7 @@

-
- (onSelection)="changeMonth($event)"> - { - this.onViewDateChanged.emit({ previousValue, currentValue: this.viewDate }); - }); } /** @@ -482,13 +479,10 @@ export class IgxCalendarComponent extends IgxMonthPickerBaseDirective implements * @internal */ public nextMonth(isKeydownTrigger = false) { - const previousValue = this.viewDate; + this.previousViewDate = this.viewDate; this.viewDate = this.calendarModel.getNextMonth(this.viewDate); this.animationAction = ScrollMonth.NEXT; this.isKeydownTrigger = isKeydownTrigger; - requestAnimationFrame(() => { - this.onViewDateChanged.emit({ previousValue, currentValue: this.viewDate }); - }); } /** @@ -617,9 +611,8 @@ export class IgxCalendarComponent extends IgxMonthPickerBaseDirective implements if (day) { this.daysView.daysNavService.focusNextDate(day.nativeElement, args.key, true); } - this.onViewDateChanged.emit({previousValue, currentValue: this.viewDate}); }; - const previousValue = this.viewDate; + this.previousViewDate = this.viewDate; this.viewDate = this.nextDate; } @@ -628,15 +621,13 @@ export class IgxCalendarComponent extends IgxMonthPickerBaseDirective implements * @intenal */ public changeMonth(event: Date) { - const previousValue = this.viewDate; + this.previousViewDate = this.viewDate; this.viewDate = this.calendarModel.getFirstViewDate(event, 'month', this.activeViewIdx); this.activeView = CalendarView.DEFAULT; requestAnimationFrame(() => { const elem = this.monthsBtns.find((e: ElementRef, idx: number) => idx === this.activeViewIdx); if (elem) { elem.nativeElement.focus(); } - this.onViewDateChanged.emit({previousValue, currentValue: this.viewDate}); - this.onActiveViewChanged.emit(this.activeView); }); } @@ -650,7 +641,6 @@ export class IgxCalendarComponent extends IgxMonthPickerBaseDirective implements requestAnimationFrame(() => { this.monthsView.date = args; this.focusMonth(event.target); - this.onActiveViewChanged.emit(this.activeView); }); } @@ -725,6 +715,11 @@ export class IgxCalendarComponent extends IgxMonthPickerBaseDirective implements * @internal */ public animationDone(event) { + if ((event.fromState === ScrollMonth.NONE && (event.toState === ScrollMonth.PREV || event.toState === ScrollMonth.NEXT)) || + (event.fromState === 'void' && event.toState === ScrollMonth.NONE)) { + this.onViewDateChanged.emit({ previousValue: this.previousViewDate, currentValue: this.viewDate }); + } + if (this.monthScrollDirection !== ScrollMonth.NONE) { this.scrollMonth$.next(); } @@ -750,6 +745,16 @@ export class IgxCalendarComponent extends IgxMonthPickerBaseDirective implements this.animationAction = ScrollMonth.NONE; } + /** + * @hidden + * @internal + */ + public viewRendered(event) { + if (event.fromState !== 'void') { + this.onActiveViewChanged.emit(this.activeView); + } + } + /** * Keyboard navigation of the calendar * @hidden @@ -827,7 +832,7 @@ export class IgxCalendarComponent extends IgxMonthPickerBaseDirective implements const isPageDown = event.key === 'PageDown'; const step = isPageDown ? 1 : -1; - const previousValue = this.viewDate; + this.previousViewDate = this.viewDate; this.viewDate = this.calendarModel.timedelta(this.viewDate, 'year', step); this.animationAction = isPageDown ? ScrollMonth.NEXT : ScrollMonth.PREV; @@ -864,10 +869,6 @@ export class IgxCalendarComponent extends IgxMonthPickerBaseDirective implements if (dayItem && dayItem.isFocusable) { dayItem.nativeElement.focus(); } }; } - - requestAnimationFrame(() => { - this.onViewDateChanged.emit({previousValue, currentValue: this.viewDate}); - }); } /** diff --git a/projects/igniteui-angular/src/lib/calendar/month-picker-base.ts b/projects/igniteui-angular/src/lib/calendar/month-picker-base.ts index 323e7623f29..24150ce16f0 100644 --- a/projects/igniteui-angular/src/lib/calendar/month-picker-base.ts +++ b/projects/igniteui-angular/src/lib/calendar/month-picker-base.ts @@ -35,6 +35,11 @@ export class IgxMonthPickerBaseDirective extends IgxCalendarBaseDirective { @ViewChildren('yearsBtn') public yearsBtns: QueryList; + /** + * @hidden @internal + */ + public previousViewDate: Date; + @Input() /** @@ -83,7 +88,7 @@ export class IgxMonthPickerBaseDirective extends IgxCalendarBaseDirective { * @hidden */ public changeYear(event: Date) { - const previousValue = this.viewDate; + this.previousViewDate = this.viewDate; this.viewDate = this.calendarModel.getFirstViewDate(event, 'month', this.activeViewIdx); this.activeView = CalendarView.DEFAULT; @@ -91,8 +96,6 @@ export class IgxMonthPickerBaseDirective extends IgxCalendarBaseDirective { if (this.yearsBtns && this.yearsBtns.length) { this.yearsBtns.find((e: ElementRef, idx: number) => idx === this.activeViewIdx).nativeElement.focus(); } - this.onViewDateChanged.emit({ previousValue, currentValue: this.viewDate }); - this.onActiveViewChanged.emit(this.activeView); }); } @@ -102,9 +105,6 @@ export class IgxMonthPickerBaseDirective extends IgxCalendarBaseDirective { public activeViewDecade(activeViewIdx = 0): void { this.activeView = CalendarView.DECADE; this.activeViewIdx = activeViewIdx; - requestAnimationFrame(() => { - this.onActiveViewChanged.emit(this.activeView); - }); } /** diff --git a/projects/igniteui-angular/src/lib/calendar/month-picker/month-picker.component.html b/projects/igniteui-angular/src/lib/calendar/month-picker/month-picker.component.html index 11c40c1c4a7..1ef703e88e5 100644 --- a/projects/igniteui-angular/src/lib/calendar/month-picker/month-picker.component.html +++ b/projects/igniteui-angular/src/lib/calendar/month-picker/month-picker.component.html @@ -1,4 +1,4 @@ -
+
- { if (this.dacadeView) { this.dacadeView.el.nativeElement.focus(); } - this.onActiveViewChanged.emit(this.activeView); }); } @@ -141,15 +154,11 @@ export class IgxMonthPickerComponent extends IgxMonthPickerBaseDirective { */ public nextYear() { this.yearAction = 'next'; - const previousValue = this.viewDate; + this.previousViewDate = this.viewDate; this.viewDate = this.calendarModel.getNextYear(this.viewDate); this.selectDate(this.viewDate); this.onSelection.emit(this.selectedDates); - - requestAnimationFrame(() => { - this.onViewDateChanged.emit({ previousValue, currentValue: this.viewDate }); - }); } /** @@ -169,15 +178,11 @@ export class IgxMonthPickerComponent extends IgxMonthPickerBaseDirective { */ public previousYear() { this.yearAction = 'prev'; - const previousValue = this.viewDate; + this.previousViewDate = this.viewDate; this.viewDate = this.calendarModel.getPrevYear(this.viewDate); this.selectDate(this.viewDate); this.onSelection.emit(this.selectedDates); - - requestAnimationFrame(() => { - this.onViewDateChanged.emit({ previousValue, currentValue: this.viewDate }); - }); } /** @@ -196,7 +201,7 @@ export class IgxMonthPickerComponent extends IgxMonthPickerBaseDirective { * @hidden */ public selectYear(event: Date) { - const previousValue = this.viewDate; + this.previousViewDate = this.viewDate; this.viewDate = new Date(event.getFullYear(), event.getMonth(), event.getDate()); this.activeView = CalendarView.DEFAULT; @@ -205,8 +210,6 @@ export class IgxMonthPickerComponent extends IgxMonthPickerBaseDirective { requestAnimationFrame(() => { if (this.yearsBtn) { this.yearsBtn.nativeElement.focus(); } - this.onViewDateChanged.emit({ previousValue, currentValue: this.viewDate }); - this.onActiveViewChanged.emit(this.activeView); }); } @@ -252,12 +255,8 @@ export class IgxMonthPickerComponent extends IgxMonthPickerBaseDirective { public onKeydownPageUp(event: KeyboardEvent) { event.preventDefault(); this.yearAction = 'prev'; - const previousValue = this.viewDate; + this.previousViewDate = this.viewDate; this.viewDate = this.calendarModel.getPrevYear(this.viewDate); - - requestAnimationFrame(() => { - this.onViewDateChanged.emit({ previousValue, currentValue: this.viewDate }); - }); } /** @@ -267,12 +266,8 @@ export class IgxMonthPickerComponent extends IgxMonthPickerBaseDirective { public onKeydownPageDown(event: KeyboardEvent) { event.preventDefault(); this.yearAction = 'next'; - const previousValue = this.viewDate; + this.previousViewDate = this.viewDate; this.viewDate = this.calendarModel.getNextYear(this.viewDate); - - requestAnimationFrame(() => { - this.onViewDateChanged.emit({ previousValue, currentValue: this.viewDate }); - }); } /** From 74eb9fa7ba6590586e3d760beae0566810b73db2 Mon Sep 17 00:00:00 2001 From: Simeon Simeonoff Date: Wed, 8 Jul 2020 10:27:43 +0300 Subject: [PATCH 21/53] fix(input-group): textarea has incorrect line-height --- .../components/input/_input-group-theme.scss | 16 +++++++++++++--- src/app/input/input.sample.html | 5 +++++ src/app/input/input.sample.ts | 7 +++++-- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/projects/igniteui-angular/src/lib/core/styles/components/input/_input-group-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/input/_input-group-theme.scss index b568cbef288..2e6218d6bff 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/input/_input-group-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/input/_input-group-theme.scss @@ -961,12 +961,22 @@ } %form-group-textarea { - min-height: rem(82px, map-get($base-scale-size, 'comfortable')); /* 3 lines * 22px + 8px bottom padding + 8px top padding */ - margin-#{$right}: -#{rem(16px, map-get($base-scale-size, 'comfortable'))}; /* this fixes resizing in chrome !?!? */ - line-height: normal !important; /* resets typography styles */ + // 3 lines * 22px + 8px bottom padding + 8px top padding + min-height: rem(82px, map-get($base-scale-size, 'comfortable')); + + // this fixes resizing in chrome !?!? + margin-#{$right}: -#{rem(16px, map-get($base-scale-size, 'comfortable'))}; + height: auto; resize: vertical; overflow: hidden; + + // resets typography styles + line-height: normal !important; + + &:not([type='*']) { + line-height: normal !important; /* resets typography styles */ + } } %form-group-textarea--cosy { diff --git a/src/app/input/input.sample.html b/src/app/input/input.sample.html index e86596d0ebb..b97236aecd0 100644 --- a/src/app/input/input.sample.html +++ b/src/app/input/input.sample.html @@ -19,6 +19,11 @@

Personal Info

+ + + + + diff --git a/src/app/input/input.sample.ts b/src/app/input/input.sample.ts index ae88b988b15..5164963a5b2 100644 --- a/src/app/input/input.sample.ts +++ b/src/app/input/input.sample.ts @@ -15,7 +15,8 @@ export class InputSampleComponent { lastName: 'Doe', password: '1337s3cr3t', registered: false, - subscribed: false + subscribed: false, + dateOfBirth: new Date('07 July, 1987') }; user2 = { @@ -25,9 +26,11 @@ export class InputSampleComponent { lastName: 'Doe', password: '1337s3cr3t', registered: true, - subscribed: false + subscribed: false, + dateOfBirth: new Date('01 July, 1954') }; + settings = [{ name: 'WiFi', icon: 'wifi', From e747ab5953d2b7592266baf19bfe6f3b35c8f4f7 Mon Sep 17 00:00:00 2001 From: Radoslav Mirchev <52001020+radomirchev@users.noreply.github.com> Date: Wed, 8 Jul 2020 13:39:10 +0300 Subject: [PATCH 22/53] (*) chore Update Milestone 12 --- ROADMAP.md | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/ROADMAP.md b/ROADMAP.md index c86e3f48a42..f8e81ca290d 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -2,12 +2,29 @@ # Current Milestone -## Milestone 12 (Due by August, 2020) +## Milestone 12 (Due by August 17th, 2020) -1. Accept ISO 8601 Date-only string as input for igx-calendar and igx-datepicker [#6994](https://github.com/IgniteUI/igniteui-angular/issues/6994) +1. igx-grid improve IGridEditEventArgs [#4965](https://github.com/IgniteUI/igniteui-angular/issues/4965) 2. igxCombo has to include caseSensitive property in filter search [#7282](https://github.com/IgniteUI/igniteui-angular/issues/7282) 3. igxCombo default positioning strategy [#7225](https://github.com/IgniteUI/igniteui-angular/issues/7225) -To Be Updated +4. igxSelect Add igxHint support [#5584](https://github.com/IgniteUI/igniteui-angular/issues/5584) +5. igxGrid Hide the group area row [#5561](https://github.com/IgniteUI/igniteui-angular/issues/5561) +6. igxDateRangePickerComponent calendar should display selected range if both start and end are filled and valid [#7593](https://github.com/IgniteUI/igniteui-angular/issues/7593) +7. Add support for mixing px and % column widths [#5486](https://github.com/IgniteUI/igniteui-angular/issues/5486) +8. Do not close modal overlay on ESC key press [#7697](https://github.com/IgniteUI/igniteui-angular/issues/7697) +9. Themes: Add Dock Manager Support [#7541](https://github.com/IgniteUI/igniteui-angular/issues/7541) +10. igx-grid - pre-select rows [#6653](https://github.com/IgniteUI/igniteui-angular/issues/6653) +11. Average and Sum are shown on the Ship country level [#7334](https://github.com/IgniteUI/igniteui-angular/issues/7334) +12. Dock Manager Better Default Themes [#7578](https://github.com/IgniteUI/igniteui-angular/issues/7578) +13. Expose templates for all ESF UI parts [#7221](https://github.com/IgniteUI/igniteui-angular/issues/7221) +14. Calendar events when user changes month/year [#7039](https://github.com/IgniteUI/igniteui-angular/issues/7039) +15. igxGrid default column display templates per-type [#7224](https://github.com/IgniteUI/igniteui-angular/issues/7224) +16. Provide "Unfreeze All" option under Freeze button on Data Grid & Tree Grid +To Be Updated [#6549](https://github.com/IgniteUI/igniteui-angular/issues/6549) +17. Exposing onActiveNodeChange output in the Grid [#7601](https://github.com/IgniteUI/igniteui-angular/issues/7601) +18. Refactor commit method of IgxHierarchicalTransactionService to accept same parameters as base type [#5205](https://github.com/IgniteUI/igniteui-angular/issues/5205) +19. Tooltip for grid cell text content [#6215](https://github.com/IgniteUI/igniteui-angular/issues/6215) +20. Add tooltip to column summary [#6505](https://github.com/IgniteUI/igniteui-angular/issues/6505) ## Going down the road From 1c9733c98786c629dd2ac63073eb54b95b499222 Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Wed, 8 Jul 2020 17:15:21 +0300 Subject: [PATCH 23/53] chore(calendar): fix sample update changelog #7039 --- CHANGELOG.md | 5 ++ .../lib/calendar/calendar.component.spec.ts | 69 ++++++++++++++++--- src/app/calendar/calendar.sample.ts | 1 - 3 files changed, 63 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index efb8d7e5da9..a654dbda974 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,11 @@ All notable changes for each version of this project will be documented in this - Removed `onDataPreLoad` event as it is specific for remote virtualization implementation, which is not supported for the `igxTreeGrid`. A more generic `onScroll` event is exposed and can be used instead. ### New Features +- `IgxCalendar` and `IgxMonthPicker` + - `onViewDateChanged` emitted after the month/year presented in the view is changed after user interaction. + - `onActiveViewChanged` event emitted after the active view (DEFAULT, YEAR, DECADE) is changed after user interaction. + - `viewDate` day value is always 1. + - `activeView` setter is now available as an input property. - `IgxGridState` directive - Added support for expansion states, column selection and row pinning. - Added support for `IgxTreeGrid` and `IgxHierarchicalGrid` (including child grids) diff --git a/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts b/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts index 2e8ed531649..460a2f90701 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts +++ b/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts @@ -7,14 +7,16 @@ import { Calendar, IgxCalendarComponent, IgxCalendarModule, isLeap, monthRange, weekDay, WEEKDAYS } from './public_api'; -import { UIInteractions } from '../test-utils/ui-interactions.spec'; +import { UIInteractions, wait } from '../test-utils/ui-interactions.spec'; import { DateRangeDescriptor, DateRangeType } from '../core/dates/dateRange'; import { configureTestSuite } from '../test-utils/configure-suite'; import { IgxDayItemComponent } from './days-view/day-item.component'; import { HelperTestFunctions } from './calendar-helper-utils'; +import { CalendarView } from './month-picker-base'; +import { IViewDateChangeEventArgs } from './calendar-base'; -describe('IgxCalendar - ', () => { +fdescribe('IgxCalendar - ', () => { it('Should create proper calendar model', () => { const calendar = new Calendar(); @@ -1554,41 +1556,66 @@ describe('IgxCalendar - ', () => { dom = fixture.debugElement; })); - it('Should navigate to the previous/next month via KB.', fakeAsync(() => { + fit('Should navigate to the previous/next month via KB.', fakeAsync(() => { + fixture.detectChanges(); + const next = dom.queryAll(By.css(HelperTestFunctions.CALENDAR_NEXT_BUTTON_CSSCLASS))[0]; const prev = dom.queryAll(By.css(HelperTestFunctions.CALENDAR_PREV_BUTTON_CSSCLASS))[0]; + + let previousValue = fixture.componentInstance.calendar.viewDate; prev.nativeElement.focus(); + spyOn(calendar.onViewDateChanged, 'emit').and.callThrough(); expect(prev.nativeElement).toBe(document.activeElement); UIInteractions.triggerKeyDownEvtUponElem('Enter', prev.nativeElement); - tick(100); fixture.detectChanges(); + const tt = flush(); + tick(100); + let eventArgs: IViewDateChangeEventArgs = { previousValue, currentValue: fixture.componentInstance.calendar.viewDate }; + expect(calendar.onViewDateChanged.emit).toHaveBeenCalledTimes(1); + expect(calendar.onViewDateChanged.emit).toHaveBeenCalledWith(eventArgs); expect(calendar.viewDate.getMonth()).toEqual(4); - const next = dom.queryAll(By.css(HelperTestFunctions.CALENDAR_NEXT_BUTTON_CSSCLASS))[0]; next.nativeElement.focus(); + previousValue = fixture.componentInstance.calendar.viewDate; expect(next.nativeElement).toBe(document.activeElement); UIInteractions.triggerKeyDownEvtUponElem('Enter', next.nativeElement); - tick(100); + fixture.detectChanges(); + tick(100); + eventArgs = { previousValue, currentValue: fixture.componentInstance.calendar.viewDate }; + expect(calendar.onViewDateChanged.emit).toHaveBeenCalledTimes(1); + expect(calendar.onViewDateChanged.emit).toHaveBeenCalledWith(eventArgs); + + previousValue = fixture.componentInstance.calendar.viewDate; UIInteractions.triggerKeyDownEvtUponElem('Enter', next.nativeElement); - tick(100); + fixture.detectChanges(); + tick(100); + eventArgs = { previousValue, currentValue: fixture.componentInstance.calendar.viewDate }; + expect(calendar.onViewDateChanged.emit).toHaveBeenCalledTimes(1); + expect(calendar.onViewDateChanged.emit).toHaveBeenCalledWith(eventArgs); expect(calendar.viewDate.getMonth()).toEqual(6); })); - it('Should open years view, navigate through and select an year via KB.', () => { + it('Should open years view, navigate through and select an year via KB.', fakeAsync(() => { const year = dom.queryAll(By.css(HelperTestFunctions.CALENDAR_DATE_CSSCLASS))[1]; year.nativeElement.focus(); expect(year.nativeElement).toBe(document.activeElement); + spyOn(calendar.onActiveViewChanged, 'emit').and.callThrough(); + UIInteractions.triggerKeyDownEvtUponElem('Enter', document.activeElement); fixture.detectChanges(); + tick(); + + expect(calendar.onActiveViewChanged.emit).toHaveBeenCalledTimes(1); + expect(calendar.onActiveViewChanged.emit).toHaveBeenCalledWith(CalendarView.DECADE); const years = dom.queryAll(By.css(HelperTestFunctions.YEAR_CSSCLASS)); let currentYear = dom.query(By.css(HelperTestFunctions.CURRENT_YEAR_CSSCLASS)); @@ -1609,20 +1636,33 @@ describe('IgxCalendar - ', () => { currentYear = dom.query(By.css(HelperTestFunctions.CURRENT_YEAR_CSSCLASS)); expect(currentYear.nativeElement.textContent.trim()).toMatch('2016'); + const previousValue = fixture.componentInstance.calendar.viewDate; + spyOn(calendar.onViewDateChanged, 'emit').and.callThrough(); + UIInteractions.triggerKeyDownEvtUponElem('Enter', currentYear.nativeElement); + fixture.detectChanges(); + tick(); + const eventArgs: IViewDateChangeEventArgs = { previousValue, currentValue: fixture.componentInstance.calendar.viewDate }; + expect(calendar.onViewDateChanged.emit).toHaveBeenCalledTimes(1); + expect(calendar.onViewDateChanged.emit).toHaveBeenCalledWith(eventArgs); expect(calendar.viewDate.getFullYear()).toEqual(2016); - }); + })); - it('Should open months view, navigate through and select a month via KB.', () => { + it('Should open months view, navigate through and select a month via KB.', fakeAsync(() => { const month = dom.queryAll(By.css(HelperTestFunctions.CALENDAR_DATE_CSSCLASS))[0]; month.nativeElement.focus(); + spyOn(calendar.onActiveViewChanged, 'emit').and.callThrough(); expect(month.nativeElement).toBe(document.activeElement); UIInteractions.triggerKeyDownEvtUponElem('Enter', document.activeElement); fixture.detectChanges(); + tick(); + + expect(calendar.onActiveViewChanged.emit).toHaveBeenCalledTimes(1); + expect(calendar.onActiveViewChanged.emit).toHaveBeenCalledWith(CalendarView.YEAR); const months = dom.queryAll(By.css(HelperTestFunctions.MONTH_CSSCLASS)); const currentMonth = dom.query(By.css(HelperTestFunctions.CURRENT_MONTH_CSSCLASS)); @@ -1651,11 +1691,18 @@ describe('IgxCalendar - ', () => { expect(document.activeElement.textContent.trim()).toMatch('Sep'); + const previousValue = fixture.componentInstance.calendar.viewDate; + spyOn(calendar.onViewDateChanged, 'emit').and.callThrough(); + UIInteractions.triggerKeyDownEvtUponElem('Enter', document.activeElement); fixture.detectChanges(); + tick(); + const eventArgs: IViewDateChangeEventArgs = { previousValue, currentValue: fixture.componentInstance.calendar.viewDate }; + expect(calendar.onViewDateChanged.emit).toHaveBeenCalledTimes(1); + expect(calendar.onViewDateChanged.emit).toHaveBeenCalledWith(eventArgs); expect(calendar.viewDate.getMonth()).toEqual(8); - }); + })); it('Should navigate to the first enabled date from the previous month when using "arrow up" key.', fakeAsync(() => { const dateRangeDescriptors: DateRangeDescriptor[] = []; diff --git a/src/app/calendar/calendar.sample.ts b/src/app/calendar/calendar.sample.ts index 405d10cc295..708d49cf4d7 100644 --- a/src/app/calendar/calendar.sample.ts +++ b/src/app/calendar/calendar.sample.ts @@ -1,7 +1,6 @@ import { Component, OnInit, ViewChild } from '@angular/core'; import { IgxCalendarComponent, DateRangeType, CalendarView } from 'igniteui-angular'; import { IViewDateChangeEventArgs } from '../../../projects/igniteui-angular/src/lib/calendar/calendar-base'; -import { CalendarView } from '../../../projects/igniteui-angular/src/lib/calendar/public_api'; @Component({ selector: 'app-calendar-sample', From ab21765f2700922261b7eb34f9ea48af1c9e2c01 Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Wed, 8 Jul 2020 17:25:01 +0300 Subject: [PATCH 24/53] test(calendar): revert test #7039 --- .../lib/calendar/calendar.component.spec.ts | 32 ++++--------------- 1 file changed, 6 insertions(+), 26 deletions(-) diff --git a/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts b/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts index 460a2f90701..fe60587e978 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts +++ b/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts @@ -16,7 +16,7 @@ import { HelperTestFunctions } from './calendar-helper-utils'; import { CalendarView } from './month-picker-base'; import { IViewDateChangeEventArgs } from './calendar-base'; -fdescribe('IgxCalendar - ', () => { +describe('IgxCalendar - ', () => { it('Should create proper calendar model', () => { const calendar = new Calendar(); @@ -1556,49 +1556,29 @@ fdescribe('IgxCalendar - ', () => { dom = fixture.debugElement; })); - fit('Should navigate to the previous/next month via KB.', fakeAsync(() => { - fixture.detectChanges(); - const next = dom.queryAll(By.css(HelperTestFunctions.CALENDAR_NEXT_BUTTON_CSSCLASS))[0]; + it('Should navigate to the previous/next month via KB.', fakeAsync(() => { const prev = dom.queryAll(By.css(HelperTestFunctions.CALENDAR_PREV_BUTTON_CSSCLASS))[0]; - - let previousValue = fixture.componentInstance.calendar.viewDate; prev.nativeElement.focus(); - spyOn(calendar.onViewDateChanged, 'emit').and.callThrough(); expect(prev.nativeElement).toBe(document.activeElement); - UIInteractions.triggerKeyDownEvtUponElem('Enter', prev.nativeElement); - fixture.detectChanges(); - const tt = flush(); tick(100); + fixture.detectChanges(); - let eventArgs: IViewDateChangeEventArgs = { previousValue, currentValue: fixture.componentInstance.calendar.viewDate }; - expect(calendar.onViewDateChanged.emit).toHaveBeenCalledTimes(1); - expect(calendar.onViewDateChanged.emit).toHaveBeenCalledWith(eventArgs); expect(calendar.viewDate.getMonth()).toEqual(4); - + const next = dom.queryAll(By.css(HelperTestFunctions.CALENDAR_NEXT_BUTTON_CSSCLASS))[0]; next.nativeElement.focus(); - previousValue = fixture.componentInstance.calendar.viewDate; expect(next.nativeElement).toBe(document.activeElement); UIInteractions.triggerKeyDownEvtUponElem('Enter', next.nativeElement); fixture.detectChanges(); tick(100); - - eventArgs = { previousValue, currentValue: fixture.componentInstance.calendar.viewDate }; - expect(calendar.onViewDateChanged.emit).toHaveBeenCalledTimes(1); - expect(calendar.onViewDateChanged.emit).toHaveBeenCalledWith(eventArgs); - - previousValue = fixture.componentInstance.calendar.viewDate; UIInteractions.triggerKeyDownEvtUponElem('Enter', next.nativeElement); - - fixture.detectChanges(); tick(100); + fixture.detectChanges(); + - eventArgs = { previousValue, currentValue: fixture.componentInstance.calendar.viewDate }; - expect(calendar.onViewDateChanged.emit).toHaveBeenCalledTimes(1); - expect(calendar.onViewDateChanged.emit).toHaveBeenCalledWith(eventArgs); expect(calendar.viewDate.getMonth()).toEqual(6); })); From 03ae3713f1ec61e0785080c60f616e739847e379 Mon Sep 17 00:00:00 2001 From: Simeon Simeonoff Date: Thu, 9 Jul 2020 10:00:39 +0300 Subject: [PATCH 25/53] docs(themes): add active color to dock-manager theme docs --- .../core/styles/components/dock-manager/_dock-manager-theme.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/projects/igniteui-angular/src/lib/core/styles/components/dock-manager/_dock-manager-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/dock-manager/_dock-manager-theme.scss index d088072566a..76c8d3b8c77 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/dock-manager/_dock-manager-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/dock-manager/_dock-manager-theme.scss @@ -10,6 +10,7 @@ /// @param {Map} $schema [$light-schema] - The schema used as basis for styling the component. /// /// @param {Color} $accent-color [null] - Sets the pinned header background color, the joystick background and border colors, as well as the context menu background color. +/// @param {Color} $active-color [null] - Sets the active text and border colors for tabs, panes, and menus. /// @param {Color} $border-color [null] - Sets the global border color in the dock manager. Also sets the pane content background and the context menu active background colors. /// @param {Color} $button-text [null] - Sets the button text color. /// @param {Color} $context-menu-background [null] - Sets the background color for context menus. From 80c805b2de1a9e7bc9b70c738484609d1fe6bf55 Mon Sep 17 00:00:00 2001 From: Desislava Dincheva <34240583+ddincheva@users.noreply.github.com> Date: Thu, 9 Jul 2020 10:05:08 +0300 Subject: [PATCH 26/53] Allow to show/hide summary row when the group/parent row is collapsed (#7750) * feat(grid): Allow to show/hide summary row when the group/parent row is collapsed Co-authored-by: Zdravko Kolev --- CHANGELOG.md | 2 + .../src/lib/grids/grid-base.directive.ts | 21 ++++ .../src/lib/grids/grid/grid-summary.spec.ts | 106 ++++++++++++++++++ .../src/lib/grids/grid/grid.component.html | 2 +- .../src/lib/grids/grid/grid.summary.pipe.ts | 19 +++- .../tree-grid/tree-grid-summaries.spec.ts | 93 +++++++++++++++ .../grids/tree-grid/tree-grid.component.html | 2 +- .../grids/tree-grid/tree-grid.summary.pipe.ts | 20 +++- src/app/grid-groupby/grid-groupby.sample.html | 6 +- src/app/grid-groupby/grid-groupby.sample.ts | 7 +- .../tree-grid-flat-data.sample.html | 1 + 11 files changed, 266 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index efb8d7e5da9..94c24c6c0cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,8 @@ All notable changes for each version of this project will be documented in this - Removed `onDataPreLoad` event as it is specific for remote virtualization implementation, which is not supported for the `igxTreeGrid`. A more generic `onScroll` event is exposed and can be used instead. ### New Features +- `IgxGrid`, `IgxTreeGrid`, `IgxHierarchicalGrid` + - Introduced `showSummaryOnCollapse` grid property which allows you to control whether the summary row stays visible when the groupBy / parent row is collapsed. - `IgxGridState` directive - Added support for expansion states, column selection and row pinning. - Added support for `IgxTreeGrid` and `IgxHierarchicalGrid` (including child grids) diff --git a/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts b/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts index 9d15266e02f..f456aaff4bb 100644 --- a/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts +++ b/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts @@ -1026,6 +1026,26 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements } } + /** + * Controls whether the summary row is visible when groupBy/parent row is collapsed. + * @example + * ```html + * + * ``` + * @remarks + * By default showSummaryOnCollapse is set to 'false' which means that the summary row is not visible + * when the groupBy/parent row is collapsed. + */ + @Input() + get showSummaryOnCollapse() { + return this._showSummaryOnCollapse; + } + + set showSummaryOnCollapse(value: boolean) { + this._showSummaryOnCollapse = value; + this.notifyChanges(); + } + /** * Gets/Sets the filtering strategy of the grid. * @example @@ -2625,6 +2645,7 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements private _summaryPosition = GridSummaryPosition.bottom; private _summaryCalculationMode = GridSummaryCalculationMode.rootAndChildLevels; + private _showSummaryOnCollapse = false; private _cellSelectionMode = GridSelectionMode.multiple; private _rowSelectionMode = GridSelectionMode.none; private _columnSelectionMode = GridSelectionMode.none; diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid-summary.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/grid-summary.spec.ts index 8fb65735aa6..8bcb989a43b 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid-summary.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/grid-summary.spec.ts @@ -1759,6 +1759,112 @@ describe('IgxGrid - Summaries #grid', () => { expect(GridSummaryFunctions.getAllVisibleSummariesLength(fix)).toEqual(5); }); + it('should show summaries when group row is collapsed', () => { + expect(grid.showSummaryOnCollapse).toBe(false); + expect(GridSummaryFunctions.getAllVisibleSummariesLength(fix)).toEqual(3); + const groupRows = grid.groupsRowList.toArray(); + grid.showSummaryOnCollapse = true; + fix.detectChanges(); + + groupRows[0].toggle(); + fix.detectChanges(); + + expect(groupRows[0].expanded).toBe(false); + expect(GridSummaryFunctions.getAllVisibleSummariesLength(fix)).toEqual(4); + let summaryRow = GridSummaryFunctions.getSummaryRowByDataRowIndex(fix, 1); + GridSummaryFunctions.verifyColumnSummaries(summaryRow, 1, ['Count', 'Min', 'Max', 'Sum', 'Avg'], ['2', '17', '17', '34', '17']); + GridSummaryFunctions.verifyColumnSummaries(summaryRow, 2, ['Count'], ['2']); + GridSummaryFunctions.verifyColumnSummaries(summaryRow, 3, + ['Count', 'Earliest', 'Latest'], ['2', 'Dec 18, 2007', 'Mar 19, 2016']); + + groupRows[0].toggle(); + fix.detectChanges(); + + expect(groupRows[0].expanded).toBe(true); + expect(GridSummaryFunctions.getAllVisibleSummariesLength(fix)).toEqual(3); + summaryRow = GridSummaryFunctions.getSummaryRowByDataRowIndex(fix, 3); + GridSummaryFunctions.verifyColumnSummaries(summaryRow, 1, ['Count', 'Min', 'Max', 'Sum', 'Avg'], ['2', '17', '17', '34', '17']); + GridSummaryFunctions.verifyColumnSummaries(summaryRow, 2, ['Count'], ['2']); + GridSummaryFunctions.verifyColumnSummaries(summaryRow, 3, + ['Count', 'Earliest', 'Latest'], ['2', 'Dec 18, 2007', 'Mar 19, 2016']); + }); + + it('should be able to change showSummaryOnCollapse run time', () => { + expect(grid.showSummaryOnCollapse).toBe(false); + expect(GridSummaryFunctions.getAllVisibleSummariesLength(fix)).toEqual(3); + const groupRows = grid.groupsRowList.toArray(); + fix.detectChanges(); + + groupRows[0].toggle(); + fix.detectChanges(); + + expect(groupRows[0].expanded).toBe(false); + expect(GridSummaryFunctions.getAllVisibleSummariesLength(fix)).toEqual(3); + + grid.showSummaryOnCollapse = true; + fix.detectChanges(); + + expect(grid.showSummaryOnCollapse).toBe(true); + expect(GridSummaryFunctions.getAllVisibleSummariesLength(fix)).toEqual(4); + const summaryRow = GridSummaryFunctions.getSummaryRowByDataRowIndex(fix, 1); + GridSummaryFunctions.verifyColumnSummaries(summaryRow, 1, ['Count', 'Min', 'Max', 'Sum', 'Avg'], ['2', '17', '17', '34', '17']); + GridSummaryFunctions.verifyColumnSummaries(summaryRow, 2, ['Count'], ['2']); + GridSummaryFunctions.verifyColumnSummaries(summaryRow, 3, + ['Count', 'Earliest', 'Latest'], ['2', 'Dec 18, 2007', 'Mar 19, 2016']); + }); + + + it('should correctly position summary row when group row is collapsed', () => { + grid.showSummaryOnCollapse = true; + fix.detectChanges(); + grid.groupBy({ fieldName: 'OnPTO', dir: SortingDirection.Asc, ignoreCase: false }); + fix.detectChanges(); + + let summaryRow = GridSummaryFunctions.getSummaryRowByDataRowIndex(fix, 4); + GridSummaryFunctions.verifyColumnSummaries(summaryRow, 1, ['Count', 'Min', 'Max', 'Sum', 'Avg'], ['2', '17', '17', '34', '17']); + GridSummaryFunctions.verifyColumnSummaries(summaryRow, 2, ['Count'], ['2']); + GridSummaryFunctions.verifyColumnSummaries(summaryRow, 3, + ['Count', 'Earliest', 'Latest'], ['2', 'Dec 18, 2007', 'Mar 19, 2016']); + + summaryRow = GridSummaryFunctions.getSummaryRowByDataRowIndex(fix, 5); + GridSummaryFunctions.verifyColumnSummaries(summaryRow, 1, ['Count', 'Min', 'Max', 'Sum', 'Avg'], ['2', '17', '17', '34', '17']); + GridSummaryFunctions.verifyColumnSummaries(summaryRow, 2, ['Count'], ['2']); + GridSummaryFunctions.verifyColumnSummaries(summaryRow, 3, + ['Count', 'Earliest', 'Latest'], ['2', 'Dec 18, 2007', 'Mar 19, 2016']); + + const groupRows = grid.groupsRowList.toArray(); + groupRows[1].toggle(); + fix.detectChanges(); + + summaryRow = GridSummaryFunctions.getSummaryRowByDataRowIndex(fix, 2); + GridSummaryFunctions.verifyColumnSummaries(summaryRow, 1, ['Count', 'Min', 'Max', 'Sum', 'Avg'], ['2', '17', '17', '34', '17']); + GridSummaryFunctions.verifyColumnSummaries(summaryRow, 2, ['Count'], ['2']); + GridSummaryFunctions.verifyColumnSummaries(summaryRow, 3, + ['Count', 'Earliest', 'Latest'], ['2', 'Dec 18, 2007', 'Mar 19, 2016']); + + summaryRow = GridSummaryFunctions.getSummaryRowByDataRowIndex(fix, 3); + GridSummaryFunctions.verifyColumnSummaries(summaryRow, 1, ['Count', 'Min', 'Max', 'Sum', 'Avg'], ['2', '17', '17', '34', '17']); + GridSummaryFunctions.verifyColumnSummaries(summaryRow, 2, ['Count'], ['2']); + GridSummaryFunctions.verifyColumnSummaries(summaryRow, 3, + ['Count', 'Earliest', 'Latest'], ['2', 'Dec 18, 2007', 'Mar 19, 2016']); + + grid.summaryPosition = 'top'; + fix.detectChanges(); + + summaryRow = GridSummaryFunctions.getSummaryRowByDataRowIndex(fix, 1); + GridSummaryFunctions.verifyColumnSummaries(summaryRow, 1, ['Count', 'Min', 'Max', 'Sum', 'Avg'], ['2', '17', '17', '34', '17']); + GridSummaryFunctions.verifyColumnSummaries(summaryRow, 2, ['Count'], ['2']); + GridSummaryFunctions.verifyColumnSummaries(summaryRow, 3, + ['Count', 'Earliest', 'Latest'], ['2', 'Dec 18, 2007', 'Mar 19, 2016']); + + summaryRow = GridSummaryFunctions.getSummaryRowByDataRowIndex(fix, 3); + GridSummaryFunctions.verifyColumnSummaries(summaryRow, 1, ['Count', 'Min', 'Max', 'Sum', 'Avg'], ['2', '17', '17', '34', '17']); + GridSummaryFunctions.verifyColumnSummaries(summaryRow, 2, ['Count'], ['2']); + GridSummaryFunctions.verifyColumnSummaries(summaryRow, 3, + ['Count', 'Earliest', 'Latest'], ['2', 'Dec 18, 2007', 'Mar 19, 2016']); + + }); + it('should be able to enable/disable summaries at runtime', () => { grid.getColumnByName('Age').hasSummary = false; grid.getColumnByName('ParentID').hasSummary = false; diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid.component.html b/projects/igniteui-angular/src/lib/grids/grid/grid.component.html index 8fd95ac088a..cbd941da732 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid.component.html +++ b/projects/igniteui-angular/src/lib/grids/grid/grid.component.html @@ -138,7 +138,7 @@ | gridSort:sortingExpressions:sortStrategy:id:pipeTrigger | gridGroupBy:groupingExpressions:groupingExpansionState:groupsExpanded:id:groupsRecords:pipeTrigger | gridPaging:page:perPage:id:pipeTrigger - | gridSummary:hasSummarizedColumns:summaryCalculationMode:summaryPosition:id:pipeTrigger:summaryPipeTrigger + | gridSummary:hasSummarizedColumns:summaryCalculationMode:summaryPosition:id:showSummaryOnCollapse:pipeTrigger:summaryPipeTrigger | gridDetails:hasDetails:expansionStates:pipeTrigger | gridRowPinning:id:false:pipeTrigger" let-rowIndex="index" [igxForScrollOrientation]="'vertical'" [igxForScrollContainer]='verticalScroll' diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid.summary.pipe.ts b/projects/igniteui-angular/src/lib/grids/grid/grid.summary.pipe.ts index 28d76e1c484..7e231436b6b 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid.summary.pipe.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/grid.summary.pipe.ts @@ -30,16 +30,16 @@ export class IgxGridSummaryPipe implements PipeTransform { hasSummary: boolean, summaryCalculationMode: GridSummaryCalculationMode, summaryPosition: GridSummaryPosition, - id: string, pipeTrigger: number, summaryPipeTrigger: number): any[] { + id: string, showSummary, pipeTrigger: number, summaryPipeTrigger: number): any[] { if (!collection.data || !hasSummary || summaryCalculationMode === GridSummaryCalculationMode.rootLevelOnly) { return collection.data; } - return this.addSummaryRows(id, collection, summaryPosition); + return this.addSummaryRows(id, collection, summaryPosition, showSummary); } - private addSummaryRows(gridId: string, collection: IGroupByResult, summaryPosition: GridSummaryPosition): any[] { + private addSummaryRows(gridId: string, collection: IGroupByResult, summaryPosition: GridSummaryPosition, showSummary): any[] { const recordsWithSummary = []; const lastChildMap = new Map(); const grid: IgxGridComponent = this.gridAPI.grid; @@ -73,6 +73,15 @@ export class IgxGridSummaryPipe implements PipeTransform { recordsWithSummary.push(record); } + if (summaryPosition === GridSummaryPosition.bottom && showSummary && (groupByRecord && !grid.isExpandedGroup(groupByRecord))) { + const records = this.removeDeletedRecord(grid, groupByRecord.records.slice()); + const summaries = grid.summaryService.calculateSummaries(recordId, records); + const summaryRecord: ISummaryRecord = { + summaries: summaries, + max: maxSummaryHeight + }; + recordsWithSummary.push(summaryRecord); + } if (summaryPosition === GridSummaryPosition.bottom && lastChildMap.has(recordId)) { const groupRecords = lastChildMap.get(recordId); @@ -89,7 +98,8 @@ export class IgxGridSummaryPipe implements PipeTransform { } } - if (groupByRecord === null || !grid.isExpandedGroup(groupByRecord)) { + const showSummaries = showSummary ? false : (groupByRecord && !grid.isExpandedGroup(groupByRecord)); + if (groupByRecord === null || showSummaries) { continue; } @@ -123,7 +133,6 @@ export class IgxGridSummaryPipe implements PipeTransform { groupRecords.unshift(groupByRecord); } } - return recordsWithSummary; } diff --git a/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid-summaries.spec.ts b/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid-summaries.spec.ts index 2ff11762564..5321c23ef1a 100644 --- a/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid-summaries.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid-summaries.spec.ts @@ -163,6 +163,99 @@ describe('IgxTreeGrid - Summaries #tGrid', () => { expect(GridSummaryFunctions.getAllVisibleSummariesRowIndexes(fix)).toEqual([6, 7, rootSummaryIndex]); }); + it('should be able to show/hide summaries for collapsed parent rows runtime', () => { + treeGrid.summaryCalculationMode = 'childLevelsOnly'; + fix.detectChanges(); + + let summaries = GridSummaryFunctions.getAllVisibleSummaries(fix); + expect(summaries.length).toBe(0); + + treeGrid.showSummaryOnCollapse = true; + fix.detectChanges(); + + summaries = GridSummaryFunctions.getAllVisibleSummaries(fix); + expect(summaries.length).toBe(4); + + treeGrid.showSummaryOnCollapse = false; + fix.detectChanges(); + + summaries = GridSummaryFunctions.getAllVisibleSummaries(fix); + expect(summaries.length).toBe(0); + }); + + it('should position correctly summary row for collapsed rows -- bottom position', () => { + treeGrid.expandAll(); + fix.detectChanges(); + + treeGrid.summaryCalculationMode = 'childLevelsOnly'; + fix.detectChanges(); + + let summaries = GridSummaryFunctions.getAllVisibleSummaries(fix); + expect(summaries.length).toBe(4); + + treeGrid.showSummaryOnCollapse = true; + fix.detectChanges(); + + treeGrid.toggleRow(treeGrid.getRowByIndex(3).rowID); + fix.detectChanges(); + + summaries = GridSummaryFunctions.getAllVisibleSummaries(fix); + expect(summaries.length).toBe(4); + + let summaryRow = GridSummaryFunctions.getSummaryRowByDataRowIndex(fix, 4); + GridSummaryFunctions.verifyColumnSummaries(summaryRow, 2, + ['Count', 'Earliest', 'Latest'], ['2', 'Nov 11, 2009', 'Oct 17, 2015']); + + summaryRow = GridSummaryFunctions.getSummaryRowByDataRowIndex(fix, 5); + GridSummaryFunctions.verifyColumnSummaries(summaryRow, 2, + ['Count', 'Earliest', 'Latest'], ['3', 'Jul 19, 2009', 'Sep 18, 2014']); + + treeGrid.summaryPosition = 'top'; + fix.detectChanges(); + + summaries = GridSummaryFunctions.getAllVisibleSummaries(fix); + expect(summaries.length).toBe(4); + + summaryRow = GridSummaryFunctions.getSummaryRowByDataRowIndex(fix, 1); + GridSummaryFunctions.verifyColumnSummaries(summaryRow, 2, + ['Count', 'Earliest', 'Latest'], ['3', 'Jul 19, 2009', 'Sep 18, 2014']); + + summaryRow = GridSummaryFunctions.getSummaryRowByDataRowIndex(fix, 5); + GridSummaryFunctions.verifyColumnSummaries(summaryRow, 2, + ['Count', 'Earliest', 'Latest'], ['2', 'Nov 11, 2009', 'Oct 17, 2015']); + }); + + it('should position correctly summary row for collapsed rows -- top position', () => { + treeGrid.expandAll(); + fix.detectChanges(); + + treeGrid.summaryCalculationMode = 'childLevelsOnly'; + fix.detectChanges(); + + treeGrid.showSummaryOnCollapse = true; + fix.detectChanges(); + + let summaries = GridSummaryFunctions.getAllVisibleSummaries(fix); + expect(summaries.length).toBe(4); + + treeGrid.toggleRow(treeGrid.getRowByIndex(3).rowID); + fix.detectChanges(); + + treeGrid.summaryPosition = 'top'; + fix.detectChanges(); + + summaries = GridSummaryFunctions.getAllVisibleSummaries(fix); + expect(summaries.length).toBe(4); + + let summaryRow = GridSummaryFunctions.getSummaryRowByDataRowIndex(fix, 1); + GridSummaryFunctions.verifyColumnSummaries(summaryRow, 2, + ['Count', 'Earliest', 'Latest'], ['3', 'Jul 19, 2009', 'Sep 18, 2014']); + + summaryRow = GridSummaryFunctions.getSummaryRowByDataRowIndex(fix, 5); + GridSummaryFunctions.verifyColumnSummaries(summaryRow, 2, + ['Count', 'Earliest', 'Latest'], ['2', 'Nov 11, 2009', 'Oct 17, 2015']); + }); + it('should be able to enable/disable summaries at runtime', () => { treeGrid.expandAll(); fix.detectChanges(); diff --git a/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid.component.html b/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid.component.html index d093d3d920a..b28206ae718 100644 --- a/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid.component.html +++ b/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid.component.html @@ -104,7 +104,7 @@ | treeGridSorting:sortingExpressions:sortStrategy:id:pipeTrigger | treeGridFlattening:id:expansionDepth:expansionStates:pipeTrigger | treeGridPaging:page:perPage:id:pipeTrigger - | treeGridSummary:hasSummarizedColumns:summaryCalculationMode:summaryPosition:id:pipeTrigger:summaryPipeTrigger + | treeGridSummary:hasSummarizedColumns:summaryCalculationMode:summaryPosition:showSummaryOnCollapse:id:pipeTrigger:summaryPipeTrigger | gridRowPinning:id:false:pipeTrigger" let-rowIndex="index" [igxForScrollOrientation]="'vertical'" [igxForScrollContainer]='verticalScroll' [igxForContainerSize]='calcHeight' [igxForItemSize]="renderedRowHeight" #verticalScrollContainer> diff --git a/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid.summary.pipe.ts b/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid.summary.pipe.ts index 07d76682b49..12f0ecdace7 100644 --- a/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid.summary.pipe.ts +++ b/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid.summary.pipe.ts @@ -23,7 +23,7 @@ export class IgxTreeGridSummaryPipe implements PipeTransform { public transform(flatData: ITreeGridRecord[], hasSummary: boolean, summaryCalculationMode: GridSummaryCalculationMode, - summaryPosition: GridSummaryPosition, + summaryPosition: GridSummaryPosition, showSummaryOnCollapse: boolean, id: string, pipeTrigger: number, summaryPipeTrigger: number): any[] { const grid: IgxTreeGridComponent = this.gridAPI.grid; @@ -31,10 +31,11 @@ export class IgxTreeGridSummaryPipe implements PipeTransform { return flatData; } - return this.addSummaryRows(grid, flatData, summaryPosition); + return this.addSummaryRows(grid, flatData, summaryPosition, showSummaryOnCollapse); } - private addSummaryRows(grid: IgxTreeGridComponent, collection: ITreeGridRecord[], summaryPosition: GridSummaryPosition): any[] { + private addSummaryRows(grid: IgxTreeGridComponent, collection: ITreeGridRecord[], + summaryPosition: GridSummaryPosition, showSummaryOnCollapse: boolean): any[] { const recordsWithSummary = []; const maxSummaryHeight = grid.summaryService.calcMaxSummaryHeight(); @@ -42,8 +43,19 @@ export class IgxTreeGridSummaryPipe implements PipeTransform { const record = collection[i]; recordsWithSummary.push(record); + const isCollapsed = !record.expanded && record.children && record.children.length > 0 && showSummaryOnCollapse; + if (isCollapsed) { + let childData = record.children.filter(r => !r.isFilteredOutParent).map(r => r.data); + childData = this.removeDeletedRecord(grid, record.rowID, childData); + const summaries = grid.summaryService.calculateSummaries(record.rowID, childData); + const summaryRecord: ISummaryRecord = { + summaries: summaries, + max: maxSummaryHeight, + cellIndentation: record.level + 1 + }; + recordsWithSummary.push(summaryRecord); + } const isExpanded = record.children && record.children.length > 0 && record.expanded; - if (summaryPosition === GridSummaryPosition.bottom && !isExpanded) { let childRecord = record; let parent = record.parent; diff --git a/src/app/grid-groupby/grid-groupby.sample.html b/src/app/grid-groupby/grid-groupby.sample.html index 4c95bd88be2..c90588152a2 100644 --- a/src/app/grid-groupby/grid-groupby.sample.html +++ b/src/app/grid-groupby/grid-groupby.sample.html @@ -1,11 +1,15 @@
Toggle Hiding Of Grouped Columns +
+ Toggle Summary Position +
+ - Show summary on collapse
+ [height]="'700px'" [(groupingExpansionState)]='expState' [rowSelection]='selectionMode' [summaryCalculationMode]="summaryMode" [summaryPosition]='position'> diff --git a/src/app/grid-groupby/grid-groupby.sample.ts b/src/app/grid-groupby/grid-groupby.sample.ts index 1e1b292b604..941943e7a26 100644 --- a/src/app/grid-groupby/grid-groupby.sample.ts +++ b/src/app/grid-groupby/grid-groupby.sample.ts @@ -2,7 +2,7 @@ import { Component, ViewChild, OnInit, Inject } from '@angular/core'; import { IgxGridComponent, SortingDirection, ISortingExpression, - DefaultSortingStrategy, DisplayDensity, IDisplayDensityOptions, DisplayDensityToken, GridSelectionMode + DefaultSortingStrategy, DisplayDensity, IDisplayDensityOptions, DisplayDensityToken, GridSelectionMode, GridSummaryPosition } from 'igniteui-angular'; @Component({ @@ -21,6 +21,7 @@ export class GridGroupBySampleComponent implements OnInit { public summaryMode = 'rootLevelOnly'; public summaryModes = []; public selectionMode; + public position = GridSummaryPosition.top; constructor(@Inject(DisplayDensityToken) public displayDensityOptions: IDisplayDensityOptions) {} public ngOnInit(): void { this.columns = [ @@ -97,6 +98,10 @@ export class GridGroupBySampleComponent implements OnInit { toggleGroupedVisibility(event){ this.grid1.hideGroupedColumns = !event.checked; } + + toggleSummaryPosition($event) { + this.position = this.position === GridSummaryPosition.top ? GridSummaryPosition.bottom : GridSummaryPosition.top; + } toggleDensity() { switch (this.displayDensityOptions.displayDensity ) { case DisplayDensity.comfortable: this.displayDensityOptions.displayDensity = DisplayDensity.compact; break; diff --git a/src/app/tree-grid-flat-data/tree-grid-flat-data.sample.html b/src/app/tree-grid-flat-data/tree-grid-flat-data.sample.html index 539a94fe943..6e0c217d5d0 100644 --- a/src/app/tree-grid-flat-data/tree-grid-flat-data.sample.html +++ b/src/app/tree-grid-flat-data/tree-grid-flat-data.sample.html @@ -11,6 +11,7 @@
+ Date: Thu, 9 Jul 2020 17:41:40 +0300 Subject: [PATCH 27/53] fix(combo): make onSearchInput cancellable #7282 --- .../src/lib/combo/combo.component.spec.ts | 25 +++++++++++++++++-- .../src/lib/combo/combo.component.ts | 22 +++++++++++++--- 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts b/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts index 8e1f89a67aa..03faf6a1fba 100644 --- a/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts +++ b/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts @@ -18,6 +18,7 @@ import { configureTestSuite } from '../test-utils/configure-suite'; import { DisplayDensity } from '../core/density'; import { AbsoluteScrollStrategy, ConnectedPositioningStrategy } from '../services/public_api'; import { IgxSelectionAPIService } from '../core/selection'; +import { CancelableEventArgs } from '../core/utils'; const CSS_CLASS_COMBO = 'igx-combo'; const CSS_CLASS_COMBO_DROPDOWN = 'igx-combo__drop-down'; @@ -530,21 +531,41 @@ describe('igxCombo', () => { expect(matchSpy).toHaveBeenCalledTimes(1); expect(combo.onSearchInput.emit).toHaveBeenCalledTimes(0); + const args = { + change: 'Fake', + cancel: false + }; combo.handleInputChange('Fake'); expect(matchSpy).toHaveBeenCalledTimes(2); expect(combo.onSearchInput.emit).toHaveBeenCalledTimes(1); - expect(combo.onSearchInput.emit).toHaveBeenCalledWith('Fake'); + expect(combo.onSearchInput.emit).toHaveBeenCalledWith(args); + args.change = ''; combo.handleInputChange(''); expect(matchSpy).toHaveBeenCalledTimes(3); expect(combo.onSearchInput.emit).toHaveBeenCalledTimes(2); - expect(combo.onSearchInput.emit).toHaveBeenCalledWith(''); + expect(combo.onSearchInput.emit).toHaveBeenCalledWith(args); combo.filterable = false; combo.handleInputChange(); expect(matchSpy).toHaveBeenCalledTimes(4); expect(combo.onSearchInput.emit).toHaveBeenCalledTimes(2); }); + it('should be able to cancel onSearchInput', () => { + combo = new IgxComboComponent({ nativeElement: null }, mockCdr, mockSelection as any, mockComboService, null, mockInjector); + combo.ngOnInit(); + combo.data = data; + combo.filterable = true; + combo.onSearchInput.subscribe((e) => { + e.cancel = true; + }); + const matchSpy = spyOn(combo, 'checkMatch').and.callThrough(); + spyOn(combo.onSearchInput, 'emit').and.callThrough(); + + combo.handleInputChange('Item1'); + expect(combo.onSearchInput.emit).toHaveBeenCalledTimes(1); + expect(matchSpy).toHaveBeenCalledTimes(0); + }); }); describe('Initialization and rendering tests: ', () => { configureTestSuite(); diff --git a/projects/igniteui-angular/src/lib/combo/combo.component.ts b/projects/igniteui-angular/src/lib/combo/combo.component.ts index da944fee344..ca2ea3308a8 100644 --- a/projects/igniteui-angular/src/lib/combo/combo.component.ts +++ b/projects/igniteui-angular/src/lib/combo/combo.component.ts @@ -96,6 +96,12 @@ export interface IComboSelectionChangeEventArgs extends CancelableEventArgs, IBa event?: Event; } +/** Event emitted when the igx-combo's search input changes */ +export interface IComboSearchInputEventArgs extends CancelableEventArgs { + /** The change that has been made to the search input */ + change: string; +} + export interface IComboItemAdditionEvent extends IBaseEventArgs { oldCollection: any[]; addedItem: any; @@ -483,7 +489,7 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas * ``` */ @Output() - public onSearchInput = new EventEmitter(); + public onSearchInput = new EventEmitter(); /** * Emitted when new chunk of data is loaded from the virtualization @@ -981,7 +987,15 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas */ public handleInputChange(event?: string) { if (event !== undefined) { - this.onSearchInput.emit(event); + const args: IComboSearchInputEventArgs = { + change: event, + cancel: false + }; + this.onSearchInput.emit(args); + if (args.cancel) { + this.searchValue = null; + return; + } } this.checkMatch(); } @@ -1436,8 +1450,8 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas /** Returns a string that should be populated in the combo's text box */ private concatDisplayText(selection: any[]): string { const value = this.displayKey !== null && this.displayKey !== undefined ? - this.convertKeysToItems(selection).map(entry => entry[this.displayKey]).join(', ') : - selection.join(', '); + this.convertKeysToItems(selection).map(entry => entry[this.displayKey]).join(', ') : + selection.join(', '); return value; } From 4a328e7e22444b5129b42e62aba06ab3cb496d29 Mon Sep 17 00:00:00 2001 From: ddincheva Date: Mon, 13 Jul 2020 11:48:40 +0300 Subject: [PATCH 28/53] feat(Summary): add title attribute to summary label and result #6505 --- .../styles/components/grid-summary/_grid-summary-theme.scss | 1 - .../src/lib/grids/summaries/summary-cell.component.html | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/projects/igniteui-angular/src/lib/core/styles/components/grid-summary/_grid-summary-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/grid-summary/_grid-summary-theme.scss index 8fdec7829ba..a012be8ae56 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/grid-summary/_grid-summary-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/grid-summary/_grid-summary-theme.scss @@ -123,7 +123,6 @@ &::after { position: absolute; - content: ''; top: 0; bottom: 0; left: 0; diff --git a/projects/igniteui-angular/src/lib/grids/summaries/summary-cell.component.html b/projects/igniteui-angular/src/lib/grids/summaries/summary-cell.component.html index 2f3ad576a5b..fa4d4f18150 100644 --- a/projects/igniteui-angular/src/lib/grids/summaries/summary-cell.component.html +++ b/projects/igniteui-angular/src/lib/grids/summaries/summary-cell.component.html @@ -10,8 +10,8 @@
- {{ translateSummary(summary) }} - + {{ translateSummary(summary) }} + {{ columnDatatype === 'number' ? (summary.summaryResult | igxdecimal: grid.locale) : columnDatatype === 'date' ? (summary.summaryResult | igxdate: grid.locale) : (summary.summaryResult) }}
From 73f320282dd9e523647e732afb0210b758dc23a5 Mon Sep 17 00:00:00 2001 From: plamenamiteva Date: Thu, 9 Jul 2020 17:41:40 +0300 Subject: [PATCH 29/53] fix(combo): make onSearchInput cancellable #7282 --- CHANGELOG.md | 2 ++ .../src/lib/combo/combo.component.spec.ts | 25 +++++++++++++++++-- .../src/lib/combo/combo.component.ts | 22 +++++++++++++--- 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index efb8d7e5da9..d831af1ac2d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ All notable changes for each version of this project will be documented in this - Added `onScroll` event, which is emitted when the grid is scrolled vertically or horizontally. - `igxTreeGrid` - Removed `onDataPreLoad` event as it is specific for remote virtualization implementation, which is not supported for the `igxTreeGrid`. A more generic `onScroll` event is exposed and can be used instead. +- `igxCombo` + - Make `onSearchInput` event cancellable. The event args type has been changed to `IComboSearchInputEventArgs`, which have two properties: `change` - holds the change in the search input and `cancel` - indicates whether the event should be canceled. ### New Features - `IgxGridState` directive diff --git a/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts b/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts index 8e1f89a67aa..03faf6a1fba 100644 --- a/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts +++ b/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts @@ -18,6 +18,7 @@ import { configureTestSuite } from '../test-utils/configure-suite'; import { DisplayDensity } from '../core/density'; import { AbsoluteScrollStrategy, ConnectedPositioningStrategy } from '../services/public_api'; import { IgxSelectionAPIService } from '../core/selection'; +import { CancelableEventArgs } from '../core/utils'; const CSS_CLASS_COMBO = 'igx-combo'; const CSS_CLASS_COMBO_DROPDOWN = 'igx-combo__drop-down'; @@ -530,21 +531,41 @@ describe('igxCombo', () => { expect(matchSpy).toHaveBeenCalledTimes(1); expect(combo.onSearchInput.emit).toHaveBeenCalledTimes(0); + const args = { + change: 'Fake', + cancel: false + }; combo.handleInputChange('Fake'); expect(matchSpy).toHaveBeenCalledTimes(2); expect(combo.onSearchInput.emit).toHaveBeenCalledTimes(1); - expect(combo.onSearchInput.emit).toHaveBeenCalledWith('Fake'); + expect(combo.onSearchInput.emit).toHaveBeenCalledWith(args); + args.change = ''; combo.handleInputChange(''); expect(matchSpy).toHaveBeenCalledTimes(3); expect(combo.onSearchInput.emit).toHaveBeenCalledTimes(2); - expect(combo.onSearchInput.emit).toHaveBeenCalledWith(''); + expect(combo.onSearchInput.emit).toHaveBeenCalledWith(args); combo.filterable = false; combo.handleInputChange(); expect(matchSpy).toHaveBeenCalledTimes(4); expect(combo.onSearchInput.emit).toHaveBeenCalledTimes(2); }); + it('should be able to cancel onSearchInput', () => { + combo = new IgxComboComponent({ nativeElement: null }, mockCdr, mockSelection as any, mockComboService, null, mockInjector); + combo.ngOnInit(); + combo.data = data; + combo.filterable = true; + combo.onSearchInput.subscribe((e) => { + e.cancel = true; + }); + const matchSpy = spyOn(combo, 'checkMatch').and.callThrough(); + spyOn(combo.onSearchInput, 'emit').and.callThrough(); + + combo.handleInputChange('Item1'); + expect(combo.onSearchInput.emit).toHaveBeenCalledTimes(1); + expect(matchSpy).toHaveBeenCalledTimes(0); + }); }); describe('Initialization and rendering tests: ', () => { configureTestSuite(); diff --git a/projects/igniteui-angular/src/lib/combo/combo.component.ts b/projects/igniteui-angular/src/lib/combo/combo.component.ts index da944fee344..ca2ea3308a8 100644 --- a/projects/igniteui-angular/src/lib/combo/combo.component.ts +++ b/projects/igniteui-angular/src/lib/combo/combo.component.ts @@ -96,6 +96,12 @@ export interface IComboSelectionChangeEventArgs extends CancelableEventArgs, IBa event?: Event; } +/** Event emitted when the igx-combo's search input changes */ +export interface IComboSearchInputEventArgs extends CancelableEventArgs { + /** The change that has been made to the search input */ + change: string; +} + export interface IComboItemAdditionEvent extends IBaseEventArgs { oldCollection: any[]; addedItem: any; @@ -483,7 +489,7 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas * ``` */ @Output() - public onSearchInput = new EventEmitter(); + public onSearchInput = new EventEmitter(); /** * Emitted when new chunk of data is loaded from the virtualization @@ -981,7 +987,15 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas */ public handleInputChange(event?: string) { if (event !== undefined) { - this.onSearchInput.emit(event); + const args: IComboSearchInputEventArgs = { + change: event, + cancel: false + }; + this.onSearchInput.emit(args); + if (args.cancel) { + this.searchValue = null; + return; + } } this.checkMatch(); } @@ -1436,8 +1450,8 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas /** Returns a string that should be populated in the combo's text box */ private concatDisplayText(selection: any[]): string { const value = this.displayKey !== null && this.displayKey !== undefined ? - this.convertKeysToItems(selection).map(entry => entry[this.displayKey]).join(', ') : - selection.join(', '); + this.convertKeysToItems(selection).map(entry => entry[this.displayKey]).join(', ') : + selection.join(', '); return value; } From 44fe867f9f202a1585aa1cf628260692d60f3bfe Mon Sep 17 00:00:00 2001 From: ddincheva Date: Mon, 13 Jul 2020 16:02:24 +0300 Subject: [PATCH 30/53] feat(IgxCell): add title attribute to the cell component #6215 --- projects/igniteui-angular/src/lib/grids/cell.component.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/projects/igniteui-angular/src/lib/grids/cell.component.ts b/projects/igniteui-angular/src/lib/grids/cell.component.ts index 39704bdec32..703ac67f3d1 100644 --- a/projects/igniteui-angular/src/lib/grids/cell.component.ts +++ b/projects/igniteui-angular/src/lib/grids/cell.component.ts @@ -285,6 +285,11 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy { return `${this.row.gridID}_${this.rowIndex}_${ this.visibleColumnIndex}`; } + @HostBinding('attr.title') + public get title() { + return this.editMode || this.cellTemplate ? '' : this.value; + } + /** * Returns a reference to the nativeElement of the cell. * ```typescript From 67c7384ce33f5f345f30918051d3ea0980c1087d Mon Sep 17 00:00:00 2001 From: Simeon Simeonoff Date: Mon, 13 Jul 2020 19:03:52 +0300 Subject: [PATCH 31/53] fix(typography): incorrect compiled custom typography styles --- .../core/styles/typography/_typography.scss | 80 +++++++++---------- 1 file changed, 38 insertions(+), 42 deletions(-) diff --git a/projects/igniteui-angular/src/lib/core/styles/typography/_typography.scss b/projects/igniteui-angular/src/lib/core/styles/typography/_typography.scss index 49ea3667492..b81d1e95c52 100644 --- a/projects/igniteui-angular/src/lib/core/styles/typography/_typography.scss +++ b/projects/igniteui-angular/src/lib/core/styles/typography/_typography.scss @@ -47,48 +47,6 @@ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; - $this: bem--selector-to-string(&); - $selector: bem--extract-first-selector($this); - - // Maps type scale typographic categories - // to native elements. - $category-element-map: ( - h1: 'h1', - h2: 'h2', - h3: 'h3', - h4: 'h4', - h5: 'h5', - h6: 'h6', - body-1: 'p' - ); - - @each $category, $type-style in $type-scale { - // Get the native element that uses typographic styles directly - // as mapped in the $category-element-map - $e: map-get($category-element-map, $category); - - // Create a placeholder selector with styles for each - // typographic style to be able to easily extend it - // elsewhere. - %#{$category} { - @include igx-type-style($type-scale, $category); - } - - // Add native element typographic styles. - @if $e != null { - #{$e} { - @extend %#{$category}; - } - } - - // Add class selector typographic styles. - @if ($selector == '.igx-typography') { - @include e(#{$category}) { - @extend %#{$category}; - } - } - } - // Call the individual component styles with the type scale @include _excel-filtering-typography($type-scale); @include igx-banner-typography($type-scale); @@ -142,6 +100,44 @@ // and all typographic elements. @include b(igx-typography) { @include _igx-typography-styles($font-family, $type-scale); + + // Maps type scale typographic categories + // to native elements. + $category-element-map: ( + h1: 'h1', + h2: 'h2', + h3: 'h3', + h4: 'h4', + h5: 'h5', + h6: 'h6', + body-1: 'p' + ); + + @each $category, $type-style in $type-scale { + // Get the native element that uses typographic styles directly + // as mapped in the $category-element-map + $e: map-get($category-element-map, $category); + + // Create a placeholder selector with styles for each + // typographic style to be able to easily extend it + // elsewhere. + %#{$category} { + @include igx-type-style($type-scale, $category); + } + + // Add native element typographic styles. + @if $e != null { + // stylelint-disable-next-line max-nesting-depth + #{$e} { + @extend %#{$category}; + } + } + + // Add class selector typographic styles. + @include e(#{$category}) { + @extend %#{$category}; + } + } } } @else { @include _igx-typography-styles($font-family, $type-scale); From 37efabf109e4e5b56019468d5206aa53be112aae Mon Sep 17 00:00:00 2001 From: plamenamiteva Date: Tue, 14 Jul 2020 10:29:32 +0300 Subject: [PATCH 32/53] docs(combo): move breaking change in changelog #7282 --- CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d831af1ac2d..e50ac5f3781 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ All notable changes for each version of this project will be documented in this ### General - `igxCombo` - **Behavioral Change** - Change default positioning strategy from `ConnectedPositioningStrategy` to `AutoPositionStrategy`. The [`Auto`](https://www.infragistics.com/products/ignite-ui-angular/angular/components/overlay_position.html#auto) strategy will initially try to show the element like the Connected strategy does. If the element goes out of the viewport Auto will flip the starting point and the direction, i.e. if the direction is 'bottom', it will switch it to 'top' and so on. If after flipping direction the content goes out of the view, auto strategy will revert to initial start point and direction and will push the content into the view. Note after pushing the content it may hide the combo's input. + - **Breaking Change** - Make `onSearchInput` event cancellable. The event args type has been changed to `IComboSearchInputEventArgs`, which have two properties: `change` - holds the change in the search input and `cancel` - indicates whether the event should be canceled. - `IgxOverlay` - Added new property - `closeOnEsc` - in `OverlaySettings`. The overlay can now be prevented from closing, on escape keypress, by setting the property to `false`, by default it's `true`. - `igxDialog` @@ -17,8 +18,6 @@ All notable changes for each version of this project will be documented in this - Added `onScroll` event, which is emitted when the grid is scrolled vertically or horizontally. - `igxTreeGrid` - Removed `onDataPreLoad` event as it is specific for remote virtualization implementation, which is not supported for the `igxTreeGrid`. A more generic `onScroll` event is exposed and can be used instead. -- `igxCombo` - - Make `onSearchInput` event cancellable. The event args type has been changed to `IComboSearchInputEventArgs`, which have two properties: `change` - holds the change in the search input and `cancel` - indicates whether the event should be canceled. ### New Features - `IgxGridState` directive From e1647520fc0c2d55c6dabff74d7df9800efe5e29 Mon Sep 17 00:00:00 2001 From: ddincheva Date: Tue, 14 Jul 2020 11:18:34 +0300 Subject: [PATCH 33/53] chore(*): update the changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a9111b8e01..8b2bae948ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ All notable changes for each version of this project will be documented in this ### New Features - `IgxGrid`, `IgxTreeGrid`, `IgxHierarchicalGrid` - Introduced `showSummaryOnCollapse` grid property which allows you to control whether the summary row stays visible when the groupBy / parent row is collapsed. + - Added support for tooltips on data cells default template and summary cells. - `IgxGridState` directive - Added support for expansion states, column selection and row pinning. - Added support for `IgxTreeGrid` and `IgxHierarchicalGrid` (including child grids) From 6e5d52bdc00e60626324e9ab0bf3ba1394e348c9 Mon Sep 17 00:00:00 2001 From: Viktor Aladzhov Date: Tue, 14 Jul 2020 13:44:27 +0300 Subject: [PATCH 34/53] =?UTF-8?q?feat(time-picker):=20=D0=B0dding=20the=20?= =?UTF-8?q?disabled=20style=20for=20items=20which=20are=20outside=20the=20?= =?UTF-8?q?min/maxValue=20range=20#3978=20(#7347)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 2 + .../src/lib/time-picker/time-picker.common.ts | 8 +++ .../time-picker/time-picker.component.html | 18 +++-- .../time-picker/time-picker.component.spec.ts | 52 +++++++++++++- .../lib/time-picker/time-picker.component.ts | 71 ++++++++++++++++--- src/app/time-picker/time-picker.sample.html | 2 +- src/app/time-picker/time-picker.sample.ts | 4 +- 7 files changed, 136 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a9111b8e01..9215b7bbfee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ All notable changes for each version of this project will be documented in this - Added `onScroll` event, which is emitted when the grid is scrolled vertically or horizontally. - `igxTreeGrid` - Removed `onDataPreLoad` event as it is specific for remote virtualization implementation, which is not supported for the `igxTreeGrid`. A more generic `onScroll` event is exposed and can be used instead. +- `IgxTimePicker` + - Added a disabled style for time parts outside of the minimum and maximum range. ### New Features - `IgxGrid`, `IgxTreeGrid`, `IgxHierarchicalGrid` diff --git a/projects/igniteui-angular/src/lib/time-picker/time-picker.common.ts b/projects/igniteui-angular/src/lib/time-picker/time-picker.common.ts index d92f5da0596..ee53c77345c 100644 --- a/projects/igniteui-angular/src/lib/time-picker/time-picker.common.ts +++ b/projects/igniteui-angular/src/lib/time-picker/time-picker.common.ts @@ -4,6 +4,14 @@ import { InteractionMode } from '../core/enums'; /** @hidden */ export const IGX_TIME_PICKER_COMPONENT = 'IgxTimePickerComponentToken'; +/** @hidden */ +export enum TimeParts { + Hour = 'hour', + Minute = 'minute', + Seconds = 'seconds', + amPM = 'ampm' +} + /** @hidden */ export interface IgxTimePickerBase { hourList: ElementRef; diff --git a/projects/igniteui-angular/src/lib/time-picker/time-picker.component.html b/projects/igniteui-angular/src/lib/time-picker/time-picker.component.html index e411d1f35e9..7cdb5951497 100644 --- a/projects/igniteui-angular/src/lib/time-picker/time-picker.component.html +++ b/projects/igniteui-angular/src/lib/time-picker/time-picker.component.html @@ -4,7 +4,7 @@ access_time -
- {{ hour }} + {{ hour }}
- {{ minute }} + {{ minute }}
- {{ seconds }} + {{ seconds }}
- {{ ampm }} + {{ ampm }}
{ @@ -1667,6 +1668,53 @@ describe('IgxTimePicker', () => { expect(input).not.toEqual(document.activeElement); expect(dummyInput).toEqual(document.activeElement); })); + + it('should apply disabled style for time outside the min and max values', fakeAsync(() => { + timePicker = new IgxTimePickerComponent(null, null); + fixture.detectChanges(); + timePicker.format = 'hh:mm:ss tt'; + const date = new Date(2018, 10, 27, 9, 50, 58); + timePicker.value = date; + + timePicker.minValue = '09:15:10 AM'; + timePicker.maxValue = '11:15:10 AM'; + + timePicker.selectedHour = '06'; + timePicker.selectedMinute = '25'; + timePicker.selectedSeconds = '00'; + timePicker.selectedAmPm = 'AM'; + + fixture.detectChanges(); + + // The selected time is 06:25:00 AM + // Testing 09:25:00 AM + expect(timePicker.applyDisabledStyleForItem('hour', '9')).toBe(false); + + timePicker.selectedHour = '9'; // The selected time is 09:25:00 AM + + // Testing 10:25:00 AM + expect(timePicker.applyDisabledStyleForItem('hour', '10')).toBe(false); + + timePicker.selectedHour = '10'; + timePicker.selectedMinute = '10'; // The selected time is 10:10:00 AM + + // Testing 11:10:00 AM + expect(timePicker.applyDisabledStyleForItem('hour', '11')).toBe(false); + + timePicker.selectedHour = '11'; // The selected time is 11:10:00 AM + + // Testing 12:11:00 AM + expect(timePicker.applyDisabledStyleForItem('hour', '12')).toBe(true); + // Testing 11:28:00 AM + expect(timePicker.applyDisabledStyleForItem('minute', '28')).toBe(true); + // Testing 11:10:28 AM + expect(timePicker.applyDisabledStyleForItem('seconds', '28')).toBe(false); + + timePicker.selectedAmPm = 'PM'; // The selected time is 11:10:00 PM + + // Testing 11:10:00 AM + expect(timePicker.applyDisabledStyleForItem('ampm', 'AM')).toBe(false); + })); }); describe('Timepicker with outlet', () => { @@ -2248,7 +2296,7 @@ export class IgxTimePickerRetemplatedComponent { } ` }) export class IgxTimePickerDropDownComponent { - itemsDelta = { hours: 1, minutes: 5 }; + itemsDelta = { hours: 1, minutes: 5, seconds: 1 }; format = 'hh:mm tt'; isSpinLoop = true; isVertical = true; diff --git a/projects/igniteui-angular/src/lib/time-picker/time-picker.component.ts b/projects/igniteui-angular/src/lib/time-picker/time-picker.component.ts index 116436f9b8a..39926a16cc1 100644 --- a/projects/igniteui-angular/src/lib/time-picker/time-picker.component.ts +++ b/projects/igniteui-angular/src/lib/time-picker/time-picker.component.ts @@ -37,7 +37,7 @@ import { } from './time-picker.directives'; import { Subject, fromEvent, interval, animationFrameScheduler, Subscription } from 'rxjs'; import { EditorProvider } from '../core/edit-provider'; -import { IgxTimePickerBase, IGX_TIME_PICKER_COMPONENT } from './time-picker.common'; +import { IgxTimePickerBase, IGX_TIME_PICKER_COMPONENT, TimeParts } from './time-picker.common'; import { AbsoluteScrollStrategy } from '../services/overlay/scroll'; import { AutoPositionStrategy } from '../services/overlay/position'; import { OverlaySettings } from '../services/overlay/utilities'; @@ -98,6 +98,7 @@ const noop = () => { }; }` ] }) + export class IgxTimePickerComponent implements IgxTimePickerBase, ControlValueAccessor, @@ -152,6 +153,10 @@ export class IgxTimePickerComponent implements this.onValidationFailed.emit(args); } } + /** + * @hidden @internal + */ + timeParts: any = Object.assign({}, TimeParts); /** * An accessor that returns the value of `igx-time-picker` component. @@ -507,10 +512,10 @@ export class IgxTimePickerComponent implements @ViewChild(IgxInputDirective, { read: ElementRef }) private _inputElementRef: ElementRef; - @ViewChild(IgxInputDirective, { read: IgxInputDirective}) + @ViewChild(IgxInputDirective, { read: IgxInputDirective }) private _inputDirective: IgxInputDirective; - @ContentChild(IgxInputDirective, { read: IgxInputDirective}) + @ContentChild(IgxInputDirective, { read: IgxInputDirective }) private _inputDirectiveUserTemplate: IgxInputDirective; @ViewChild(IgxInputGroupComponent, { read: IgxInputGroupComponent }) @@ -635,6 +640,46 @@ export class IgxTimePickerComponent implements } } + /** @hidden @internal */ + applyDisabledStyleForItem(period: string, value: string) { + if (!this.minValue || !this.maxValue) { + return false; + } + const minValueDate: Date = this.convertMinMaxValue(this.minValue); + const maxValueDate: Date = this.convertMinMaxValue(this.maxValue); + let hour: number = parseInt(this.selectedHour, 10); + let minute: number = parseInt(this.selectedMinute, 10); + let seconds: number = parseInt(this.selectedSeconds, 10); + let amPM: string = this.selectedAmPm; + const date = new Date(minValueDate); + switch (period) { + case TimeParts.Hour: + hour = parseInt(value, 10); + break; + + case TimeParts.Minute: + minute = parseInt(value, 10); + break; + + case TimeParts.Seconds: + seconds = parseInt(value, 10); + break; + + case TimeParts.amPM: + amPM = value; + break; + } + + if (amPM === 'PM') { + hour += 12; + } + date.setHours(hour); + date.setMinutes(minute); + date.setSeconds(seconds); + return date < minValueDate || date > maxValueDate; + + } + /** @hidden @internal */ public registerOnChange(fn: (_: Date) => void) { this._onChangeCallback = fn; } @@ -1267,7 +1312,11 @@ export class IgxTimePickerComponent implements return date; } - private _convertMinMaxValue(value: string): Date { + /** @hidden @internal */ + public convertMinMaxValue(value: string): Date { + if (!value) { + return; + } const date = this.value ? new Date(this.value) : this._dateFromModel ? new Date(this._dateFromModel) : new Date(); const sections = value.split(/[\s:]+/); let hour, minutes, seconds, amPM; @@ -1310,9 +1359,9 @@ export class IgxTimePickerComponent implements } private _isValueValid(value: Date): boolean { - if (this.maxValue && value > this._convertMinMaxValue(this.maxValue)) { + if (this.maxValue && value > this.convertMinMaxValue(this.maxValue)) { return false; - } else if (this.minValue && value < this._convertMinMaxValue(this.minValue)) { + } else if (this.minValue && value < this.convertMinMaxValue(this.minValue)) { return false; } else { return true; @@ -1484,7 +1533,7 @@ export class IgxTimePickerComponent implements private _onDropDownClosed(): void { const oldValue = this.value; - const newVal = this._convertMinMaxValue(this.displayValue); + const newVal = this.convertMinMaxValue(this.displayValue); if (this.displayValue === this.parseMask(false)) { return; @@ -1922,7 +1971,7 @@ export class IgxTimePickerComponent implements // timepicker own value property if it is a valid Date if (val.indexOf(this.promptChar) === -1) { if (this._isEntryValid(val)) { - const newVal = this._convertMinMaxValue(val); + const newVal = this.convertMinMaxValue(val); if (oldVal.getTime() !== newVal.getTime()) { this.value = newVal; } @@ -1970,7 +2019,7 @@ export class IgxTimePickerComponent implements if (value && value !== this.parseMask()) { if (this._isEntryValid(value)) { - const newVal = this._convertMinMaxValue(value); + const newVal = this.convertMinMaxValue(value); if (!this.value || this.value.getTime() !== newVal.getTime()) { this.value = newVal; } @@ -2007,8 +2056,8 @@ export class IgxTimePickerComponent implements let sign: number; let displayVal: string; const currentVal = new Date(this.value); - const min = this.minValue ? this._convertMinMaxValue(this.minValue) : this._convertMinMaxValue('00:00'); - const max = this.maxValue ? this._convertMinMaxValue(this.maxValue) : this._convertMinMaxValue('24:00'); + const min = this.minValue ? this.convertMinMaxValue(this.minValue) : this.convertMinMaxValue('00:00'); + const max = this.maxValue ? this.convertMinMaxValue(this.maxValue) : this.convertMinMaxValue('24:00'); const cursor = this._getCursorPosition(); diff --git a/src/app/time-picker/time-picker.sample.html b/src/app/time-picker/time-picker.sample.html index 875109c1a8b..8b75d6f6ab4 100644 --- a/src/app/time-picker/time-picker.sample.html +++ b/src/app/time-picker/time-picker.sample.html @@ -7,7 +7,7 @@

Time Picker with Dropdown

{{showDate(date)}}
- diff --git a/src/app/time-picker/time-picker.sample.ts b/src/app/time-picker/time-picker.sample.ts index 25e8aa4e1f1..fc71d87cc31 100644 --- a/src/app/time-picker/time-picker.sample.ts +++ b/src/app/time-picker/time-picker.sample.ts @@ -11,13 +11,13 @@ export class TimePickerSampleComponent implements AfterViewInit { min = '09:00'; itemsDelta = { hours: 1, minutes: 5 }; - format = 'hh:mm tt'; + format = 'hh:mm:ss tt'; isSpinLoop = true; isVertical = true; mode = InteractionMode.DropDown; date1 = new Date(2018, 10, 27, 17, 45, 0, 0); - date = new Date(2018, 10, 27, 21, 45, 0, 0); + date = new Date(2018, 10, 27, 9, 45, 0, 0); val = new Date(0, 0, 0, 19, 35, 30, 0); today = new Date(Date.now()); From dc0e6595b88ca8d8d26f7a654d52f3e9b4c56b9f Mon Sep 17 00:00:00 2001 From: Radoslav Karaivanov Date: Tue, 14 Jul 2020 15:10:48 +0300 Subject: [PATCH 35/53] Merge pull request #7791 from IgniteUI/dmdimitrov/exportersPerf-10.0.x fix(exporters): performance optimizations for CSV and Excel exporters (cherry picked from commit 1419ff3ca356bea368ec27d1a73934d6552901eb) --- package-lock.json | 8 +- package.json | 2 + projects/igniteui-angular/ng-package.json | 1 + .../igniteui-angular/ng-package.prod.json | 1 + projects/igniteui-angular/package.json | 1 + .../schematics/utils/dependency-handler.ts | 1 + .../igniteui-angular/src/lib/core/utils.ts | 17 +++ .../services/csv/char-separated-value-data.ts | 55 ++++++-- .../src/lib/services/csv/csv-exporter.ts | 9 +- .../excel/excel-exporter-grid.spec.ts | 3 +- .../services/excel/excel-exporter-options.ts | 4 +- .../src/lib/services/excel/excel-exporter.ts | 30 +++-- .../src/lib/services/excel/excel-files.ts | 120 +++++++++++++++++- .../services/excel/test-data.service.spec.ts | 5 +- .../excel/worksheet-data-dictionary.ts | 14 +- .../src/lib/services/excel/worksheet-data.ts | 6 +- .../exporter-common/base-export-service.ts | 24 +++- 17 files changed, 244 insertions(+), 57 deletions(-) diff --git a/package-lock.json b/package-lock.json index f57a1701742..0099154be1a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7174,6 +7174,11 @@ } } }, + "core-js-pure": { + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.6.5.tgz", + "integrity": "sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA==" + }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -20162,8 +20167,7 @@ "setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" }, "setprototypeof": { "version": "1.1.1", diff --git a/package.json b/package.json index 28a558dd4f7..8c24fb799f3 100644 --- a/package.json +++ b/package.json @@ -57,12 +57,14 @@ "@types/source-map": "0.5.2", "classlist.js": "^1.1.20150312", "core-js": "^2.6.11", + "core-js-pure": "^3.6.5", "hammerjs": "^2.0.8", "igniteui-trial-watermark": "^1.0.3", "jszip": "^3.4.0", "resize-observer-polyfill": "^1.5.1", "rxjs": "^6.5.4", "tslib": "^2.0.0", + "setimmediate": "^1.0.5", "web-animations-js": "^2.3.2", "zone.js": "~0.10.3" }, diff --git a/projects/igniteui-angular/ng-package.json b/projects/igniteui-angular/ng-package.json index 0750500bbb6..ae5d8097051 100644 --- a/projects/igniteui-angular/ng-package.json +++ b/projects/igniteui-angular/ng-package.json @@ -8,6 +8,7 @@ "whitelistedNonPeerDependencies": [ "@types/hammerjs", "@types/jszip", + "core-js-pure", "hammerjs", "jszip", "resize-observer-polyfill", diff --git a/projects/igniteui-angular/ng-package.prod.json b/projects/igniteui-angular/ng-package.prod.json index 2088cdfbb99..6b21ffae16d 100644 --- a/projects/igniteui-angular/ng-package.prod.json +++ b/projects/igniteui-angular/ng-package.prod.json @@ -10,6 +10,7 @@ "whitelistedNonPeerDependencies": [ "@types/hammerjs", "@types/jszip", + "core-js-pure", "hammerjs", "jszip", "resize-observer-polyfill", diff --git a/projects/igniteui-angular/package.json b/projects/igniteui-angular/package.json index 232b741a9c3..c958315b67a 100644 --- a/projects/igniteui-angular/package.json +++ b/projects/igniteui-angular/package.json @@ -68,6 +68,7 @@ "dependencies": { "@types/hammerjs": "^2.0.36", "@types/jszip": "^3.1.7", + "core-js-pure": "^3.6.5", "hammerjs": "^2.0.8", "jszip": "^3.3.0", "tslib": "^2.0.0", diff --git a/projects/igniteui-angular/schematics/utils/dependency-handler.ts b/projects/igniteui-angular/schematics/utils/dependency-handler.ts index 607e3467623..99a68e2e96f 100644 --- a/projects/igniteui-angular/schematics/utils/dependency-handler.ts +++ b/projects/igniteui-angular/schematics/utils/dependency-handler.ts @@ -30,6 +30,7 @@ export const DEPENDENCIES_MAP: PackageEntry[] = [ { name: '@types/hammerjs', target: PackageTarget.DEV }, { name: '@types/jszip', target: PackageTarget.DEV }, { name: 'igniteui-trial-watermark', target: PackageTarget.NONE }, + { name: 'core-js-pure', target: PackageTarget.NONE }, // peerDependencies { name: '@angular/forms', target: PackageTarget.NONE }, { name: '@angular/common', target: PackageTarget.NONE }, diff --git a/projects/igniteui-angular/src/lib/core/utils.ts b/projects/igniteui-angular/src/lib/core/utils.ts index 9166378170e..8e8d6389784 100644 --- a/projects/igniteui-angular/src/lib/core/utils.ts +++ b/projects/igniteui-angular/src/lib/core/utils.ts @@ -2,6 +2,7 @@ import { Injectable, PLATFORM_ID, Inject } from '@angular/core'; import { isPlatformBrowser } from '@angular/common'; import { Observable } from 'rxjs'; import ResizeObserver from 'resize-observer-polyfill'; +import { setImmediate } from 'core-js-pure'; /** * @hidden @@ -383,3 +384,19 @@ export function compareMaps(map1: Map, map2: Map): boolean { } return match; } + +export function yieldingLoop(count: number, chunkSize: number, callback: (index: number) => void, done: () => void) { + let i = 0; + const chunk = () => { + const end = Math.min(i + chunkSize, count); + for ( ; i < end; ++i) { + callback(i); + } + if (i < count) { + setImmediate(chunk); + } else { + done(); + } + }; + chunk(); +} diff --git a/projects/igniteui-angular/src/lib/services/csv/char-separated-value-data.ts b/projects/igniteui-angular/src/lib/services/csv/char-separated-value-data.ts index 1e23bd7aa35..aa137c1e56b 100644 --- a/projects/igniteui-angular/src/lib/services/csv/char-separated-value-data.ts +++ b/projects/igniteui-angular/src/lib/services/csv/char-separated-value-data.ts @@ -1,4 +1,5 @@ import { ExportUtilities } from '../exporter-common/export-utilities'; +import { yieldingLoop } from '../../core/utils'; /** * @hidden @@ -36,6 +37,26 @@ export class CharSeparatedValueData { return this._headerRecord + this._dataRecords; } + public prepareDataAsync(done: (result: string) => void) { + if (!this._data || this._data.length === 0) { + done(''); + } + + const keys = ExportUtilities.getKeysFromData(this._data); + + if (keys.length === 0) { + done(''); + } + + this._isSpecialData = ExportUtilities.isSpecialData(this._data); + this._escapeCharacters.push(this._delimiter); + + this._headerRecord = this.processHeaderRecord(keys, this._escapeCharacters); + this.processDataRecordsAsync(this._data, keys, this._escapeCharacters, (dr) => { + done(this._headerRecord + dr); + }); + } + private processField(value, escapeChars): string { let safeValue = ExportUtilities.hasValue(value) ? String(value) : ''; if (escapeChars.some((v) => safeValue.includes(v))) { @@ -54,23 +75,37 @@ export class CharSeparatedValueData { } private processRecord(record, keys, escapeChars): string { - let recordData = ''; - for (const keyName of keys) { - - const value = (record[keyName] !== undefined) ? record[keyName] : this._isSpecialData ? record : ''; - recordData += this.processField(value, this._escapeCharacters); + const recordData = new Array(keys.length); + for (let index = 0; index < keys.length; index++) { + const value = (record[keys[index]] !== undefined) ? record[keys[index]] : this._isSpecialData ? record : ''; + recordData[index] = this.processField(value, this._escapeCharacters); } - return recordData.slice(0, -this._delimiterLength) + this._eor; + return recordData.join('').slice(0, -this._delimiterLength) + this._eor; } private processDataRecords(currentData, keys, escapeChars) { - let dataRecords = ''; - for (const row of currentData) { - dataRecords += this.processRecord(row, keys, escapeChars); + const dataRecords = new Array(currentData.length); + + for (let i = 0; i < currentData.length; i++) { + const row = currentData[i]; + dataRecords[i] = this.processRecord(row, keys, escapeChars); } - return dataRecords; + return dataRecords.join(''); + } + + private processDataRecordsAsync(currentData, keys, escapeChars, done: (result: string) => void) { + const dataRecords = new Array(currentData.length); + + yieldingLoop(currentData.length, 1000, + (i) => { + const row = currentData[i]; + dataRecords[i] = this.processRecord(row, keys, escapeChars); + }, + () => { + done(dataRecords.join('')); + }); } private setDelimiter(value) { diff --git a/projects/igniteui-angular/src/lib/services/csv/csv-exporter.ts b/projects/igniteui-angular/src/lib/services/csv/csv-exporter.ts index 740f293a2bc..b15e55e0eb7 100644 --- a/projects/igniteui-angular/src/lib/services/csv/csv-exporter.ts +++ b/projects/igniteui-angular/src/lib/services/csv/csv-exporter.ts @@ -50,10 +50,11 @@ export class IgxCsvExporterService extends IgxBaseExporter { protected exportDataImplementation(data: any[], options: IgxCsvExporterOptions) { data = data.map((item) => item.rowData); const csvData = new CharSeparatedValueData(data, options.valueDelimiter); - this._stringData = csvData.prepareData(); - - this.saveFile(options); - this.onExportEnded.emit({ csvData: this._stringData }); + csvData.prepareDataAsync((r) => { + this._stringData = r; + this.saveFile(options); + this.onExportEnded.emit({ csvData: this._stringData }); + }); } private saveFile(options: IgxCsvExporterOptions) { diff --git a/projects/igniteui-angular/src/lib/services/excel/excel-exporter-grid.spec.ts b/projects/igniteui-angular/src/lib/services/excel/excel-exporter-grid.spec.ts index 9e9b0465c55..fe1364d60ed 100644 --- a/projects/igniteui-angular/src/lib/services/excel/excel-exporter-grid.spec.ts +++ b/projects/igniteui-angular/src/lib/services/excel/excel-exporter-grid.spec.ts @@ -266,14 +266,13 @@ describe('Excel Exporter', () => { const grid = fix.componentInstance.grid; grid.columns[1].hidden = true; grid.columns[2].hidden = true; - const columnWidths = [100, 200, 0, undefined, null]; + const columnWidths = [100, 200, 0, null]; fix.detectChanges(); await setColWidthAndExport(grid, options, fix, columnWidths[0]); await setColWidthAndExport(grid, options, fix, columnWidths[1]); await setColWidthAndExport(grid, options, fix, columnWidths[2]); await setColWidthAndExport(grid, options, fix, columnWidths[3]); - await setColWidthAndExport(grid, options, fix, columnWidths[4]); }); it('should export all rows with the height specified in options.', async () => { diff --git a/projects/igniteui-angular/src/lib/services/excel/excel-exporter-options.ts b/projects/igniteui-angular/src/lib/services/excel/excel-exporter-options.ts index 28c1bb4f559..c4b86d4477c 100644 --- a/projects/igniteui-angular/src/lib/services/excel/excel-exporter-options.ts +++ b/projects/igniteui-angular/src/lib/services/excel/excel-exporter-options.ts @@ -44,8 +44,8 @@ export class IgxExcelExporterOptions extends IgxExporterOptionsBase { } /** - * Sets the width of the columns in the exported excel file. If left unspecified or 0, - * the width of the largest string in the column will be used. + * Sets the width of the columns in the exported excel file. If left unspecified, + * the width of the column or the default width of the excel columns will be used. * ```typescript * this.exportOptions.columnWidth = 55; * ``` diff --git a/projects/igniteui-angular/src/lib/services/excel/excel-exporter.ts b/projects/igniteui-angular/src/lib/services/excel/excel-exporter.ts index dd9d9419fd1..077af5aa3f5 100644 --- a/projects/igniteui-angular/src/lib/services/excel/excel-exporter.ts +++ b/projects/igniteui-angular/src/lib/services/excel/excel-exporter.ts @@ -9,6 +9,7 @@ import { IgxBaseExporter } from '../exporter-common/base-export-service'; import { ExportUtilities } from '../exporter-common/export-utilities'; import { WorksheetData } from './worksheet-data'; import { IBaseEventArgs } from '../../core/utils'; +import { WorksheetFile } from './excel-files'; export interface IExcelExportEndedEventArgs extends IBaseEventArgs { xlsx: JSZip; @@ -53,16 +54,20 @@ export class IgxExcelExporterService extends IgxBaseExporter { @Output() public onExportEnded = new EventEmitter(); - private static populateFolder(folder: IExcelFolder, zip: JSZip, worksheetData: WorksheetData): any { + private static async populateFolderAsync(folder: IExcelFolder, zip: JSZip, worksheetData: WorksheetData) { for (const childFolder of folder.childFolders(worksheetData)) { - const folderIntance = ExcelElementsFactory.getExcelFolder(childFolder); - const zipFolder = zip.folder(folderIntance.folderName); - IgxExcelExporterService.populateFolder(folderIntance, zipFolder, worksheetData); + const folderInstance = ExcelElementsFactory.getExcelFolder(childFolder); + const zipFolder = zip.folder(folderInstance.folderName); + await IgxExcelExporterService.populateFolderAsync(folderInstance, zipFolder, worksheetData); } for (const childFile of folder.childFiles(worksheetData)) { const fileInstance = ExcelElementsFactory.getExcelFile(childFile); - fileInstance.writeElement(zip, worksheetData); + if (fileInstance instanceof WorksheetFile) { + await (fileInstance as WorksheetFile).writeElementAsync(zip, worksheetData); + } else { + fileInstance.writeElement(zip, worksheetData); + } } } @@ -77,16 +82,19 @@ export class IgxExcelExporterService extends IgxBaseExporter { } } - const worksheetData = new WorksheetData(data, options, this._indexOfLastPinnedColumn, this._sort, this._isTreeGrid); + const worksheetData = + new WorksheetData(data, this.columnWidthList, options, this._indexOfLastPinnedColumn, this._sort, this._isTreeGrid); + this._xlsx = new JSZip(); const rootFolder = ExcelElementsFactory.getExcelFolder(ExcelFolderTypes.RootExcelFolder); - IgxExcelExporterService.populateFolder(rootFolder, this._xlsx, worksheetData); - this._xlsx.generateAsync(IgxExcelExporterService.ZIP_OPTIONS).then((result) => { - this.saveFile(result, options.fileName); - - this.onExportEnded.emit({ xlsx: this._xlsx }); + IgxExcelExporterService.populateFolderAsync(rootFolder, this._xlsx, worksheetData) + .then(() => { + this._xlsx.generateAsync(IgxExcelExporterService.ZIP_OPTIONS).then((result) => { + this.saveFile(result, options.fileName); + this.onExportEnded.emit({ xlsx: this._xlsx }); + }); }); } diff --git a/projects/igniteui-angular/src/lib/services/excel/excel-files.ts b/projects/igniteui-angular/src/lib/services/excel/excel-files.ts index 561733c0f6e..19f367be866 100644 --- a/projects/igniteui-angular/src/lib/services/excel/excel-files.ts +++ b/projects/igniteui-angular/src/lib/services/excel/excel-files.ts @@ -3,6 +3,7 @@ import { ExcelStrings } from './excel-strings'; import { WorksheetData } from './worksheet-data'; import * as JSZip from 'jszip'; +import { yieldingLoop } from '../../core/utils'; /** * @hidden @@ -54,7 +55,11 @@ export class ThemeFile implements IExcelFile { * @hidden */ export class WorksheetFile implements IExcelFile { - private static MIN_WIDTH = 8.34; + private static MIN_WIDTH = 8.43; + private maxOutlineLevel = 0; + private dimension = ''; + private freezePane = ''; + private rowHeight = ''; public writeElement(folder: JSZip, worksheetData: WorksheetData) { const sheetData = []; @@ -107,9 +112,12 @@ export class WorksheetFile implements IExcelFile { for (let i = 0; i < worksheetData.columnCount; i++) { const width = dictionary.columnWidths[i]; // Use the width provided in the options if it exists - const widthInTwips = worksheetData.options.columnWidth ? - worksheetData.options.columnWidth : - Math.max(((width / 96) * 14.4), WorksheetFile.MIN_WIDTH); + let widthInTwips = worksheetData.options.columnWidth !== undefined ? + worksheetData.options.columnWidth : + Math.max(((width / 96) * 14.4), WorksheetFile.MIN_WIDTH); + if (!(widthInTwips > 0)) { + widthInTwips = WorksheetFile.MIN_WIDTH; + } cols.push(``); } @@ -131,6 +139,110 @@ export class WorksheetFile implements IExcelFile { worksheetData.isTreeGridData, maxOutlineLevel)); } + public async writeElementAsync(folder: JSZip, worksheetData: WorksheetData) { + return new Promise(resolve => { + this.prepareDataAsync(worksheetData, (cols, rows) => { + const hasTable = !worksheetData.isEmpty && worksheetData.options.exportAsTable; + folder.file('sheet1.xml', ExcelStrings.getSheetXML( + this.dimension, this.freezePane, cols, rows, hasTable, worksheetData.isTreeGridData, this.maxOutlineLevel)); + resolve(); + }); + }); + } + + private prepareDataAsync(worksheetData: WorksheetData, done: (cols: string, sheetData: string) => void) { + let sheetData = ''; + let cols = ''; + const dictionary = worksheetData.dataDictionary; + + if (worksheetData.isEmpty) { + sheetData += ''; + this.dimension = 'A1'; + done('', sheetData); + } else { + sheetData += ''; + const height = worksheetData.options.rowHeight; + this.rowHeight = height ? ' ht="' + height + '" customHeight="1"' : ''; + sheetData += ``; + + for (let i = 0; i < worksheetData.columnCount; i++) { + const column = ExcelStrings.getExcelColumn(i) + 1; + const value = dictionary.saveValue(worksheetData.keys[i], i, true); + sheetData += `${value}`; + } + sheetData += ''; + + this.dimension = 'A1:' + ExcelStrings.getExcelColumn(worksheetData.columnCount - 1) + worksheetData.rowCount; + cols += ''; + + for (let i = 0; i < worksheetData.columnCount; i++) { + const width = dictionary.columnWidths[i]; + // Use the width provided in the options if it exists + let widthInTwips = worksheetData.options.columnWidth !== undefined ? + worksheetData.options.columnWidth : + Math.max(((width / 96) * 14.4), WorksheetFile.MIN_WIDTH); + if (!(widthInTwips > 0)) { + widthInTwips = WorksheetFile.MIN_WIDTH; + } + + cols += ``; + } + + cols += ''; + + if (worksheetData.indexOfLastPinnedColumn !== -1 && + !worksheetData.options.ignorePinning && + !worksheetData.options.ignoreColumnsOrder) { + const frozenColumnCount = worksheetData.indexOfLastPinnedColumn + 1; + const firstCell = ExcelStrings.getExcelColumn(frozenColumnCount) + '1'; + this.freezePane = ``; + } + + this.processDataRecordsAsync(worksheetData, (rows) => { + sheetData += rows; + sheetData += ''; + done(cols, sheetData); + }); + } + } + + private processDataRecordsAsync(worksheetData: WorksheetData, done: (rows: string) => void) { + const rowDataArr = new Array(worksheetData.rowCount - 1); + const height = worksheetData.options.rowHeight; + this.rowHeight = height ? ' ht="' + height + '" customHeight="1"' : ''; + + yieldingLoop(worksheetData.rowCount - 1, 1000, + (i) => { + rowDataArr[i] = this.processRow(worksheetData, i + 1); + }, + () => { + done(rowDataArr.join('')); + }); + } + + private processRow(worksheetData: WorksheetData, i: number) { + const rowData = new Array(worksheetData.columnCount + 2); + if (!worksheetData.isTreeGridData) { + rowData[0] = ``; + } else { + const originalData = worksheetData.data[i - 1].originalRowData; + const sCollapsed = (!originalData.expanded) ? '' : (originalData.expanded === true) ? '' : ` collapsed="1"`; + const sHidden = (originalData.parent && this.hasCollapsedParent(originalData)) ? ` hidden="1"` : ''; + const rowOutlineLevel = originalData.level ? originalData.level : 0; + const sOutlineLevel = rowOutlineLevel > 0 ? ` outlineLevel="${rowOutlineLevel}"` : ''; + this.maxOutlineLevel = this.maxOutlineLevel < rowOutlineLevel ? rowOutlineLevel : this.maxOutlineLevel; + rowData[0] = ``; + } + + for (let j = 0; j < worksheetData.columnCount; j++) { + const cellData = WorksheetFile.getCellData(worksheetData, i, j); + rowData[j + 1] = cellData; + } + rowData[worksheetData.columnCount + 1] = ''; + + return rowData.join(''); + } + private hasCollapsedParent(rowData) { let result = !rowData.parent.expanded; while (rowData.parent) { diff --git a/projects/igniteui-angular/src/lib/services/excel/test-data.service.spec.ts b/projects/igniteui-angular/src/lib/services/excel/test-data.service.spec.ts index 206f175c032..bd8ce2a9fd5 100644 --- a/projects/igniteui-angular/src/lib/services/excel/test-data.service.spec.ts +++ b/projects/igniteui-angular/src/lib/services/excel/test-data.service.spec.ts @@ -346,7 +346,7 @@ export class FileContentData { ``; this._worksheetData = `` + - `01` + `23`; @@ -611,11 +611,10 @@ export class FileContentData { wsDataColSettings = ``; break; - case undefined: case null: case 0: wsDataColSettings = - ``; + ``; break; } diff --git a/projects/igniteui-angular/src/lib/services/excel/worksheet-data-dictionary.ts b/projects/igniteui-angular/src/lib/services/excel/worksheet-data-dictionary.ts index 7b9ec3d8cca..c533f1cd049 100644 --- a/projects/igniteui-angular/src/lib/services/excel/worksheet-data-dictionary.ts +++ b/projects/igniteui-angular/src/lib/services/excel/worksheet-data-dictionary.ts @@ -15,7 +15,6 @@ export class WorksheetDataDictionary { private _keysAreValid: boolean; private _counter: number; - private _calculateColumnWidth: boolean; private _columnWidths: number[]; private _context: any; @@ -24,18 +23,19 @@ export class WorksheetDataDictionary { public stringsCount: number; - constructor(columnCount: number, columnWidth: number) { + constructor(columnCount: number, columnWidth: number, columnWidthsList: number[]) { this._dictionary = {}; this._widthsDictionary = {}; this._counter = 0; this.dirtyKeyCollections(); - this._calculateColumnWidth = !columnWidth; this._columnWidths = new Array(columnCount); this._columnTypeInfo = new Array(columnCount); - if (!this._calculateColumnWidth) { + if (columnWidth) { this._columnWidths.fill(columnWidth); + } else { + this._columnWidths = columnWidthsList; } this.stringsCount = 0; @@ -68,12 +68,6 @@ export class WorksheetDataDictionary { this.hasNonStringValues = true; } - if (this._calculateColumnWidth) { - const width = this.getTextWidth(value); - const maxWidth = Math.max(this._columnWidths[column] || 0, width); - this._columnWidths[column] = maxWidth; - } - return isSavedAsString ? this.getSanitizedValue(sanitizedValue) : -1; } diff --git a/projects/igniteui-angular/src/lib/services/excel/worksheet-data.ts b/projects/igniteui-angular/src/lib/services/excel/worksheet-data.ts index 4496edf0012..fa944268059 100644 --- a/projects/igniteui-angular/src/lib/services/excel/worksheet-data.ts +++ b/projects/igniteui-angular/src/lib/services/excel/worksheet-data.ts @@ -10,8 +10,8 @@ export class WorksheetData { private _keys: string[]; private _isSpecialData: boolean; - constructor(private _data: any[], public options: IgxExcelExporterOptions, public indexOfLastPinnedColumn, - public sort: any, public isTreeGridData = false) { + constructor(private _data: any[], private _columnWidths: number[], public options: IgxExcelExporterOptions, + public indexOfLastPinnedColumn, public sort: any, public isTreeGridData = false) { this.initializeData(); } @@ -60,6 +60,6 @@ export class WorksheetData { this._columnCount = this._keys.length; this._rowCount = this._data.length + 1; - this._dataDictionary = new WorksheetDataDictionary(this._columnCount, this.options.columnWidth); + this._dataDictionary = new WorksheetDataDictionary(this._columnCount, this.options.columnWidth, this._columnWidths); } } diff --git a/projects/igniteui-angular/src/lib/services/exporter-common/base-export-service.ts b/projects/igniteui-angular/src/lib/services/exporter-common/base-export-service.ts index 14a3066e92b..a8a0eca3f22 100644 --- a/projects/igniteui-angular/src/lib/services/exporter-common/base-export-service.ts +++ b/projects/igniteui-angular/src/lib/services/exporter-common/base-export-service.ts @@ -1,6 +1,6 @@ import { EventEmitter } from '@angular/core'; -import { cloneValue, IBaseEventArgs } from '../../core/utils'; +import { cloneValue, IBaseEventArgs, yieldingLoop } from '../../core/utils'; import { DataUtil } from '../../data-operations/data-util'; import { ExportUtilities } from './export-utilities'; @@ -66,9 +66,12 @@ export interface IColumnExportingEventArgs extends IBaseEventArgs { skipFormatter: boolean; } +const DEFAULT_COLUMN_WIDTH = 8.43; + export abstract class IgxBaseExporter { private _columnList: any[]; private flatRecords = []; + private _columnWidthList: number[]; protected _isTreeGrid = false; protected _indexOfLastPinnedColumn = -1; @@ -96,6 +99,10 @@ export abstract class IgxBaseExporter { */ public onColumnExport = new EventEmitter(); + public get columnWidthList() { + return this._columnWidthList; + } + /** * Method for exporting IgxGrid component's data. * ```typescript @@ -110,6 +117,7 @@ export abstract class IgxBaseExporter { const columns = grid.columnList.toArray(); this._columnList = new Array(columns.length); + this._columnWidthList = new Array(columns.filter(c => !c.hidden).length); const hiddenColumns = []; let lastVisbleColumnIndex = -1; @@ -118,6 +126,7 @@ export abstract class IgxBaseExporter { const columnHeader = column.header !== '' ? column.header : column.field; const exportColumn = !column.hidden || options.ignoreColumnsVisibility; const index = options.ignoreColumnsOrder ? column.index : column.visibleIndex; + const columnWidth = Number(column.width.slice(0, -2)); const columnInfo = { header: columnHeader, @@ -129,6 +138,7 @@ export abstract class IgxBaseExporter { if (index !== -1) { this._columnList[index] = columnInfo; + this._columnWidthList[index] = columnWidth; lastVisbleColumnIndex = Math.max(lastVisbleColumnIndex, index); } else { hiddenColumns.push(columnInfo); @@ -163,6 +173,7 @@ export abstract class IgxBaseExporter { if (!this._columnList || this._columnList.length === 0) { const keys = ExportUtilities.getKeysFromData(data); this._columnList = keys.map((k) => ({ header: k, field: k, skip: false })); + this._columnWidthList = new Array(keys.length).fill(DEFAULT_COLUMN_WIDTH); } let skippedPinnedColumnsCount = 0; @@ -202,12 +213,13 @@ export abstract class IgxBaseExporter { const dataToExport = new Array(); const isSpecialData = ExportUtilities.isSpecialData(data); - data.forEach((row, index) => { - this.exportRow(dataToExport, row, index, isSpecialData); + yieldingLoop(data.length, 1000, (i) => { + const row = data[i]; + this.exportRow(dataToExport, row, i, isSpecialData); + }, () => { + this.exportDataImplementation(dataToExport, options); + this.resetDefaults(); }); - - this.exportDataImplementation(dataToExport, options); - this.resetDefaults(); } protected abstract exportDataImplementation(data: any[], options: IgxExporterOptionsBase): void; From c7e87882d4fa0ea08b37d16149335aa2b0fe0c6a Mon Sep 17 00:00:00 2001 From: Boris Date: Tue, 14 Jul 2020 15:10:04 +0300 Subject: [PATCH 36/53] refactor(overlay): consecutevly close overlays on escape keypress - set closeOnEsc to false by default --- CHANGELOG.md | 2 +- .../lib/date-picker/date-picker.component.ts | 2 +- .../src/lib/dialog/dialog.component.ts | 1 + .../toggle/toggle.directive.spec.ts | 4 -- .../lib/directives/toggle/toggle.directive.ts | 1 - .../src/lib/services/overlay/overlay.spec.ts | 61 ++++++++----------- .../src/lib/services/overlay/overlay.ts | 18 +++++- 7 files changed, 45 insertions(+), 44 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0bb69687c3a..6b9c860901e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ All notable changes for each version of this project will be documented in this - `igxCombo` - **Behavioral Change** - Change default positioning strategy from `ConnectedPositioningStrategy` to `AutoPositionStrategy`. The [`Auto`](https://www.infragistics.com/products/ignite-ui-angular/angular/components/overlay_position.html#auto) strategy will initially try to show the element like the Connected strategy does. If the element goes out of the viewport Auto will flip the starting point and the direction, i.e. if the direction is 'bottom', it will switch it to 'top' and so on. If after flipping direction the content goes out of the view, auto strategy will revert to initial start point and direction and will push the content into the view. Note after pushing the content it may hide the combo's input. - `IgxOverlay` - - Added new property - `closeOnEsc` - in `OverlaySettings`. The overlay can now be prevented from closing, on escape keypress, by setting the property to `false`, by default it's `true`. + - Added new property - `closeOnEsc` - in `OverlaySettings`. The overlay can now be prevented from closing, on escape keypress, by setting the property to `false`, it is `false` by default. - `igxDialog` - Added `closeOnEscapeKey` - with it, the dialog can be allowed or prevented from closing when `Esc` is pressed. - `IgxNavbar`: diff --git a/projects/igniteui-angular/src/lib/date-picker/date-picker.component.ts b/projects/igniteui-angular/src/lib/date-picker/date-picker.component.ts index 6a0fa20e661..76320f170a4 100644 --- a/projects/igniteui-angular/src/lib/date-picker/date-picker.component.ts +++ b/projects/igniteui-angular/src/lib/date-picker/date-picker.component.ts @@ -783,8 +783,8 @@ export class IgxDatePickerComponent implements IDatePicker, ControlValueAccessor this._modalOverlaySettings = { closeOnOutsideClick: true, - closeOnEsc: true, modal: true, + closeOnEsc: true, outlet: this.outlet }; diff --git a/projects/igniteui-angular/src/lib/dialog/dialog.component.ts b/projects/igniteui-angular/src/lib/dialog/dialog.component.ts index 2e295ca9ce7..35c01665c3b 100644 --- a/projects/igniteui-angular/src/lib/dialog/dialog.component.ts +++ b/projects/igniteui-angular/src/lib/dialog/dialog.component.ts @@ -83,6 +83,7 @@ export class IgxDialogComponent implements IToggleView, OnInit, OnDestroy, After this._isModal = val; } + @Input() get closeOnEscapeKey() { return this._closeOnEscapeKey; } diff --git a/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.spec.ts b/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.spec.ts index 35365c58662..33744066b07 100644 --- a/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.spec.ts +++ b/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.spec.ts @@ -475,7 +475,6 @@ describe('IgxToggle', () => { positionStrategy: jasmine.any(ConnectedPositioningStrategy) as any, closeOnOutsideClick: true, modal: false, - closeOnEsc: true, scrollStrategy: jasmine.any(AbsoluteScrollStrategy) as any, excludePositionTarget: true }; @@ -499,7 +498,6 @@ describe('IgxToggle', () => { positionStrategy: jasmine.any(ConnectedPositioningStrategy) as any, closeOnOutsideClick: true, modal: false, - closeOnEsc: true, scrollStrategy: jasmine.any(AbsoluteScrollStrategy) as any, excludePositionTarget: true }; @@ -535,7 +533,6 @@ describe('IgxToggle', () => { positionStrategy: jasmine.any(ConnectedPositioningStrategy) as any, closeOnOutsideClick: true, modal: false, - closeOnEsc: true, scrollStrategy: jasmine.any(AbsoluteScrollStrategy) as any, excludePositionTarget: true }; @@ -594,7 +591,6 @@ describe('IgxToggle', () => { positionStrategy: jasmine.any(ConnectedPositioningStrategy) as any, closeOnOutsideClick: true, modal: false, - closeOnEsc: true, scrollStrategy: jasmine.any(AbsoluteScrollStrategy) as any, outlet: jasmine.any(IgxOverlayOutletDirective) as any, excludePositionTarget: true diff --git a/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.ts b/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.ts index 9ae74bfd93b..1db48870e9e 100644 --- a/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.ts +++ b/projects/igniteui-angular/src/lib/directives/toggle/toggle.directive.ts @@ -429,7 +429,6 @@ export class IgxToggleActionDirective implements OnInit { scrollStrategy: new AbsoluteScrollStrategy(), closeOnOutsideClick: true, modal: false, - closeOnEsc: true, excludePositionTarget: true }; } diff --git a/projects/igniteui-angular/src/lib/services/overlay/overlay.spec.ts b/projects/igniteui-angular/src/lib/services/overlay/overlay.spec.ts index 98cc3cd1985..cda00d5204d 100644 --- a/projects/igniteui-angular/src/lib/services/overlay/overlay.spec.ts +++ b/projects/igniteui-angular/src/lib/services/overlay/overlay.spec.ts @@ -216,8 +216,7 @@ describe('igxOverlay', () => { overlay.show(overlay.attach(SimpleDynamicComponent), { outlet: button, - modal: false, - closeOnEsc: false + modal: false }); tick(); let wrapper = document.getElementsByClassName(CLASS_OVERLAY_WRAPPER)[0]; @@ -225,7 +224,7 @@ describe('igxOverlay', () => { expect(wrapper.parentNode).toBe(button.nativeElement); overlay.hideAll(); - overlay.show(overlay.attach(SimpleDynamicComponent), { modal: false, closeOnEsc: false }); + overlay.show(overlay.attach(SimpleDynamicComponent), { modal: false }); tick(); wrapper = document.getElementsByClassName(CLASS_OVERLAY_WRAPPER)[0]; expect(wrapper).toBeDefined(); @@ -237,7 +236,6 @@ describe('igxOverlay', () => { fixture.debugElement.nativeElement.appendChild(outlet); overlay.show(overlay.attach(SimpleDynamicComponent), { modal: false, - closeOnEsc: false, outlet: new IgxOverlayOutletDirective(new ElementRef(outlet)) }); tick(); @@ -688,7 +686,6 @@ describe('igxOverlay', () => { tick(); fix.componentInstance.overlaySettings.outlet = fix.componentInstance.elementRef; - fix.componentInstance.overlaySettings.closeOnEsc = false; const buttonElement: HTMLElement = fix.componentInstance.buttonElement.nativeElement; buttonElement.click(); @@ -1078,7 +1075,6 @@ describe('igxOverlay', () => { positionStrategy: new GlobalPositionStrategy(), scrollStrategy: new NoOpScrollStrategy(), modal: false, - closeOnEsc: false, closeOnOutsideClick: false }; const positionSettings: PositionSettings = { @@ -1305,7 +1301,6 @@ describe('igxOverlay', () => { positionStrategy: new GlobalPositionStrategy(), scrollStrategy: new NoOpScrollStrategy(), modal: false, - closeOnEsc: false, closeOnOutsideClick: false }; const positionSettings: PositionSettings = { @@ -1332,7 +1327,6 @@ describe('igxOverlay', () => { positionStrategy: new GlobalPositionStrategy(), scrollStrategy: new NoOpScrollStrategy(), modal: false, - closeOnEsc: false, closeOnOutsideClick: false }; overlaySettings.positionStrategy = new ConnectedPositioningStrategy(); @@ -1460,7 +1454,6 @@ describe('igxOverlay', () => { positionStrategy: new GlobalPositionStrategy(), scrollStrategy: scrollStrat, modal: false, - closeOnEsc: false, closeOnOutsideClick: false }; const overlay = fixture.componentInstance.overlay; @@ -1490,7 +1483,6 @@ describe('igxOverlay', () => { positionStrategy: new ConnectedPositioningStrategy(), scrollStrategy: scrollStrat, modal: false, - closeOnEsc: false, closeOnOutsideClick: false }; const buttonElement = fixture.componentInstance.buttonElement.nativeElement; @@ -1668,7 +1660,6 @@ describe('igxOverlay', () => { positionStrategy: new AutoPositionStrategy(), scrollStrategy: new NoOpScrollStrategy(), modal: false, - closeOnEsc: false, closeOnOutsideClick: false }; @@ -1697,7 +1688,6 @@ describe('igxOverlay', () => { positionStrategy: new GlobalPositionStrategy(), scrollStrategy: new NoOpScrollStrategy(), modal: false, - closeOnEsc: false, closeOnOutsideClick: false }; const positionSettings: PositionSettings = { @@ -1943,7 +1933,6 @@ describe('igxOverlay', () => { positionStrategy: new AutoPositionStrategy(positionSettings), scrollStrategy: new NoOpScrollStrategy(), modal: false, - closeOnEsc: false, closeOnOutsideClick: false }; const hAlignmentArray = Object.keys(HorizontalAlignment).filter(key => !isNaN(Number(HorizontalAlignment[key]))); @@ -2000,7 +1989,6 @@ describe('igxOverlay', () => { positionStrategy: new AutoPositionStrategy(positionSettings), scrollStrategy: new NoOpScrollStrategy(), modal: false, - closeOnEsc: false, closeOnOutsideClick: false }; overlay.show(overlay.attach(SimpleDynamicComponent), overlaySettings); @@ -2043,7 +2031,6 @@ describe('igxOverlay', () => { positionStrategy: new AutoPositionStrategy(positionSettings), scrollStrategy: new NoOpScrollStrategy(), modal: false, - closeOnEsc: false, closeOnOutsideClick: false }; overlay.show(overlay.attach(SimpleDynamicComponent), overlaySettings); @@ -2145,7 +2132,6 @@ describe('igxOverlay', () => { positionStrategy: new ElasticPositionStrategy(), scrollStrategy: new NoOpScrollStrategy(), modal: false, - closeOnEsc: false, closeOnOutsideClick: false }; @@ -2174,7 +2160,6 @@ describe('igxOverlay', () => { positionStrategy: new GlobalPositionStrategy(), scrollStrategy: new NoOpScrollStrategy(), modal: false, - closeOnEsc: false, closeOnOutsideClick: false }; const positionSettings: PositionSettings = { @@ -2438,7 +2423,6 @@ describe('igxOverlay', () => { positionStrategy: new ElasticPositionStrategy(positionSettings), scrollStrategy: new NoOpScrollStrategy(), modal: false, - closeOnEsc: false, closeOnOutsideClick: false }; const hAlignmentArray = Object.keys(HorizontalAlignment).filter(key => !isNaN(Number(HorizontalAlignment[key]))); @@ -2495,7 +2479,6 @@ describe('igxOverlay', () => { positionStrategy: new ElasticPositionStrategy(positionSettings), scrollStrategy: new NoOpScrollStrategy(), modal: false, - closeOnEsc: false, closeOnOutsideClick: false }; overlay.show(overlay.attach(SimpleDynamicComponent), overlaySettings); @@ -2539,7 +2522,6 @@ describe('igxOverlay', () => { positionStrategy: new ElasticPositionStrategy(positionSettings), scrollStrategy: new NoOpScrollStrategy(), modal: false, - closeOnEsc: false, closeOnOutsideClick: false }; overlay.show(overlay.attach(SimpleDynamicComponent), overlaySettings); @@ -2766,7 +2748,6 @@ describe('igxOverlay', () => { const overlay = fixture.componentInstance.overlay; const overlaySettings: OverlaySettings = { modal: true, - closeOnEsc: false, positionStrategy: new GlobalPositionStrategy() }; const targetButton = 'Escape'; @@ -2790,6 +2771,27 @@ describe('igxOverlay', () => { expect(overlayWrapper).toBeTruthy(); })); + it('Should close the opened overlays consecutively on escape keypress', fakeAsync(() => { + const fixture = TestBed.createComponent(EmptyPageComponent); + const overlay = fixture.componentInstance.overlay; + overlay.show(overlay.attach(SimpleDynamicComponent), { modal: false, closeOnEsc: true }); + tick(); + overlay.show(overlay.attach(SimpleDynamicComponent), { modal: true, closeOnEsc: true }); + tick(); + + const overlayWrapper = document.getElementsByClassName(CLASS_OVERLAY_WRAPPER_MODAL)[0]; + const escEvent = new KeyboardEvent('keydown', { + key: 'Escape' + }); + overlayWrapper.dispatchEvent(escEvent); + tick(); + expect(document.getElementsByClassName(CLASS_OVERLAY_WRAPPER_MODAL)[0]).toBeFalsy(); + + document.dispatchEvent(escEvent); + tick(); + expect(document.getElementsByClassName(CLASS_OVERLAY_WRAPPER)[0]).toBeFalsy(); + })); + // Test #1883 #1820 it('It should close the component when esc key is pressed and there were other keys pressed prior to esc.', fakeAsync(() => { const fixture = TestBed.createComponent(EmptyPageComponent); @@ -2837,8 +2839,7 @@ describe('igxOverlay', () => { const fixture = TestBed.createComponent(EmptyPageComponent); const overlay = fixture.componentInstance.overlay; const overlaySettings: OverlaySettings = { - modal: false, - closeOnEsc: false + modal: false }; overlay.show(overlay.attach(SimpleDynamicComponent), overlaySettings); @@ -2867,7 +2868,6 @@ describe('igxOverlay', () => { const overlay = fixture.componentInstance.overlay; const overlaySettings: OverlaySettings = { modal: false, - closeOnEsc: false, positionStrategy: new GlobalPositionStrategy() }; const targetEvent = 'keydown'; @@ -2986,7 +2986,6 @@ describe('igxOverlay', () => { positionStrategy: new ConnectedPositioningStrategy(), scrollStrategy: scrollStrat, modal: false, - closeOnEsc: false, closeOnOutsideClick: false }; const overlay = fixture.componentInstance.overlay; @@ -3405,7 +3404,6 @@ describe('igxOverlay', () => { const overlaySettings: OverlaySettings = { modal: false, - closeOnEsc: false }; const overlay = fixture.componentInstance.overlay; @@ -3448,7 +3446,6 @@ describe('igxOverlay', () => { positionStrategy: new GlobalPositionStrategy(), scrollStrategy: scrollStrategy, modal: false, - closeOnEsc: false }; overlay.show(overlay.attach(SimpleDynamicComponent), overlaySettings); @@ -3489,7 +3486,6 @@ describe('igxOverlay', () => { scrollStrategy: scrollStrategy, closeOnOutsideClick: false, modal: false, - closeOnEsc: false }; overlay.show(overlay.attach(SimpleDynamicComponent), overlaySettings); @@ -3524,7 +3520,6 @@ describe('igxOverlay', () => { positionStrategy: new GlobalPositionStrategy(), scrollStrategy: scrollStrategy, modal: false, - closeOnEsc: false }; overlay.show(overlay.attach(SimpleDynamicComponent), overlaySettings); @@ -3562,7 +3557,6 @@ describe('igxOverlay', () => { const overlay = fixture.componentInstance.overlay; const overlaySettings: OverlaySettings = { modal: false, - closeOnEsc: false, scrollStrategy: scrollStrategy, positionStrategy: new GlobalPositionStrategy() }; @@ -3604,7 +3598,6 @@ describe('igxOverlay', () => { const overlaySettings: OverlaySettings = { closeOnOutsideClick: false, modal: false, - closeOnEsc: false, positionStrategy: new ConnectedPositioningStrategy(), scrollStrategy: scrollStrategy }; @@ -3879,16 +3872,16 @@ export class TopLeftOffsetComponent {
` }) export class TwoButtonsComponent { - private _setting: OverlaySettings = { modal: false, closeOnEsc: false }; + public settings: OverlaySettings = { modal: false }; constructor(@Inject(IgxOverlayService) public overlay: IgxOverlayService) { } clickOne() { - this.overlay.show(this.overlay.attach(SimpleDynamicComponent), this._setting); + this.overlay.show(this.overlay.attach(SimpleDynamicComponent), this.settings); } clickTwo() { - this.overlay.show(this.overlay.attach(SimpleDynamicComponent), this._setting); + this.overlay.show(this.overlay.attach(SimpleDynamicComponent), this.settings); } divClick(ev: Event) { diff --git a/projects/igniteui-angular/src/lib/services/overlay/overlay.ts b/projects/igniteui-angular/src/lib/services/overlay/overlay.ts index e6f04bd9636..976db7792ea 100644 --- a/projects/igniteui-angular/src/lib/services/overlay/overlay.ts +++ b/projects/igniteui-angular/src/lib/services/overlay/overlay.ts @@ -30,6 +30,7 @@ import { fromEvent, Subject } from 'rxjs'; import { filter, takeUntil } from 'rxjs/operators'; import { IAnimationParams } from '../../animations/main'; import { showMessage } from '../../core/deprecateDecorators'; +import { FromEventTarget } from 'rxjs/internal/observable/fromEvent'; let warningShown = false; @@ -50,7 +51,7 @@ export class IgxOverlayService implements OnDestroy { scrollStrategy: new NoOpScrollStrategy(), modal: true, closeOnOutsideClick: true, - closeOnEsc: true + closeOnEsc: false }; /** @@ -476,11 +477,22 @@ export class IgxOverlayService implements OnDestroy { } private setUpCloseOnEscape(info: OverlayInfo) { + if (!info.settings.modal) { + this.subscribeOnEscape(this._document); + return; + } const wrapperElement = info.elementRef.nativeElement.parentElement.parentElement; - fromEvent(wrapperElement, 'keydown').pipe( + this.subscribeOnEscape(wrapperElement); + } + + private subscribeOnEscape(target: FromEventTarget) { + fromEvent(target, 'keydown').pipe( filter((ev: KeyboardEvent) => ev.key === 'Escape' || ev.key === 'Esc'), takeUntil(this.destroy$) - ).subscribe(() => this.hide(info.id)); + ).subscribe(() => { + const targetOverlay = this._overlayInfos[this._overlayInfos.length - 1]; + this.hide(targetOverlay.id); + }); } private onCloseDone(info: OverlayInfo) { From b78303d5472894a65b968a88d06d6a41aec4992e Mon Sep 17 00:00:00 2001 From: Boris Date: Tue, 14 Jul 2020 17:14:58 +0300 Subject: [PATCH 37/53] refactor(overlay): apply requested changes --- .../src/lib/services/overlay/overlay.spec.ts | 28 +++++++++++-------- .../src/lib/services/overlay/overlay.ts | 24 ++++++++++------ 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/projects/igniteui-angular/src/lib/services/overlay/overlay.spec.ts b/projects/igniteui-angular/src/lib/services/overlay/overlay.spec.ts index cda00d5204d..c0993c9d3ca 100644 --- a/projects/igniteui-angular/src/lib/services/overlay/overlay.spec.ts +++ b/projects/igniteui-angular/src/lib/services/overlay/overlay.spec.ts @@ -2735,11 +2735,12 @@ describe('igxOverlay', () => { overlayWrapper.addEventListener('keydown', (event: KeyboardEvent) => { if (event.key === targetButton) { overlayWrapper = document.getElementsByClassName(CLASS_OVERLAY_WRAPPER_MODAL)[0]; + expect(overlayWrapper).toBeFalsy(); } }); tick(); expect(overlayWrapper).toBeTruthy(); - overlayWrapper.dispatchEvent(escEvent); + document.dispatchEvent(escEvent); tick(); })); @@ -2764,7 +2765,7 @@ describe('igxOverlay', () => { overlayWrapper = document.getElementsByClassName(CLASS_OVERLAY_WRAPPER_MODAL)[0]; } }); - overlayWrapper.dispatchEvent(escEvent); + document.dispatchEvent(escEvent); tick(); fixture.detectChanges(); @@ -2774,22 +2775,25 @@ describe('igxOverlay', () => { it('Should close the opened overlays consecutively on escape keypress', fakeAsync(() => { const fixture = TestBed.createComponent(EmptyPageComponent); const overlay = fixture.componentInstance.overlay; - overlay.show(overlay.attach(SimpleDynamicComponent), { modal: false, closeOnEsc: true }); + overlay.show(overlay.attach(SimpleDynamicComponent), { closeOnEsc: true }); tick(); - overlay.show(overlay.attach(SimpleDynamicComponent), { modal: true, closeOnEsc: true }); + overlay.show(overlay.attach(SimpleDynamicComponent), { closeOnEsc: true }); tick(); - const overlayWrapper = document.getElementsByClassName(CLASS_OVERLAY_WRAPPER_MODAL)[0]; + const overlayDiv = document.getElementsByClassName(CLASS_OVERLAY_MAIN)[0]; + expect(overlayDiv.children.length).toBe(2); + const escEvent = new KeyboardEvent('keydown', { key: 'Escape' }); - overlayWrapper.dispatchEvent(escEvent); + + document.dispatchEvent(escEvent); tick(); - expect(document.getElementsByClassName(CLASS_OVERLAY_WRAPPER_MODAL)[0]).toBeFalsy(); + expect(overlayDiv.children.length).toBe(1); document.dispatchEvent(escEvent); tick(); - expect(document.getElementsByClassName(CLASS_OVERLAY_WRAPPER)[0]).toBeFalsy(); + expect(overlayDiv.children.length).toBe(0); })); // Test #1883 #1820 @@ -2828,10 +2832,10 @@ describe('igxOverlay', () => { tick(); expect(overlayWrapper).toBeTruthy(); - overlayWrapper.dispatchEvent(enterEvent); - overlayWrapper.dispatchEvent(aEvent); - overlayWrapper.dispatchEvent(arrowUpEvent); - overlayWrapper.dispatchEvent(escEvent); + document.dispatchEvent(enterEvent); + document.dispatchEvent(aEvent); + document.dispatchEvent(arrowUpEvent); + document.dispatchEvent(escEvent); })); // 3.2 Non - Modal diff --git a/projects/igniteui-angular/src/lib/services/overlay/overlay.ts b/projects/igniteui-angular/src/lib/services/overlay/overlay.ts index 976db7792ea..91c7f5df10b 100644 --- a/projects/igniteui-angular/src/lib/services/overlay/overlay.ts +++ b/projects/igniteui-angular/src/lib/services/overlay/overlay.ts @@ -331,9 +331,7 @@ export class IgxOverlayService implements OnDestroy { wrapperElement.classList.add('igx-overlay__wrapper--modal'); } - if (info.settings.closeOnEsc) { - this.setUpCloseOnEscape(info); - } + this.setUpCloseOnEscape(); if (info.settings.positionStrategy.settings.openAnimation) { this.playOpenAnimation(info); @@ -476,13 +474,11 @@ export class IgxOverlayService implements OnDestroy { } } - private setUpCloseOnEscape(info: OverlayInfo) { - if (!info.settings.modal) { + private setUpCloseOnEscape() { + if (this._overlayInfos.length - this._overlayInfos.filter(x => x.closeAnimationPlayer + && x.closeAnimationPlayer.hasStarted()).length === 1) { this.subscribeOnEscape(this._document); - return; } - const wrapperElement = info.elementRef.nativeElement.parentElement.parentElement; - this.subscribeOnEscape(wrapperElement); } private subscribeOnEscape(target: FromEventTarget) { @@ -491,7 +487,9 @@ export class IgxOverlayService implements OnDestroy { takeUntil(this.destroy$) ).subscribe(() => { const targetOverlay = this._overlayInfos[this._overlayInfos.length - 1]; - this.hide(targetOverlay.id); + if (targetOverlay.settings.closeOnEsc) { + this.hide(targetOverlay.id); + } }); } @@ -712,6 +710,14 @@ export class IgxOverlayService implements OnDestroy { } } + private hasRemainingOverlaysAfterClose(): boolean { + // if all overlays minus closing overlays equals one add the handler + return this._overlayInfos.filter(x => x.settings.closeOnOutsideClick && !x.settings.modal).length - + this._overlayInfos.filter(x => x.settings.closeOnOutsideClick && !x.settings.modal && + x.closeAnimationPlayer && + x.closeAnimationPlayer.hasStarted()).length === 1; + } + private removeOutsideClickListener(info: OverlayInfo) { if (info.settings.modal === false) { let shouldRemoveClickEventListener = true; From 81702e41ce47f2de3eae6604f90522bf98f166f9 Mon Sep 17 00:00:00 2001 From: MKirova Date: Tue, 14 Jul 2020 19:26:38 +0300 Subject: [PATCH 38/53] feat(igxDatePicker): Adding new input - editorTabIndex that allows setting tabindex for the input in the default template. --- CHANGELOG.md | 2 ++ .../src/lib/date-picker/date-picker.component.html | 2 ++ .../src/lib/date-picker/date-picker.component.spec.ts | 7 +++++++ .../src/lib/date-picker/date-picker.component.ts | 9 +++++++++ 4 files changed, 20 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a9111b8e01..70d6389893e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ All notable changes for each version of this project will be documented in this - Added `onScroll` event, which is emitted when the grid is scrolled vertically or horizontally. - `igxTreeGrid` - Removed `onDataPreLoad` event as it is specific for remote virtualization implementation, which is not supported for the `igxTreeGrid`. A more generic `onScroll` event is exposed and can be used instead. +- `igxDatePicker` + - Added new property - `editorTabIndex`, that allows setting tabindex for the default editor. ### New Features - `IgxGrid`, `IgxTreeGrid`, `IgxHierarchicalGrid` diff --git a/projects/igniteui-angular/src/lib/date-picker/date-picker.component.html b/projects/igniteui-angular/src/lib/date-picker/date-picker.component.html index 673dc7b3c62..26c3e4f51e2 100644 --- a/projects/igniteui-angular/src/lib/date-picker/date-picker.component.html +++ b/projects/igniteui-angular/src/lib/date-picker/date-picker.component.html @@ -10,6 +10,7 @@ [value]="displayData || ''" [disabled]="disabled" (blur)="onBlur($event)" + [tabindex]='editorTabIndex' readonly /> @@ -36,6 +37,7 @@ (wheel)="onWheel($event)" (input)="onInput($event)" (focus)="onFocus()" + [tabindex]='editorTabIndex' /> clear diff --git a/projects/igniteui-angular/src/lib/date-picker/date-picker.component.spec.ts b/projects/igniteui-angular/src/lib/date-picker/date-picker.component.spec.ts index ab724154379..45955cebf4e 100644 --- a/projects/igniteui-angular/src/lib/date-picker/date-picker.component.spec.ts +++ b/projects/igniteui-angular/src/lib/date-picker/date-picker.component.spec.ts @@ -277,6 +277,13 @@ describe('IgxDatePicker', () => { expect(input).toEqual(document.activeElement); })); + it('should allow setting editorTabIndex', () => { + fixture.componentInstance.datePicker.editorTabIndex = 3; + fixture.detectChanges(); + const input = fixture.debugElement.query(By.directive(IgxInputDirective)).nativeElement; + expect(input.tabIndex).toBe(3); + }); + }); describe('DatePicker with passed date', () => { diff --git a/projects/igniteui-angular/src/lib/date-picker/date-picker.component.ts b/projects/igniteui-angular/src/lib/date-picker/date-picker.component.ts index 6a0fa20e661..d6b5b702984 100644 --- a/projects/igniteui-angular/src/lib/date-picker/date-picker.component.ts +++ b/projects/igniteui-angular/src/lib/date-picker/date-picker.component.ts @@ -177,6 +177,15 @@ export class IgxDatePickerComponent implements IDatePicker, ControlValueAccessor */ @Input() public locale: 'en'; + /** + * Gets/Sets the default template editor's tabindex. + * @example + * ```html + * + * ``` + */ + @Input() public editorTabIndex: number; + /** * Gets/Sets on which day the week starts. * @example From bfd59b8174b9bc037fad8a4b3721fe100cb707a4 Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Wed, 15 Jul 2020 11:08:44 +0300 Subject: [PATCH 39/53] feat(calendar): remove on prefix from events #7039 --- CHANGELOG.md | 4 ++-- .../src/lib/calendar/README.md | 6 ++--- .../src/lib/calendar/calendar-base.ts | 10 ++++---- .../lib/calendar/calendar.component.spec.ts | 24 +++++++++---------- .../src/lib/calendar/calendar.component.ts | 4 ++-- .../src/lib/calendar/month-picker/README.md | 6 ++--- .../month-picker/month-picker.component.ts | 4 ++-- .../calendar-views/calendar-views.sample.html | 4 ++-- .../calendar-views/calendar-views.sample.ts | 4 ++-- src/app/calendar/calendar.sample.html | 2 +- src/app/calendar/calendar.sample.ts | 4 ++-- 11 files changed, 36 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0bb69687c3a..883e7c97508 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,8 +38,8 @@ All notable changes for each version of this project will be documented in this - `IgxNavbar` - Added new `igx-navbar-title, igxNavbarTitle` directive that can be used to provide custom content for navbar title. It would override the value of `title` input property. - `IgxCalendar` and `IgxMonthPicker` - - `onViewDateChanged` emitted after the month/year presented in the view is changed after user interaction. - - `onActiveViewChanged` event emitted after the active view (DEFAULT, YEAR, DECADE) is changed after user interaction. + - `viewDateChanged` emitted after the month/year presented in the view is changed after user interaction. + - `activeViewChanged` event emitted after the active view (DEFAULT, YEAR, DECADE) is changed after user interaction. - `viewDate` day value is always 1. - `activeView` setter is now available as an input property. diff --git a/projects/igniteui-angular/src/lib/calendar/README.md b/projects/igniteui-angular/src/lib/calendar/README.md index 29da0cad44d..a2407c2df68 100644 --- a/projects/igniteui-angular/src/lib/calendar/README.md +++ b/projects/igniteui-angular/src/lib/calendar/README.md @@ -175,12 +175,12 @@ Controls the visibility of the dates that do not belong to the current month. Event fired when a value is selected through UI interaction. Emits the selected value (depending on the type of selection). -- `onViewDateChanged(): IViewDateChangeEventArgs` +- `viewDateChanged(): IViewDateChangeEventArgs` -Event fired after the the month/year presented in the view is changed. +Event fired after the month/year presented in the view is changed. Emits an object containing the previous and current value of the `viewDate` property. -- `onActiveViewChanged(): CalendarView` +- `activeViewChanged(): CalendarView` Event fired after the active view is changed. Emits an CalendarView enum, indicating the `activeView` property value. diff --git a/projects/igniteui-angular/src/lib/calendar/calendar-base.ts b/projects/igniteui-angular/src/lib/calendar/calendar-base.ts index e63c3e49e6e..2101e31d2ba 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar-base.ts +++ b/projects/igniteui-angular/src/lib/calendar/calendar-base.ts @@ -250,21 +250,21 @@ export class IgxCalendarBaseDirective implements ControlValueAccessor { /** * Emits an event when the month in view is changed. * ```html - * + * * ``` * ```typescript * public viewDateChanged(event: IViewDateChangeEventArgs) { - * let newDate = event.newViewDate; + * let viewDate = event.currentValue; * } * ``` */ @Output() - public onViewDateChanged = new EventEmitter(); + public viewDateChanged = new EventEmitter(); /** * Emits an event when the active view is changed. * ```html - * + * * ``` * ```typescript * public activeViewChanged(event: CalendarView) { @@ -273,7 +273,7 @@ export class IgxCalendarBaseDirective implements ControlValueAccessor { * ``` */ @Output() - public onActiveViewChanged = new EventEmitter(); + public activeViewChanged = new EventEmitter(); /** * @hidden diff --git a/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts b/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts index fe60587e978..74f74b31d09 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts +++ b/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts @@ -1588,14 +1588,14 @@ describe('IgxCalendar - ', () => { expect(year.nativeElement).toBe(document.activeElement); - spyOn(calendar.onActiveViewChanged, 'emit').and.callThrough(); + spyOn(calendar.activeViewChanged, 'emit').and.callThrough(); UIInteractions.triggerKeyDownEvtUponElem('Enter', document.activeElement); fixture.detectChanges(); tick(); - expect(calendar.onActiveViewChanged.emit).toHaveBeenCalledTimes(1); - expect(calendar.onActiveViewChanged.emit).toHaveBeenCalledWith(CalendarView.DECADE); + expect(calendar.activeViewChanged.emit).toHaveBeenCalledTimes(1); + expect(calendar.activeViewChanged.emit).toHaveBeenCalledWith(CalendarView.DECADE); const years = dom.queryAll(By.css(HelperTestFunctions.YEAR_CSSCLASS)); let currentYear = dom.query(By.css(HelperTestFunctions.CURRENT_YEAR_CSSCLASS)); @@ -1617,7 +1617,7 @@ describe('IgxCalendar - ', () => { expect(currentYear.nativeElement.textContent.trim()).toMatch('2016'); const previousValue = fixture.componentInstance.calendar.viewDate; - spyOn(calendar.onViewDateChanged, 'emit').and.callThrough(); + spyOn(calendar.viewDateChanged, 'emit').and.callThrough(); UIInteractions.triggerKeyDownEvtUponElem('Enter', currentYear.nativeElement); @@ -1625,15 +1625,15 @@ describe('IgxCalendar - ', () => { tick(); const eventArgs: IViewDateChangeEventArgs = { previousValue, currentValue: fixture.componentInstance.calendar.viewDate }; - expect(calendar.onViewDateChanged.emit).toHaveBeenCalledTimes(1); - expect(calendar.onViewDateChanged.emit).toHaveBeenCalledWith(eventArgs); + expect(calendar.viewDateChanged.emit).toHaveBeenCalledTimes(1); + expect(calendar.viewDateChanged.emit).toHaveBeenCalledWith(eventArgs); expect(calendar.viewDate.getFullYear()).toEqual(2016); })); it('Should open months view, navigate through and select a month via KB.', fakeAsync(() => { const month = dom.queryAll(By.css(HelperTestFunctions.CALENDAR_DATE_CSSCLASS))[0]; month.nativeElement.focus(); - spyOn(calendar.onActiveViewChanged, 'emit').and.callThrough(); + spyOn(calendar.activeViewChanged, 'emit').and.callThrough(); expect(month.nativeElement).toBe(document.activeElement); @@ -1641,8 +1641,8 @@ describe('IgxCalendar - ', () => { fixture.detectChanges(); tick(); - expect(calendar.onActiveViewChanged.emit).toHaveBeenCalledTimes(1); - expect(calendar.onActiveViewChanged.emit).toHaveBeenCalledWith(CalendarView.YEAR); + expect(calendar.activeViewChanged.emit).toHaveBeenCalledTimes(1); + expect(calendar.activeViewChanged.emit).toHaveBeenCalledWith(CalendarView.YEAR); const months = dom.queryAll(By.css(HelperTestFunctions.MONTH_CSSCLASS)); const currentMonth = dom.query(By.css(HelperTestFunctions.CURRENT_MONTH_CSSCLASS)); @@ -1672,15 +1672,15 @@ describe('IgxCalendar - ', () => { expect(document.activeElement.textContent.trim()).toMatch('Sep'); const previousValue = fixture.componentInstance.calendar.viewDate; - spyOn(calendar.onViewDateChanged, 'emit').and.callThrough(); + spyOn(calendar.viewDateChanged, 'emit').and.callThrough(); UIInteractions.triggerKeyDownEvtUponElem('Enter', document.activeElement); fixture.detectChanges(); tick(); const eventArgs: IViewDateChangeEventArgs = { previousValue, currentValue: fixture.componentInstance.calendar.viewDate }; - expect(calendar.onViewDateChanged.emit).toHaveBeenCalledTimes(1); - expect(calendar.onViewDateChanged.emit).toHaveBeenCalledWith(eventArgs); + expect(calendar.viewDateChanged.emit).toHaveBeenCalledTimes(1); + expect(calendar.viewDateChanged.emit).toHaveBeenCalledWith(eventArgs); expect(calendar.viewDate.getMonth()).toEqual(8); })); diff --git a/projects/igniteui-angular/src/lib/calendar/calendar.component.ts b/projects/igniteui-angular/src/lib/calendar/calendar.component.ts index e6926140659..723f951b2e9 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/calendar.component.ts @@ -717,7 +717,7 @@ export class IgxCalendarComponent extends IgxMonthPickerBaseDirective implements public animationDone(event) { if ((event.fromState === ScrollMonth.NONE && (event.toState === ScrollMonth.PREV || event.toState === ScrollMonth.NEXT)) || (event.fromState === 'void' && event.toState === ScrollMonth.NONE)) { - this.onViewDateChanged.emit({ previousValue: this.previousViewDate, currentValue: this.viewDate }); + this.viewDateChanged.emit({ previousValue: this.previousViewDate, currentValue: this.viewDate }); } if (this.monthScrollDirection !== ScrollMonth.NONE) { @@ -751,7 +751,7 @@ export class IgxCalendarComponent extends IgxMonthPickerBaseDirective implements */ public viewRendered(event) { if (event.fromState !== 'void') { - this.onActiveViewChanged.emit(this.activeView); + this.activeViewChanged.emit(this.activeView); } } diff --git a/projects/igniteui-angular/src/lib/calendar/month-picker/README.md b/projects/igniteui-angular/src/lib/calendar/month-picker/README.md index 3dbed313ca0..277084ec8af 100644 --- a/projects/igniteui-angular/src/lib/calendar/month-picker/README.md +++ b/projects/igniteui-angular/src/lib/calendar/month-picker/README.md @@ -122,12 +122,12 @@ The default values are listed below. Event fired when a value is selected through UI interaction. Returns the selected value (depending on the type of selection). -- `onViewDateChanged(): IViewDateChangeEventArgs` +- `viewDateChanged(): IViewDateChangeEventArgs` -Event fired after the the month/year presented in the view is changed. +Event fired after the month/year presented in the view is changed. Emits an object containing the previous and current value of the `viewDate` property. -- `onActiveViewChanged(): CalendarView` +- `activeViewChanged(): CalendarView` Event fired after the active view is changed. Emits an CalendarView enum, indicating the `activeView` property value. diff --git a/projects/igniteui-angular/src/lib/calendar/month-picker/month-picker.component.ts b/projects/igniteui-angular/src/lib/calendar/month-picker/month-picker.component.ts index 3bd46b9ed5d..ff6d92e7a34 100644 --- a/projects/igniteui-angular/src/lib/calendar/month-picker/month-picker.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/month-picker/month-picker.component.ts @@ -103,7 +103,7 @@ export class IgxMonthPickerComponent extends IgxMonthPickerBaseDirective { public animationDone(event) { if ((event.fromState === 'void' && event.toState === '') || (event.fromState === '' && (event.toState === ScrollMonth.PREV || event.toState === ScrollMonth.NEXT))) { - this.onViewDateChanged.emit({ previousValue: this.previousViewDate, currentValue: this.viewDate }); + this.viewDateChanged.emit({ previousValue: this.previousViewDate, currentValue: this.viewDate }); } this.yearAction = ''; } @@ -113,7 +113,7 @@ export class IgxMonthPickerComponent extends IgxMonthPickerBaseDirective { */ public viewRendered(event) { if (event.fromState !== 'void') { - this.onActiveViewChanged.emit(this.activeView); + this.activeViewChanged.emit(this.activeView); } } diff --git a/src/app/calendar-views/calendar-views.sample.html b/src/app/calendar-views/calendar-views.sample.html index d3e5b293e21..aa4deb60ea3 100644 --- a/src/app/calendar-views/calendar-views.sample.html +++ b/src/app/calendar-views/calendar-views.sample.html @@ -11,8 +11,8 @@

Month Picker

[formatOptions]="formatOptions" [locale]="localeDe" (onSelection)="onSelection($event)" - (onViewDateChanged)="onViewDateChanged($event)" - (onActiveViewChanged)="onActiveViewChanged($event)" > + (viewDateChanged)="viewDateChanged($event)" + (activeViewChanged)="activeViewChanged($event)" >
{{ date1 }} diff --git a/src/app/calendar-views/calendar-views.sample.ts b/src/app/calendar-views/calendar-views.sample.ts index cdf43c90530..8904ded8cc3 100644 --- a/src/app/calendar-views/calendar-views.sample.ts +++ b/src/app/calendar-views/calendar-views.sample.ts @@ -101,11 +101,11 @@ export class CalendarViewsSampleComponent implements OnInit { // this.daysView.deselectDate([new Date(2019, 1, 13), new Date(2019, 1, 14)]); } - public onViewDateChanged(event: Date) { + public viewDateChanged(event: Date) { const date = event; console.log(date); } - public onActiveViewChanged(event: CalendarView) { + public activeViewChanged(event: CalendarView) { } } diff --git a/src/app/calendar/calendar.sample.html b/src/app/calendar/calendar.sample.html index 88558788b7c..6b7a4eb67db 100644 --- a/src/app/calendar/calendar.sample.html +++ b/src/app/calendar/calendar.sample.html @@ -24,7 +24,7 @@

Default Calendar

- +
diff --git a/src/app/calendar/calendar.sample.ts b/src/app/calendar/calendar.sample.ts index 708d49cf4d7..7cf35edadfa 100644 --- a/src/app/calendar/calendar.sample.ts +++ b/src/app/calendar/calendar.sample.ts @@ -41,11 +41,11 @@ export class CalendarSampleComponent implements OnInit { const date = event; } - public onViewDateChanged(event: IViewDateChangeEventArgs) { + public viewDateChanged(event: IViewDateChangeEventArgs) { console.log(event); } - public onActiveViewChanged(event: CalendarView) { + public activeViewChanged(event: CalendarView) { } public setSelection(args: string) { From 5989592299af42df6166e198ee7edbe3c728b9d6 Mon Sep 17 00:00:00 2001 From: wnvko Date: Wed, 15 Jul 2020 11:23:12 +0300 Subject: [PATCH 40/53] refactor(overlay): change some method names and refactor tests --- .../src/lib/services/overlay/overlay.spec.ts | 115 ++++++++---------- .../src/lib/services/overlay/overlay.ts | 45 +++---- 2 files changed, 71 insertions(+), 89 deletions(-) diff --git a/projects/igniteui-angular/src/lib/services/overlay/overlay.spec.ts b/projects/igniteui-angular/src/lib/services/overlay/overlay.spec.ts index c0993c9d3ca..cc4336bbbbd 100644 --- a/projects/igniteui-angular/src/lib/services/overlay/overlay.spec.ts +++ b/projects/igniteui-angular/src/lib/services/overlay/overlay.spec.ts @@ -9,7 +9,7 @@ import { ComponentRef } from '@angular/core'; import { TestBed, fakeAsync, tick, async, inject } from '@angular/core/testing'; -import { BrowserModule } from '@angular/platform-browser'; +import { BrowserModule, By } from '@angular/platform-browser'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { IgxOverlayService } from './overlay'; import { IgxToggleDirective, IgxToggleModule, IgxOverlayOutletDirective } from './../../directives/toggle/toggle.directive'; @@ -2718,61 +2718,43 @@ describe('igxOverlay', () => { const fixture = TestBed.createComponent(EmptyPageComponent); const overlay = fixture.componentInstance.overlay; const overlaySettings: OverlaySettings = { - modal: true, closeOnEsc: true, - positionStrategy: new GlobalPositionStrategy() }; - const targetButton = 'Escape'; - const escEvent = new KeyboardEvent('keydown', { - key: targetButton - }); - overlay.show(overlay.attach(SimpleDynamicComponent), overlaySettings); tick(); let overlayWrapper = document.getElementsByClassName(CLASS_OVERLAY_WRAPPER_MODAL)[0]; - overlayWrapper.addEventListener('keydown', (event: KeyboardEvent) => { - if (event.key === targetButton) { - overlayWrapper = document.getElementsByClassName(CLASS_OVERLAY_WRAPPER_MODAL)[0]; - expect(overlayWrapper).toBeFalsy(); - } - }); - tick(); expect(overlayWrapper).toBeTruthy(); - document.dispatchEvent(escEvent); + + UIInteractions.triggerKeyDownEvtUponElem('Escape', document); tick(); + + overlayWrapper = document.getElementsByClassName(CLASS_OVERLAY_WRAPPER_MODAL)[0]; + expect(overlayWrapper).toBeFalsy(); })); it('Should not close the component when esc key is pressed and closeOnEsc is false', fakeAsync(() => { const fixture = TestBed.createComponent(EmptyPageComponent); const overlay = fixture.componentInstance.overlay; const overlaySettings: OverlaySettings = { - modal: true, - positionStrategy: new GlobalPositionStrategy() + closeOnEsc: false }; - const targetButton = 'Escape'; - const escEvent = new KeyboardEvent('keydown', { - key: targetButton - }); overlay.show(overlay.attach(SimpleDynamicComponent), overlaySettings); tick(); let overlayWrapper = document.getElementsByClassName(CLASS_OVERLAY_WRAPPER_MODAL)[0]; - overlayWrapper.addEventListener('keydown', (event: KeyboardEvent) => { - if (event.key === targetButton) { - overlayWrapper = document.getElementsByClassName(CLASS_OVERLAY_WRAPPER_MODAL)[0]; - } - }); - document.dispatchEvent(escEvent); + expect(overlayWrapper).toBeTruthy(); + + UIInteractions.triggerKeyDownEvtUponElem('Escape', document); tick(); - fixture.detectChanges(); + overlayWrapper = document.getElementsByClassName(CLASS_OVERLAY_WRAPPER_MODAL)[0]; expect(overlayWrapper).toBeTruthy(); })); - it('Should close the opened overlays consecutively on escape keypress', fakeAsync(() => { + it('Should close the opened overlays consecutively on esc keypress', fakeAsync(() => { const fixture = TestBed.createComponent(EmptyPageComponent); const overlay = fixture.componentInstance.overlay; overlay.show(overlay.attach(SimpleDynamicComponent), { closeOnEsc: true }); @@ -2783,59 +2765,70 @@ describe('igxOverlay', () => { const overlayDiv = document.getElementsByClassName(CLASS_OVERLAY_MAIN)[0]; expect(overlayDiv.children.length).toBe(2); - const escEvent = new KeyboardEvent('keydown', { - key: 'Escape' - }); - - document.dispatchEvent(escEvent); + UIInteractions.triggerKeyDownEvtUponElem('Escape', document); tick(); expect(overlayDiv.children.length).toBe(1); - document.dispatchEvent(escEvent); + UIInteractions.triggerKeyDownEvtUponElem('Escape', document); tick(); expect(overlayDiv.children.length).toBe(0); })); + it('Should not close the opened overlays consecutively on esc keypress', fakeAsync(() => { + const fixture = TestBed.createComponent(EmptyPageComponent); + const overlay = fixture.componentInstance.overlay; + overlay.show(overlay.attach(SimpleDynamicComponent), { closeOnEsc: true }); + tick(); + overlay.show(overlay.attach(SimpleDynamicComponent), { closeOnEsc: false }); + tick(); + overlay.show(overlay.attach(SimpleDynamicComponent), { closeOnEsc: true }); + tick(); + + const overlayDiv = document.getElementsByClassName(CLASS_OVERLAY_MAIN)[0]; + expect(overlayDiv.children.length).toBe(3); + + UIInteractions.triggerKeyDownEvtUponElem('Escape', document); + tick(); + expect(overlayDiv.children.length).toBe(2); + + UIInteractions.triggerKeyDownEvtUponElem('Escape', document); + tick(); + expect(overlayDiv.children.length).toBe(2); + })); + // Test #1883 #1820 it('It should close the component when esc key is pressed and there were other keys pressed prior to esc.', fakeAsync(() => { const fixture = TestBed.createComponent(EmptyPageComponent); const overlay = fixture.componentInstance.overlay; const overlaySettings: OverlaySettings = { - modal: true, closeOnEsc: true, - positionStrategy: new GlobalPositionStrategy() }; - const escEvent = new KeyboardEvent('keydown', { - key: 'Escape' - }); - const enterEvent = new KeyboardEvent('keydown', { - key: 'Enter' - }); - const arrowUpEvent = new KeyboardEvent('keydown', { - key: 'ArrowUp' - }); - const aEvent = new KeyboardEvent('keydown', { - key: 'a' - }); - overlay.show(overlay.attach(SimpleDynamicComponent), overlaySettings); tick(); let overlayWrapper = document.getElementsByClassName(CLASS_OVERLAY_WRAPPER_MODAL)[0]; - overlayWrapper.addEventListener('keydown', (event: KeyboardEvent) => { - if (event.key === 'Escape') { - overlayWrapper = document.getElementsByClassName(CLASS_OVERLAY_WRAPPER_MODAL)[0]; - expect(overlayWrapper).toBeFalsy(); - } - }); + expect(overlayWrapper).toBeTruthy(); + + UIInteractions.triggerKeyDownEvtUponElem('Enter', document); tick(); + overlayWrapper = document.getElementsByClassName(CLASS_OVERLAY_WRAPPER_MODAL)[0]; expect(overlayWrapper).toBeTruthy(); - document.dispatchEvent(enterEvent); - document.dispatchEvent(aEvent); - document.dispatchEvent(arrowUpEvent); - document.dispatchEvent(escEvent); + UIInteractions.triggerKeyDownEvtUponElem('a', document); + tick(); + overlayWrapper = document.getElementsByClassName(CLASS_OVERLAY_WRAPPER_MODAL)[0]; + expect(overlayWrapper).toBeTruthy(); + + UIInteractions.triggerKeyDownEvtUponElem('ArrowUp', document); + tick(); + overlayWrapper = document.getElementsByClassName(CLASS_OVERLAY_WRAPPER_MODAL)[0]; + expect(overlayWrapper).toBeTruthy(); + + UIInteractions.triggerKeyDownEvtUponElem('Escape', document); + tick(); + overlayWrapper = document.getElementsByClassName(CLASS_OVERLAY_WRAPPER_MODAL)[0]; + expect(overlayWrapper).toBeFalsy(); })); // 3.2 Non - Modal diff --git a/projects/igniteui-angular/src/lib/services/overlay/overlay.ts b/projects/igniteui-angular/src/lib/services/overlay/overlay.ts index 91c7f5df10b..0f6fcdc70f3 100644 --- a/projects/igniteui-angular/src/lib/services/overlay/overlay.ts +++ b/projects/igniteui-angular/src/lib/services/overlay/overlay.ts @@ -323,6 +323,7 @@ export class IgxOverlayService implements OnDestroy { this.addOutsideClickListener(info); this.addResizeHandler(info.id); + this.addCloseOnEscapeListener(); if (info.settings.modal) { const wrapperElement = info.elementRef.nativeElement.parentElement.parentElement; @@ -331,7 +332,6 @@ export class IgxOverlayService implements OnDestroy { wrapperElement.classList.add('igx-overlay__wrapper--modal'); } - this.setUpCloseOnEscape(); if (info.settings.positionStrategy.settings.openAnimation) { this.playOpenAnimation(info); @@ -474,25 +474,6 @@ export class IgxOverlayService implements OnDestroy { } } - private setUpCloseOnEscape() { - if (this._overlayInfos.length - this._overlayInfos.filter(x => x.closeAnimationPlayer - && x.closeAnimationPlayer.hasStarted()).length === 1) { - this.subscribeOnEscape(this._document); - } - } - - private subscribeOnEscape(target: FromEventTarget) { - fromEvent(target, 'keydown').pipe( - filter((ev: KeyboardEvent) => ev.key === 'Escape' || ev.key === 'Esc'), - takeUntil(this.destroy$) - ).subscribe(() => { - const targetOverlay = this._overlayInfos[this._overlayInfos.length - 1]; - if (targetOverlay.settings.closeOnEsc) { - this.hide(targetOverlay.id); - } - }); - } - private onCloseDone(info: OverlayInfo) { this.cleanUp(info); this.onClosed.emit({ id: info.id, componentRef: info.componentRef }); @@ -710,14 +691,6 @@ export class IgxOverlayService implements OnDestroy { } } - private hasRemainingOverlaysAfterClose(): boolean { - // if all overlays minus closing overlays equals one add the handler - return this._overlayInfos.filter(x => x.settings.closeOnOutsideClick && !x.settings.modal).length - - this._overlayInfos.filter(x => x.settings.closeOnOutsideClick && !x.settings.modal && - x.closeAnimationPlayer && - x.closeAnimationPlayer.hasStarted()).length === 1; - } - private removeOutsideClickListener(info: OverlayInfo) { if (info.settings.modal === false) { let shouldRemoveClickEventListener = true; @@ -753,6 +726,22 @@ export class IgxOverlayService implements OnDestroy { } } + private addCloseOnEscapeListener() { + // if all overlays minus closing overlays equals one add the handler + if (this._overlayInfos.length - this._overlayInfos.filter(x => x.closeAnimationPlayer + && x.closeAnimationPlayer.hasStarted()).length === 1) { + fromEvent(this._document, 'keydown').pipe( + filter((ev: KeyboardEvent) => ev.key === 'Escape' || ev.key === 'Esc'), + takeUntil(this.destroy$) + ).subscribe(() => { + const targetOverlay = this._overlayInfos[this._overlayInfos.length - 1]; + if (targetOverlay.settings.closeOnEsc) { + this.hide(targetOverlay.id); + } + }); + } + } + /** @hidden */ public repositionAll = () => { for (let i = this._overlayInfos.length; i--;) { From 5a791105218d07e7543e3b93df0d5051c443df90 Mon Sep 17 00:00:00 2001 From: plamenamiteva Date: Wed, 15 Jul 2020 13:03:09 +0300 Subject: [PATCH 41/53] docs(combo): remove breaking change from changelog #7282 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e50ac5f3781..dadb1d1c46d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ All notable changes for each version of this project will be documented in this ### General - `igxCombo` - **Behavioral Change** - Change default positioning strategy from `ConnectedPositioningStrategy` to `AutoPositionStrategy`. The [`Auto`](https://www.infragistics.com/products/ignite-ui-angular/angular/components/overlay_position.html#auto) strategy will initially try to show the element like the Connected strategy does. If the element goes out of the viewport Auto will flip the starting point and the direction, i.e. if the direction is 'bottom', it will switch it to 'top' and so on. If after flipping direction the content goes out of the view, auto strategy will revert to initial start point and direction and will push the content into the view. Note after pushing the content it may hide the combo's input. - - **Breaking Change** - Make `onSearchInput` event cancellable. The event args type has been changed to `IComboSearchInputEventArgs`, which have two properties: `change` - holds the change in the search input and `cancel` - indicates whether the event should be canceled. + - Make `onSearchInput` event cancellable. The event args type has been changed to `IComboSearchInputEventArgs`, which have two properties: `change` - holds the change in the search input and `cancel` - indicates whether the event should be canceled. - `IgxOverlay` - Added new property - `closeOnEsc` - in `OverlaySettings`. The overlay can now be prevented from closing, on escape keypress, by setting the property to `false`, by default it's `true`. - `igxDialog` From 6c01d4174ee52d3e972c735862af6b387ca73631 Mon Sep 17 00:00:00 2001 From: wnvko Date: Wed, 15 Jul 2020 17:14:37 +0300 Subject: [PATCH 42/53] docs(overlay): update closeOnEsc related docs in CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f7d0b2e233..eb6d81e96a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ All notable changes for each version of this project will be documented in this - `igxCombo` - **Behavioral Change** - Change default positioning strategy from `ConnectedPositioningStrategy` to `AutoPositionStrategy`. The [`Auto`](https://www.infragistics.com/products/ignite-ui-angular/angular/components/overlay_position.html#auto) strategy will initially try to show the element like the Connected strategy does. If the element goes out of the viewport Auto will flip the starting point and the direction, i.e. if the direction is 'bottom', it will switch it to 'top' and so on. If after flipping direction the content goes out of the view, auto strategy will revert to initial start point and direction and will push the content into the view. Note after pushing the content it may hide the combo's input. - `IgxOverlay` - - Added new property - `closeOnEsc` - in `OverlaySettings`. The overlay can now be prevented from closing, on escape keypress, by setting the property to `false`, it is `false` by default. + - **Behavioral Change** - Added new property `closeOnEsc` in `OverlaySettings`. Should overlay close or not on escape keypress can now be controlled via this new property. By default `closeOnEsc` is set to `false`. - `igxDialog` - Added `closeOnEscapeKey` - with it, the dialog can be allowed or prevented from closing when `Esc` is pressed. - `IgxNavbar`: From eae84a46edd740d54c44762e519a3f94fcc7009e Mon Sep 17 00:00:00 2001 From: plamenamiteva Date: Wed, 15 Jul 2020 18:23:05 +0300 Subject: [PATCH 43/53] chore(combo): rename change to searchTerm #7282 --- CHANGELOG.md | 2 +- .../igniteui-angular/src/lib/combo/combo.component.spec.ts | 4 ++-- projects/igniteui-angular/src/lib/combo/combo.component.ts | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b62997f8eca..bd1a98e4809 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ All notable changes for each version of this project will be documented in this ### General - `igxCombo` - **Behavioral Change** - Change default positioning strategy from `ConnectedPositioningStrategy` to `AutoPositionStrategy`. The [`Auto`](https://www.infragistics.com/products/ignite-ui-angular/angular/components/overlay_position.html#auto) strategy will initially try to show the element like the Connected strategy does. If the element goes out of the viewport Auto will flip the starting point and the direction, i.e. if the direction is 'bottom', it will switch it to 'top' and so on. If after flipping direction the content goes out of the view, auto strategy will revert to initial start point and direction and will push the content into the view. Note after pushing the content it may hide the combo's input. - - Make `onSearchInput` event cancellable. The event args type has been changed to `IComboSearchInputEventArgs`, which have two properties: `change` - holds the change in the search input and `cancel` - indicates whether the event should be canceled. + - Make `onSearchInput` event cancellable. The event args type has been changed to `IComboSearchInputEventArgs`, which have two properties: `searchTerm` - holds the change in the search input and `cancel` - indicates whether the event should be canceled. - `IgxOverlay` - Added new property - `closeOnEsc` - in `OverlaySettings`. The overlay can now be prevented from closing, on escape keypress, by setting the property to `false`, by default it's `true`. - `igxDialog` diff --git a/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts b/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts index 03faf6a1fba..a047d139725 100644 --- a/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts +++ b/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts @@ -532,7 +532,7 @@ describe('igxCombo', () => { expect(combo.onSearchInput.emit).toHaveBeenCalledTimes(0); const args = { - change: 'Fake', + searchTerm: 'Fake', cancel: false }; combo.handleInputChange('Fake'); @@ -540,7 +540,7 @@ describe('igxCombo', () => { expect(combo.onSearchInput.emit).toHaveBeenCalledTimes(1); expect(combo.onSearchInput.emit).toHaveBeenCalledWith(args); - args.change = ''; + args.searchTerm = ''; combo.handleInputChange(''); expect(matchSpy).toHaveBeenCalledTimes(3); expect(combo.onSearchInput.emit).toHaveBeenCalledTimes(2); diff --git a/projects/igniteui-angular/src/lib/combo/combo.component.ts b/projects/igniteui-angular/src/lib/combo/combo.component.ts index ca2ea3308a8..36a621df99f 100644 --- a/projects/igniteui-angular/src/lib/combo/combo.component.ts +++ b/projects/igniteui-angular/src/lib/combo/combo.component.ts @@ -99,7 +99,7 @@ export interface IComboSelectionChangeEventArgs extends CancelableEventArgs, IBa /** Event emitted when the igx-combo's search input changes */ export interface IComboSearchInputEventArgs extends CancelableEventArgs { /** The change that has been made to the search input */ - change: string; + searchTerm: string; } export interface IComboItemAdditionEvent extends IBaseEventArgs { @@ -988,7 +988,7 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas public handleInputChange(event?: string) { if (event !== undefined) { const args: IComboSearchInputEventArgs = { - change: event, + searchTerm: event, cancel: false }; this.onSearchInput.emit(args); From 65a78797d86120d1e4be1690dd081413d0a4ffdb Mon Sep 17 00:00:00 2001 From: Milko Venkov Date: Thu, 16 Jul 2020 10:07:18 +0300 Subject: [PATCH 44/53] Update CHANGELOG.md Co-authored-by: Damyan Petev --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eb6d81e96a3..996acda6f2d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,8 @@ All notable changes for each version of this project will be documented in this - `igxCombo` - **Behavioral Change** - Change default positioning strategy from `ConnectedPositioningStrategy` to `AutoPositionStrategy`. The [`Auto`](https://www.infragistics.com/products/ignite-ui-angular/angular/components/overlay_position.html#auto) strategy will initially try to show the element like the Connected strategy does. If the element goes out of the viewport Auto will flip the starting point and the direction, i.e. if the direction is 'bottom', it will switch it to 'top' and so on. If after flipping direction the content goes out of the view, auto strategy will revert to initial start point and direction and will push the content into the view. Note after pushing the content it may hide the combo's input. - `IgxOverlay` - - **Behavioral Change** - Added new property `closeOnEsc` in `OverlaySettings`. Should overlay close or not on escape keypress can now be controlled via this new property. By default `closeOnEsc` is set to `false`. + - Added new property `closeOnEsc` in `OverlaySettings` that controls whether the overlay should close on escape keypress. By default `closeOnEsc` is set to `false`. + - **Behavioral Change** - `modal` overlays shown directly through the Overlay Service no longer close on Escape by default. That behavior can now be specified using the `closeOnEsc` property. - `igxDialog` - Added `closeOnEscapeKey` - with it, the dialog can be allowed or prevented from closing when `Esc` is pressed. - `IgxNavbar`: From bd75a1f6d38dfe0307e5f833af40ed8889e24317 Mon Sep 17 00:00:00 2001 From: plamenamiteva Date: Thu, 16 Jul 2020 13:59:18 +0300 Subject: [PATCH 45/53] chore(combo): extend IBaseEventArgs & rename searchTerm #7282 --- CHANGELOG.md | 2 +- .../src/lib/combo/combo.component.ts | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd1a98e4809..4df14ed04d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ All notable changes for each version of this project will be documented in this ### General - `igxCombo` - **Behavioral Change** - Change default positioning strategy from `ConnectedPositioningStrategy` to `AutoPositionStrategy`. The [`Auto`](https://www.infragistics.com/products/ignite-ui-angular/angular/components/overlay_position.html#auto) strategy will initially try to show the element like the Connected strategy does. If the element goes out of the viewport Auto will flip the starting point and the direction, i.e. if the direction is 'bottom', it will switch it to 'top' and so on. If after flipping direction the content goes out of the view, auto strategy will revert to initial start point and direction and will push the content into the view. Note after pushing the content it may hide the combo's input. - - Make `onSearchInput` event cancellable. The event args type has been changed to `IComboSearchInputEventArgs`, which have two properties: `searchTerm` - holds the change in the search input and `cancel` - indicates whether the event should be canceled. + - Make `onSearchInput` event cancellable. The event args type has been changed to `IComboSearchInputEventArgs`, which have the following properties: `searchText` - holds the text typed into the search input and `cancel` - indicates whether the event should be canceled. - `IgxOverlay` - Added new property - `closeOnEsc` - in `OverlaySettings`. The overlay can now be prevented from closing, on escape keypress, by setting the property to `false`, by default it's `true`. - `igxDialog` diff --git a/projects/igniteui-angular/src/lib/combo/combo.component.ts b/projects/igniteui-angular/src/lib/combo/combo.component.ts index 36a621df99f..d11e6b18bd5 100644 --- a/projects/igniteui-angular/src/lib/combo/combo.component.ts +++ b/projects/igniteui-angular/src/lib/combo/combo.component.ts @@ -81,7 +81,7 @@ export enum IgxComboState { } /** Event emitted when an igx-combo's selection is changing */ -export interface IComboSelectionChangeEventArgs extends CancelableEventArgs, IBaseEventArgs { +export interface IComboSelectionChangeEventArgs extends CancelableEventArgs, IBaseEventonSeaArgs { /** An array containing the values that are currently selected */ oldSelection: any[]; /** An array containing the values that will be selected after this event */ @@ -97,9 +97,9 @@ export interface IComboSelectionChangeEventArgs extends CancelableEventArgs, IBa } /** Event emitted when the igx-combo's search input changes */ -export interface IComboSearchInputEventArgs extends CancelableEventArgs { - /** The change that has been made to the search input */ - searchTerm: string; +export interface IComboSearchInputEventArgs extends CancelableEventArgs, IBaseEventArgs { + /** The text that has been typed into the search input */ + searchText: string; } export interface IComboItemAdditionEvent extends IBaseEventArgs { @@ -489,7 +489,7 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas * ``` */ @Output() - public onSearchInput = new EventEmitter(); + public onSearchInput = new EventEmitter(); /** * Emitted when new chunk of data is loaded from the virtualization @@ -988,7 +988,7 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas public handleInputChange(event?: string) { if (event !== undefined) { const args: IComboSearchInputEventArgs = { - searchTerm: event, + searchText: event, cancel: false }; this.onSearchInput.emit(args); From af45ba8bfcc7ea1daeadde93c2e4cfbb52f90ac2 Mon Sep 17 00:00:00 2001 From: plamenamiteva Date: Thu, 16 Jul 2020 13:59:18 +0300 Subject: [PATCH 46/53] chore(combo): extend IBaseEventArgs & rename searchTerm #7282 --- CHANGELOG.md | 2 +- .../src/lib/combo/combo.component.spec.ts | 4 ++-- .../igniteui-angular/src/lib/combo/combo.component.ts | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd1a98e4809..4df14ed04d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ All notable changes for each version of this project will be documented in this ### General - `igxCombo` - **Behavioral Change** - Change default positioning strategy from `ConnectedPositioningStrategy` to `AutoPositionStrategy`. The [`Auto`](https://www.infragistics.com/products/ignite-ui-angular/angular/components/overlay_position.html#auto) strategy will initially try to show the element like the Connected strategy does. If the element goes out of the viewport Auto will flip the starting point and the direction, i.e. if the direction is 'bottom', it will switch it to 'top' and so on. If after flipping direction the content goes out of the view, auto strategy will revert to initial start point and direction and will push the content into the view. Note after pushing the content it may hide the combo's input. - - Make `onSearchInput` event cancellable. The event args type has been changed to `IComboSearchInputEventArgs`, which have two properties: `searchTerm` - holds the change in the search input and `cancel` - indicates whether the event should be canceled. + - Make `onSearchInput` event cancellable. The event args type has been changed to `IComboSearchInputEventArgs`, which have the following properties: `searchText` - holds the text typed into the search input and `cancel` - indicates whether the event should be canceled. - `IgxOverlay` - Added new property - `closeOnEsc` - in `OverlaySettings`. The overlay can now be prevented from closing, on escape keypress, by setting the property to `false`, by default it's `true`. - `igxDialog` diff --git a/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts b/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts index a047d139725..c66b9d08f77 100644 --- a/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts +++ b/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts @@ -532,7 +532,7 @@ describe('igxCombo', () => { expect(combo.onSearchInput.emit).toHaveBeenCalledTimes(0); const args = { - searchTerm: 'Fake', + searchText: 'Fake', cancel: false }; combo.handleInputChange('Fake'); @@ -540,7 +540,7 @@ describe('igxCombo', () => { expect(combo.onSearchInput.emit).toHaveBeenCalledTimes(1); expect(combo.onSearchInput.emit).toHaveBeenCalledWith(args); - args.searchTerm = ''; + args.searchText = ''; combo.handleInputChange(''); expect(matchSpy).toHaveBeenCalledTimes(3); expect(combo.onSearchInput.emit).toHaveBeenCalledTimes(2); diff --git a/projects/igniteui-angular/src/lib/combo/combo.component.ts b/projects/igniteui-angular/src/lib/combo/combo.component.ts index 36a621df99f..309bdd088b4 100644 --- a/projects/igniteui-angular/src/lib/combo/combo.component.ts +++ b/projects/igniteui-angular/src/lib/combo/combo.component.ts @@ -97,9 +97,9 @@ export interface IComboSelectionChangeEventArgs extends CancelableEventArgs, IBa } /** Event emitted when the igx-combo's search input changes */ -export interface IComboSearchInputEventArgs extends CancelableEventArgs { - /** The change that has been made to the search input */ - searchTerm: string; +export interface IComboSearchInputEventArgs extends CancelableEventArgs, IBaseEventArgs { + /** The text that has been typed into the search input */ + searchText: string; } export interface IComboItemAdditionEvent extends IBaseEventArgs { @@ -988,7 +988,7 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas public handleInputChange(event?: string) { if (event !== undefined) { const args: IComboSearchInputEventArgs = { - searchTerm: event, + searchText: event, cancel: false }; this.onSearchInput.emit(args); From a71a892503c9db27c79871d3f0e042f39feb26f9 Mon Sep 17 00:00:00 2001 From: plamenamiteva Date: Thu, 16 Jul 2020 14:28:19 +0300 Subject: [PATCH 47/53] chore(combo): fix typos #7282 --- projects/igniteui-angular/src/lib/combo/combo.component.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/projects/igniteui-angular/src/lib/combo/combo.component.ts b/projects/igniteui-angular/src/lib/combo/combo.component.ts index d11e6b18bd5..309bdd088b4 100644 --- a/projects/igniteui-angular/src/lib/combo/combo.component.ts +++ b/projects/igniteui-angular/src/lib/combo/combo.component.ts @@ -81,7 +81,7 @@ export enum IgxComboState { } /** Event emitted when an igx-combo's selection is changing */ -export interface IComboSelectionChangeEventArgs extends CancelableEventArgs, IBaseEventonSeaArgs { +export interface IComboSelectionChangeEventArgs extends CancelableEventArgs, IBaseEventArgs { /** An array containing the values that are currently selected */ oldSelection: any[]; /** An array containing the values that will be selected after this event */ @@ -489,7 +489,7 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas * ``` */ @Output() - public onSearchInput = new EventEmitter(); + public onSearchInput = new EventEmitter(); /** * Emitted when new chunk of data is loaded from the virtualization From 761bccc5d71853226a2b7c053610510d6e33832b Mon Sep 17 00:00:00 2001 From: wnvko Date: Thu, 16 Jul 2020 15:10:22 +0300 Subject: [PATCH 48/53] refactor(overlay): address PR comments --- CHANGELOG.md | 4 +- .../lib/date-picker/date-picker.component.ts | 2 +- .../src/lib/dialog/dialog.component.ts | 30 +++++++--- .../src/lib/services/overlay/overlay.spec.ts | 16 ++--- .../src/lib/services/overlay/overlay.ts | 58 ++++++++++--------- .../src/lib/services/overlay/utilities.ts | 2 +- 6 files changed, 65 insertions(+), 47 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eb6d81e96a3..7e1c4b1eacf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,9 +8,9 @@ All notable changes for each version of this project will be documented in this - `igxCombo` - **Behavioral Change** - Change default positioning strategy from `ConnectedPositioningStrategy` to `AutoPositionStrategy`. The [`Auto`](https://www.infragistics.com/products/ignite-ui-angular/angular/components/overlay_position.html#auto) strategy will initially try to show the element like the Connected strategy does. If the element goes out of the viewport Auto will flip the starting point and the direction, i.e. if the direction is 'bottom', it will switch it to 'top' and so on. If after flipping direction the content goes out of the view, auto strategy will revert to initial start point and direction and will push the content into the view. Note after pushing the content it may hide the combo's input. - `IgxOverlay` - - **Behavioral Change** - Added new property `closeOnEsc` in `OverlaySettings`. Should overlay close or not on escape keypress can now be controlled via this new property. By default `closeOnEsc` is set to `false`. + - **Behavioral Change** - Added new property `closeOnEscape` in `OverlaySettings`. Should overlay close or not on escape keypress can now be controlled via this new property. By default `closeOnEscape` is set to `false`. - `igxDialog` - - Added `closeOnEscapeKey` - with it, the dialog can be allowed or prevented from closing when `Esc` is pressed. + - Added `closeOnEscape` - with it, the dialog can be allowed or prevented from closing when `Esc` is pressed. - `IgxNavbar`: - **Breaking Changes** - The `igx-action-icon` has been renamed to `igx-navbar-action`. It should get renamed in your components via `ng update`; - `igxGrid` diff --git a/projects/igniteui-angular/src/lib/date-picker/date-picker.component.ts b/projects/igniteui-angular/src/lib/date-picker/date-picker.component.ts index 76320f170a4..dc31cfa19f5 100644 --- a/projects/igniteui-angular/src/lib/date-picker/date-picker.component.ts +++ b/projects/igniteui-angular/src/lib/date-picker/date-picker.component.ts @@ -784,7 +784,7 @@ export class IgxDatePickerComponent implements IDatePicker, ControlValueAccessor this._modalOverlaySettings = { closeOnOutsideClick: true, modal: true, - closeOnEsc: true, + closeOnEscape: true, outlet: this.outlet }; diff --git a/projects/igniteui-angular/src/lib/dialog/dialog.component.ts b/projects/igniteui-angular/src/lib/dialog/dialog.component.ts index 35c01665c3b..0082152dd6b 100644 --- a/projects/igniteui-angular/src/lib/dialog/dialog.component.ts +++ b/projects/igniteui-angular/src/lib/dialog/dialog.component.ts @@ -73,24 +73,36 @@ export class IgxDialogComponent implements IToggleView, OnInit, OnDestroy, After @Input() public id = `igx-dialog-${DIALOG_ID++}`; + /** + * Controls whether the dialog should be shown as modal. Defaults to `true` + * ```html + * + * ``` + */ @Input() - get isModal() { + public get isModal() { return this._isModal; } - set isModal(val: boolean) { + public set isModal(val: boolean) { this._overlayDefaultSettings.modal = val; this._isModal = val; } + /** + * Controls whether the dialog should close when `Esc` key is pressed. Defaults to `true` + * ```html + * + * ``` + */ @Input() - get closeOnEscapeKey() { - return this._closeOnEscapeKey; + public get closeOnEscape() { + return this._closeOnEscape; } - set closeOnEscapeKey(val: boolean) { - this._overlayDefaultSettings.closeOnEsc = val; - this._closeOnEscapeKey = val; + public set closeOnEscape(val: boolean) { + this._overlayDefaultSettings.closeOnEscape = val; + this._closeOnEscape = val; } /** @@ -311,7 +323,7 @@ export class IgxDialogComponent implements IToggleView, OnInit, OnDestroy, After private _overlayDefaultSettings: OverlaySettings; private _closeOnOutsideSelect = false; - private _closeOnEscapeKey = true; + private _closeOnEscape = true; private _isModal = true; protected destroy$ = new Subject(); @@ -415,7 +427,7 @@ export class IgxDialogComponent implements IToggleView, OnInit, OnDestroy, After positionStrategy: new GlobalPositionStrategy(this._positionSettings), scrollStrategy: new NoOpScrollStrategy(), modal: this.isModal, - closeOnEsc: this._closeOnEscapeKey, + closeOnEscape: this._closeOnEscape, closeOnOutsideClick: this.closeOnOutsideSelect }; } diff --git a/projects/igniteui-angular/src/lib/services/overlay/overlay.spec.ts b/projects/igniteui-angular/src/lib/services/overlay/overlay.spec.ts index cc4336bbbbd..889c533d818 100644 --- a/projects/igniteui-angular/src/lib/services/overlay/overlay.spec.ts +++ b/projects/igniteui-angular/src/lib/services/overlay/overlay.spec.ts @@ -2718,7 +2718,7 @@ describe('igxOverlay', () => { const fixture = TestBed.createComponent(EmptyPageComponent); const overlay = fixture.componentInstance.overlay; const overlaySettings: OverlaySettings = { - closeOnEsc: true, + closeOnEscape: true, }; overlay.show(overlay.attach(SimpleDynamicComponent), overlaySettings); @@ -2738,7 +2738,7 @@ describe('igxOverlay', () => { const fixture = TestBed.createComponent(EmptyPageComponent); const overlay = fixture.componentInstance.overlay; const overlaySettings: OverlaySettings = { - closeOnEsc: false + closeOnEscape: false }; overlay.show(overlay.attach(SimpleDynamicComponent), overlaySettings); @@ -2757,9 +2757,9 @@ describe('igxOverlay', () => { it('Should close the opened overlays consecutively on esc keypress', fakeAsync(() => { const fixture = TestBed.createComponent(EmptyPageComponent); const overlay = fixture.componentInstance.overlay; - overlay.show(overlay.attach(SimpleDynamicComponent), { closeOnEsc: true }); + overlay.show(overlay.attach(SimpleDynamicComponent), { closeOnEscape: true }); tick(); - overlay.show(overlay.attach(SimpleDynamicComponent), { closeOnEsc: true }); + overlay.show(overlay.attach(SimpleDynamicComponent), { closeOnEscape: true }); tick(); const overlayDiv = document.getElementsByClassName(CLASS_OVERLAY_MAIN)[0]; @@ -2777,11 +2777,11 @@ describe('igxOverlay', () => { it('Should not close the opened overlays consecutively on esc keypress', fakeAsync(() => { const fixture = TestBed.createComponent(EmptyPageComponent); const overlay = fixture.componentInstance.overlay; - overlay.show(overlay.attach(SimpleDynamicComponent), { closeOnEsc: true }); + overlay.show(overlay.attach(SimpleDynamicComponent), { closeOnEscape: true }); tick(); - overlay.show(overlay.attach(SimpleDynamicComponent), { closeOnEsc: false }); + overlay.show(overlay.attach(SimpleDynamicComponent), { closeOnEscape: false }); tick(); - overlay.show(overlay.attach(SimpleDynamicComponent), { closeOnEsc: true }); + overlay.show(overlay.attach(SimpleDynamicComponent), { closeOnEscape: true }); tick(); const overlayDiv = document.getElementsByClassName(CLASS_OVERLAY_MAIN)[0]; @@ -2801,7 +2801,7 @@ describe('igxOverlay', () => { const fixture = TestBed.createComponent(EmptyPageComponent); const overlay = fixture.componentInstance.overlay; const overlaySettings: OverlaySettings = { - closeOnEsc: true, + closeOnEscape: true, }; overlay.show(overlay.attach(SimpleDynamicComponent), overlaySettings); diff --git a/projects/igniteui-angular/src/lib/services/overlay/overlay.ts b/projects/igniteui-angular/src/lib/services/overlay/overlay.ts index 0f6fcdc70f3..4b6656fcbc4 100644 --- a/projects/igniteui-angular/src/lib/services/overlay/overlay.ts +++ b/projects/igniteui-angular/src/lib/services/overlay/overlay.ts @@ -1,15 +1,5 @@ +import { AnimationAnimateRefMetadata, AnimationBuilder, AnimationMetadataType, AnimationReferenceMetadata } from '@angular/animations'; import { DOCUMENT } from '@angular/common'; -import { GlobalPositionStrategy } from './position/global-position-strategy'; -import { NoOpScrollStrategy } from './scroll/NoOpScrollStrategy'; -import { - OverlaySettings, - OverlayEventArgs, - OverlayInfo, - OverlayAnimationEventArgs, - OverlayCancelableEventArgs, - OverlayClosingEventArgs -} from './utilities'; - import { ApplicationRef, ComponentFactory, @@ -20,17 +10,22 @@ import { Inject, Injectable, Injector, - Type, - OnDestroy, NgModuleRef, - NgZone + NgZone, OnDestroy, Type } from '@angular/core'; -import { AnimationBuilder, AnimationReferenceMetadata, AnimationMetadataType, AnimationAnimateRefMetadata } from '@angular/animations'; -import { fromEvent, Subject } from 'rxjs'; +import { fromEvent, Subject, Subscription } from 'rxjs'; import { filter, takeUntil } from 'rxjs/operators'; import { IAnimationParams } from '../../animations/main'; import { showMessage } from '../../core/deprecateDecorators'; -import { FromEventTarget } from 'rxjs/internal/observable/fromEvent'; +import { GlobalPositionStrategy } from './position/global-position-strategy'; +import { NoOpScrollStrategy } from './scroll/NoOpScrollStrategy'; +import { + OverlayAnimationEventArgs, + OverlayCancelableEventArgs, + OverlayClosingEventArgs, OverlayEventArgs, + OverlayInfo, OverlaySettings +} from './utilities'; + let warningShown = false; @@ -44,6 +39,7 @@ export class IgxOverlayService implements OnDestroy { private _overlayInfos: OverlayInfo[] = []; private _overlayElement: HTMLElement; private _document: Document; + private _keyPressEventListener: Subscription; private destroy$ = new Subject(); private _defaultSettings: OverlaySettings = { @@ -51,7 +47,7 @@ export class IgxOverlayService implements OnDestroy { scrollStrategy: new NoOpScrollStrategy(), modal: true, closeOnOutsideClick: true, - closeOnEsc: false + closeOnEscape: false }; /** @@ -322,7 +318,7 @@ export class IgxOverlayService implements OnDestroy { } this.addOutsideClickListener(info); - this.addResizeHandler(info.id); + this.addResizeHandler(); this.addCloseOnEscapeListener(); if (info.settings.modal) { @@ -359,7 +355,8 @@ export class IgxOverlayService implements OnDestroy { // TODO: synchronize where these are added/attached and where removed/detached info.settings.scrollStrategy.detach(); this.removeOutsideClickListener(info); - this.removeResizeHandler(info.id); + this.removeResizeHandler(); + this.removeCloseOnEscapeListener(); const child: HTMLElement = info.elementRef.nativeElement; if (info.settings.modal) { @@ -706,7 +703,7 @@ export class IgxOverlayService implements OnDestroy { } } - private addResizeHandler(id: string) { + private addResizeHandler() { const closingOverlaysCount = this._overlayInfos .filter(o => o.closeAnimationPlayer && o.closeAnimationPlayer.hasStarted()) @@ -716,7 +713,7 @@ export class IgxOverlayService implements OnDestroy { } } - private removeResizeHandler(id: string) { + private removeResizeHandler() { const closingOverlaysCount = this._overlayInfos .filter(o => o.closeAnimationPlayer && o.closeAnimationPlayer.hasStarted()) @@ -730,18 +727,27 @@ export class IgxOverlayService implements OnDestroy { // if all overlays minus closing overlays equals one add the handler if (this._overlayInfos.length - this._overlayInfos.filter(x => x.closeAnimationPlayer && x.closeAnimationPlayer.hasStarted()).length === 1) { - fromEvent(this._document, 'keydown').pipe( - filter((ev: KeyboardEvent) => ev.key === 'Escape' || ev.key === 'Esc'), - takeUntil(this.destroy$) + this._keyPressEventListener = fromEvent(this._document, 'keydown').pipe( + filter((ev: KeyboardEvent) => ev.key === 'Escape' || ev.key === 'Esc') ).subscribe(() => { const targetOverlay = this._overlayInfos[this._overlayInfos.length - 1]; - if (targetOverlay.settings.closeOnEsc) { + if (targetOverlay.settings.closeOnEscape) { this.hide(targetOverlay.id); } }); } } + private removeCloseOnEscapeListener() { + const closingOverlaysCount = + this._overlayInfos + .filter(o => o.closeAnimationPlayer && o.closeAnimationPlayer.hasStarted()) + .length; + if (this._overlayInfos.length - closingOverlaysCount === 1 && !this._keyPressEventListener.closed) { + this._keyPressEventListener.unsubscribe(); + } + } + /** @hidden */ public repositionAll = () => { for (let i = this._overlayInfos.length; i--;) { diff --git a/projects/igniteui-angular/src/lib/services/overlay/utilities.ts b/projects/igniteui-angular/src/lib/services/overlay/utilities.ts index a78f9dd16a9..78674fc04ae 100644 --- a/projects/igniteui-angular/src/lib/services/overlay/utilities.ts +++ b/projects/igniteui-angular/src/lib/services/overlay/utilities.ts @@ -59,7 +59,7 @@ export interface OverlaySettings { /** Set if the overlay should close on outside click */ closeOnOutsideClick?: boolean; /** Set if the overlay should close when `Esc` key is pressed */ - closeOnEsc?: boolean; + closeOnEscape?: boolean; /** Set the outlet container to attach the overlay to */ outlet?: IgxOverlayOutletDirective | ElementRef; /** From e564acb54b50699ed24419ac82f92f2ce055a185 Mon Sep 17 00:00:00 2001 From: plamenamiteva Date: Thu, 16 Jul 2020 16:48:59 +0300 Subject: [PATCH 49/53] fix(combo): add owner to event args #7282 --- CHANGELOG.md | 2 +- projects/igniteui-angular/src/lib/combo/combo.component.spec.ts | 1 + projects/igniteui-angular/src/lib/combo/combo.component.ts | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4df14ed04d4..5f22fba5c34 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ All notable changes for each version of this project will be documented in this ### General - `igxCombo` - **Behavioral Change** - Change default positioning strategy from `ConnectedPositioningStrategy` to `AutoPositionStrategy`. The [`Auto`](https://www.infragistics.com/products/ignite-ui-angular/angular/components/overlay_position.html#auto) strategy will initially try to show the element like the Connected strategy does. If the element goes out of the viewport Auto will flip the starting point and the direction, i.e. if the direction is 'bottom', it will switch it to 'top' and so on. If after flipping direction the content goes out of the view, auto strategy will revert to initial start point and direction and will push the content into the view. Note after pushing the content it may hide the combo's input. - - Make `onSearchInput` event cancellable. The event args type has been changed to `IComboSearchInputEventArgs`, which have the following properties: `searchText` - holds the text typed into the search input and `cancel` - indicates whether the event should be canceled. + - Make `onSearchInput` event cancellable. The event args type has been changed to `IComboSearchInputEventArgs`, which have the following properties: `searchText` - holds the text typed into the search input, `owner` - holds a reference to the combo component and `cancel` - indicates whether the event should be canceled. - `IgxOverlay` - Added new property - `closeOnEsc` - in `OverlaySettings`. The overlay can now be prevented from closing, on escape keypress, by setting the property to `false`, by default it's `true`. - `igxDialog` diff --git a/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts b/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts index c66b9d08f77..2e74e945738 100644 --- a/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts +++ b/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts @@ -533,6 +533,7 @@ describe('igxCombo', () => { const args = { searchText: 'Fake', + owner: combo, cancel: false }; combo.handleInputChange('Fake'); diff --git a/projects/igniteui-angular/src/lib/combo/combo.component.ts b/projects/igniteui-angular/src/lib/combo/combo.component.ts index 309bdd088b4..8366a569f9a 100644 --- a/projects/igniteui-angular/src/lib/combo/combo.component.ts +++ b/projects/igniteui-angular/src/lib/combo/combo.component.ts @@ -989,6 +989,7 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas if (event !== undefined) { const args: IComboSearchInputEventArgs = { searchText: event, + owner: this, cancel: false }; this.onSearchInput.emit(args); From 8547d903be8de5633c780720e97070007523463f Mon Sep 17 00:00:00 2001 From: wnvko Date: Thu, 16 Jul 2020 16:16:26 +0300 Subject: [PATCH 50/53] refactor(overlay): refactor close on escape handler handling --- .../src/lib/services/overlay/overlay.ts | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/projects/igniteui-angular/src/lib/services/overlay/overlay.ts b/projects/igniteui-angular/src/lib/services/overlay/overlay.ts index 4b6656fcbc4..67bff12f0fb 100644 --- a/projects/igniteui-angular/src/lib/services/overlay/overlay.ts +++ b/projects/igniteui-angular/src/lib/services/overlay/overlay.ts @@ -319,7 +319,7 @@ export class IgxOverlayService implements OnDestroy { this.addOutsideClickListener(info); this.addResizeHandler(); - this.addCloseOnEscapeListener(); + this.addCloseOnEscapeListener(info); if (info.settings.modal) { const wrapperElement = info.elementRef.nativeElement.parentElement.parentElement; @@ -723,10 +723,8 @@ export class IgxOverlayService implements OnDestroy { } } - private addCloseOnEscapeListener() { - // if all overlays minus closing overlays equals one add the handler - if (this._overlayInfos.length - this._overlayInfos.filter(x => x.closeAnimationPlayer - && x.closeAnimationPlayer.hasStarted()).length === 1) { + private addCloseOnEscapeListener(info: OverlayInfo) { + if (info.settings.closeOnEscape && !this._keyPressEventListener) { this._keyPressEventListener = fromEvent(this._document, 'keydown').pipe( filter((ev: KeyboardEvent) => ev.key === 'Escape' || ev.key === 'Esc') ).subscribe(() => { @@ -740,11 +738,12 @@ export class IgxOverlayService implements OnDestroy { private removeCloseOnEscapeListener() { const closingOverlaysCount = - this._overlayInfos - .filter(o => o.closeAnimationPlayer && o.closeAnimationPlayer.hasStarted()) - .length; - if (this._overlayInfos.length - closingOverlaysCount === 1 && !this._keyPressEventListener.closed) { + this._overlayInfos + .filter(o => o.closeAnimationPlayer && o.closeAnimationPlayer.hasStarted()) + .length; + if (this._overlayInfos.length - closingOverlaysCount === 1 && this._keyPressEventListener && !this._keyPressEventListener.closed) { this._keyPressEventListener.unsubscribe(); + this._keyPressEventListener = null; } } From c6225202ea664be1ba58d2e8214cceeeceafaedf Mon Sep 17 00:00:00 2001 From: wnvko Date: Fri, 17 Jul 2020 09:16:26 +0300 Subject: [PATCH 51/53] chore(overlay): remove excesive check for key press subscribtion --- projects/igniteui-angular/src/lib/services/overlay/overlay.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/igniteui-angular/src/lib/services/overlay/overlay.ts b/projects/igniteui-angular/src/lib/services/overlay/overlay.ts index 67bff12f0fb..b8c1ce497f2 100644 --- a/projects/igniteui-angular/src/lib/services/overlay/overlay.ts +++ b/projects/igniteui-angular/src/lib/services/overlay/overlay.ts @@ -741,7 +741,7 @@ export class IgxOverlayService implements OnDestroy { this._overlayInfos .filter(o => o.closeAnimationPlayer && o.closeAnimationPlayer.hasStarted()) .length; - if (this._overlayInfos.length - closingOverlaysCount === 1 && this._keyPressEventListener && !this._keyPressEventListener.closed) { + if (this._overlayInfos.length - closingOverlaysCount === 1 && this._keyPressEventListener) { this._keyPressEventListener.unsubscribe(); this._keyPressEventListener = null; } From 10b75ab75953cb78daa2a55421e32b22bbc75d32 Mon Sep 17 00:00:00 2001 From: wnvko Date: Fri, 17 Jul 2020 11:46:57 +0300 Subject: [PATCH 52/53] fix(overlay): correctly close all overlays on escape key, #7803 --- .../igniteui-angular/src/lib/services/overlay/overlay.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/projects/igniteui-angular/src/lib/services/overlay/overlay.ts b/projects/igniteui-angular/src/lib/services/overlay/overlay.ts index b8c1ce497f2..ce7549cd62f 100644 --- a/projects/igniteui-angular/src/lib/services/overlay/overlay.ts +++ b/projects/igniteui-angular/src/lib/services/overlay/overlay.ts @@ -356,7 +356,6 @@ export class IgxOverlayService implements OnDestroy { info.settings.scrollStrategy.detach(); this.removeOutsideClickListener(info); this.removeResizeHandler(); - this.removeCloseOnEscapeListener(); const child: HTMLElement = info.elementRef.nativeElement; if (info.settings.modal) { @@ -502,6 +501,7 @@ export class IgxOverlayService implements OnDestroy { if (this._overlayInfos.length === 0 && this._overlayElement && this._overlayElement.parentElement) { this._overlayElement.parentElement.removeChild(this._overlayElement); this._overlayElement = null; + this.removeCloseOnEscapeListener(); } } @@ -737,11 +737,7 @@ export class IgxOverlayService implements OnDestroy { } private removeCloseOnEscapeListener() { - const closingOverlaysCount = - this._overlayInfos - .filter(o => o.closeAnimationPlayer && o.closeAnimationPlayer.hasStarted()) - .length; - if (this._overlayInfos.length - closingOverlaysCount === 1 && this._keyPressEventListener) { + if (this._keyPressEventListener) { this._keyPressEventListener.unsubscribe(); this._keyPressEventListener = null; } From 12e9723241271981ae8e2d33eccc97f09a1bbeb4 Mon Sep 17 00:00:00 2001 From: Aleksandar Kamenov Date: Mon, 20 Jul 2020 17:10:13 +0300 Subject: [PATCH 53/53] feat(grid-row): expose data type bool class --- .../igniteui-angular/src/lib/grids/grid/grid-row.component.html | 1 + 1 file changed, 1 insertion(+) diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid-row.component.html b/projects/igniteui-angular/src/lib/grids/grid/grid-row.component.html index e100c6ffea0..d60f23b85e6 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid-row.component.html +++ b/projects/igniteui-angular/src/lib/grids/grid/grid-row.component.html @@ -90,6 +90,7 @@ class="igx-grid__td igx-grid__td--fw" [class.igx-grid__td--pinned]="col.pinned" [class.igx-grid__td--number]="col.dataType === 'number'" + [class.igx-grid__td--bool]="col.dataType === 'boolean'" [ngClass]="col.cellClasses | igxCellStyleClasses:rowData[col.field]:rowData:col.field:viewIndex" [ngStyle]="col.cellStyles | igxCellStyles:rowData[col.field]:rowData:col.field:viewIndex" [editMode]="col.editable && crudService.isInEditMode(index, col.index)"