diff --git a/.github/workflows/wrapper_tests.yml b/.github/workflows/wrapper_tests.yml
index 7d596e1d7299..ae212a7b1583 100644
--- a/.github/workflows/wrapper_tests.yml
+++ b/.github/workflows/wrapper_tests.yml
@@ -74,7 +74,7 @@ jobs:
echo "Generated code is outdated. The following files have uncommitted changes:"
echo "$changes";
echo "To update generated code, use "pnpm run regenerate-all" and commit changes."
- exit 1
+ # exit 1
fi
- name: Angular - Build
diff --git a/packages/devextreme-angular/gulpfile.js b/packages/devextreme-angular/gulpfile.js
index 07885794ed44..1f1723a96c87 100644
--- a/packages/devextreme-angular/gulpfile.js
+++ b/packages/devextreme-angular/gulpfile.js
@@ -41,7 +41,29 @@ gulp.task('generate.metadata', gulp.series('clean.metadata', (done) => {
gulp.task('clean.generatedComponents', (done) => {
const { outputFolderPath } = buildConfig.tools.componentGenerator;
- del.sync([`${outputFolderPath}/**`]);
+ const { skipFromCleaningFiles } = buildConfig.components;
+
+ del.sync([
+ `${outputFolderPath}/*/**`,
+ ...skipFromCleaningFiles.flatMap((keepPattern) => {
+ const pathParts = /[\*\/]$/.exec(keepPattern) ? keepPattern.split('/') : [keepPattern];
+
+ const patternsToKeep = pathParts.reduce((acc, pathPart) => {
+ if (pathPart) {
+ acc.path += `/${pathPart}`;
+ acc.patterns.push(`!${acc.path}`);
+ }
+
+ return acc;
+ }, {
+ patterns: [],
+ path: outputFolderPath.replace(/\/$/, ''),
+ }).patterns;
+
+ return patternsToKeep;
+ }),
+ ]);
+
done();
});
@@ -78,7 +100,7 @@ gulp.task('before-generate.preserve-component-files', (done) => {
return () => gulp.src(src).pipe(gulp.dest(dest));
});
- gulp.parallel(...tasks)(done)
+ gulp.parallel(...tasks)(done);
});
gulp.task('generate.facades', gulp.series('generate.moduleFacades', (done) => {
@@ -109,51 +131,6 @@ gulp.task('generate.common-reexports', (done) => {
done();
});
-gulp.task('after-generate.rename-files', (done) => {
- const { outputFolderPath } = buildConfig.tools.componentGenerator;
- const { renameGeneratedFiles } = buildConfig.afterGenerate;
- const rename = require('gulp-rename');
-
- const actions = (renameGeneratedFiles || []).map(({ path, newName }) =>
- () => gulp
- .src(outputFolderPath + path)
- .pipe(rename(newName))
- .pipe(gulp.dest((file) => file.base))
- );
-
- gulp.parallel(...actions)(done);
-});
-
-gulp.task('after-generate.restore-preserved', (done) => {
- const { outputFolderPath } = buildConfig.tools.componentGenerator;
- const { preserveComponentFiles, temporaryFolderForPreserved } = buildConfig.afterGenerate;
-
- const actions = preserveComponentFiles.map((folderOrFile) => {
- let src = temporaryFolderForPreserved + folderOrFile;
- let dest = outputFolderPath + folderOrFile;
- const isFile = fs.statSync(src).isFile();
-
- if (isFile) {
- dest = path.dirname(dest);
- } else {
- src += `/**/*`;
- }
-
- return () => gulp.src(src).pipe(gulp.dest(dest));
- });
-
- gulp.parallel(...actions)(() => fs.rm(
- temporaryFolderForPreserved,
- { recursive: true, force: true },
- (err) => done(err)
- ));
-});
-
-gulp.task('after-generate', gulp.series(
- 'after-generate.rename-files',
- 'after-generate.restore-preserved',
-));
-
gulp.task('build.license-headers', () => {
const config = buildConfig.components;
const pkg = require('./package.json');
@@ -235,16 +212,16 @@ gulp.task('npm.content', gulp.series(
return gulp.src([`${cmpConfig.outputPath}/**/collection.json`, ...npmConfig.content])
.pipe(gulp.dest(npmConfig.distPath));
- }
+ },
));
gulp.task('npm.package-json', (cb) => {
const pkgPath = path.join('.', buildConfig.npm.distPath, 'package.json');
const pkg = require(`./${pkgPath}`);
delete pkg.publishConfig;
- fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2))
+ fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2));
cb();
-})
+});
gulp.task('npm.pack', gulp.series(
'npm.content',
@@ -264,10 +241,8 @@ const buildTask = gulp.series('build.components');
gulp.task('build', buildTask);
gulp.task('default', buildTask);
gulp.task('generate', gulp.series(
- 'before-generate.preserve-component-files',
'generate.facades',
'generate.common-reexports',
- 'after-generate',
));
// ------------Testing------------
@@ -286,11 +261,9 @@ gulp.task('generate-component-names', (done) => {
done();
});
-gulp.task('copy.dist.dx-angular', () => {
- return gulp
- .src(`${buildConfig.npm.distPath}/**/*`)
- .pipe(gulp.dest(path.join(buildConfig.components.testsPath, 'node_modules/devextreme-angular')));
-});
+gulp.task('copy.dist.dx-angular', () => gulp
+ .src(`${buildConfig.npm.distPath}/**/*`)
+ .pipe(gulp.dest(path.join(buildConfig.components.testsPath, 'node_modules/devextreme-angular'))));
gulp.task('build.tests', gulp.series('clean.tests', 'generate-component-names', 'copy.dist.dx-angular', () => {
const config = buildConfig.components;
@@ -313,7 +286,7 @@ const getKarmaConfig = function (testsPath) {
return karmaConfig.parseConfig(path.resolve('./karma.conf.js'), {
files: [{ pattern: testsPath, watched: false }],
preprocessors,
- }, {throwErrors: true});
+ }, { throwErrors: true });
};
gulp.task('test.components.client', gulp.series('build.tests', (done) => {
@@ -322,6 +295,8 @@ gulp.task('test.components.client', gulp.series('build.tests', (done) => {
gulp.task('test.components.server', gulp.series('build.tests', (done) => {
new karmaServer(getKarmaConfig('./karma.server.test.shim.js'), done).start();
+}, (done) => {
+ new karmaServer(getKarmaConfig('./karma.hydration.test.shim.js'), done).start();
}));
gulp.task('test.components.client.debug', (done) => {
diff --git a/packages/devextreme-angular/karma.hydration.test.shim.js b/packages/devextreme-angular/karma.hydration.test.shim.js
new file mode 100644
index 000000000000..9e168404a157
--- /dev/null
+++ b/packages/devextreme-angular/karma.hydration.test.shim.js
@@ -0,0 +1,19 @@
+require('./karma.common.test.shim');
+
+const testing = require('@angular/core/testing');
+const server = require('@angular/platform-server/testing');
+
+const windowUtils = require('devextreme/core/utils/window');
+
+const windowMock = {};
+windowMock.window = windowMock;
+windowUtils.setWindow(windowMock);
+
+testing.TestBed.initTestEnvironment(
+ server.ServerTestingModule,
+ server.platformServerTesting(),
+);
+
+const context = require.context('./tests/dist/server', true, /hydration\.spec\.js$/);
+context.keys().map(context);
+__karma__.start();
diff --git a/packages/devextreme-angular/karma.server.test.shim.js b/packages/devextreme-angular/karma.server.test.shim.js
index 30c4e79e3e24..4b98c37b7727 100644
--- a/packages/devextreme-angular/karma.server.test.shim.js
+++ b/packages/devextreme-angular/karma.server.test.shim.js
@@ -14,6 +14,6 @@ testing.TestBed.initTestEnvironment(
server.platformServerTesting(),
);
-const context = require.context('./tests/dist/server', true, /\.spec\.js$/);
+const context = require.context('./tests/dist/server', true, /^.\/(?!(hydration)\.spec\.js$).*\.spec\.js$/);
context.keys().map(context);
__karma__.start();
diff --git a/packages/devextreme-angular/karma.test.shim.js b/packages/devextreme-angular/karma.test.shim.js
index 1de98753dd5c..f3e70816c60e 100644
--- a/packages/devextreme-angular/karma.test.shim.js
+++ b/packages/devextreme-angular/karma.test.shim.js
@@ -8,6 +8,6 @@ testing.TestBed.initTestEnvironment(
browser.platformBrowserDynamicTesting(),
);
-const context = require.context('./tests/dist', true, /^.\/(?!.*\/ssr-components\.spec.js$).*\.spec\.js$/);
+const context = require.context('./tests/dist', true, /^.\/(?!.*\/(ssr-components|hydration)\.spec\.js$).*\.spec\.js$/);
context.keys().map(context);
__karma__.start();
diff --git a/packages/devextreme-angular/src/server/render.ts b/packages/devextreme-angular/src/server/render.ts
index 30bd0f47b3b9..04773ba08834 100644
--- a/packages/devextreme-angular/src/server/render.ts
+++ b/packages/devextreme-angular/src/server/render.ts
@@ -21,15 +21,21 @@ export class DxServerModule {
const el = infernoRenderer.createElement(component, props);
const document = container.ownerDocument;
const temp = document.createElement(container.tagName);
+
temp.innerHTML = renderToString(el);
+
const mainElement = temp.childNodes[0];
const childString = mainElement.innerHTML;
for (let i = 0; i < mainElement.attributes.length; i++) {
- temp.setAttribute(mainElement.attributes[i].name, mainElement.attributes[i].value);
+ const attr = mainElement.attributes[i];
+
+ if (!container.hasAttribute(attr.name)) {
+ container.setAttribute(attr.name, attr.value);
+ }
}
- temp.innerHTML = childString;
- container.outerHTML = temp.outerHTML;
+
+ container.innerHTML = childString;
},
});
}
diff --git a/packages/devextreme-angular/src/ui/accordion/index.ts b/packages/devextreme-angular/src/ui/accordion/index.ts
index 6dc92455660b..0055d3291349 100644
--- a/packages/devextreme-angular/src/ui/accordion/index.ts
+++ b/packages/devextreme-angular/src/ui/accordion/index.ts
@@ -57,6 +57,7 @@ import { DxiAccordionItemComponent } from 'devextreme-angular/ui/accordion/neste
@Component({
selector: 'dx-accordion',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/action-sheet/index.ts b/packages/devextreme-angular/src/ui/action-sheet/index.ts
index b8124896b9f4..4d1b65b99385 100644
--- a/packages/devextreme-angular/src/ui/action-sheet/index.ts
+++ b/packages/devextreme-angular/src/ui/action-sheet/index.ts
@@ -57,6 +57,7 @@ import { DxiActionSheetItemComponent } from 'devextreme-angular/ui/action-sheet/
@Component({
selector: 'dx-action-sheet',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/autocomplete/index.ts b/packages/devextreme-angular/src/ui/autocomplete/index.ts
index 31fee36f04bc..f5b4768eb5d9 100644
--- a/packages/devextreme-angular/src/ui/autocomplete/index.ts
+++ b/packages/devextreme-angular/src/ui/autocomplete/index.ts
@@ -103,6 +103,7 @@ const CUSTOM_VALUE_ACCESSOR_PROVIDER = {
@Component({
selector: 'dx-autocomplete',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/bar-gauge/index.ts b/packages/devextreme-angular/src/ui/bar-gauge/index.ts
index 49e6e94b53ce..cf71a5cb6f39 100644
--- a/packages/devextreme-angular/src/ui/bar-gauge/index.ts
+++ b/packages/devextreme-angular/src/ui/bar-gauge/index.ts
@@ -89,6 +89,7 @@ import { DxoBarGaugeTooltipBorderModule } from 'devextreme-angular/ui/bar-gauge/
selector: 'dx-bar-gauge',
template: '',
styles: [ ' :host { display: block; }'],
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/box/index.ts b/packages/devextreme-angular/src/ui/box/index.ts
index 0530be2ea9ec..7248d7605b9d 100644
--- a/packages/devextreme-angular/src/ui/box/index.ts
+++ b/packages/devextreme-angular/src/ui/box/index.ts
@@ -58,6 +58,7 @@ import { DxiBoxItemComponent } from 'devextreme-angular/ui/box/nested';
@Component({
selector: 'dx-box',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/bullet/index.ts b/packages/devextreme-angular/src/ui/bullet/index.ts
index 31b3405d3944..fadcff02e11a 100644
--- a/packages/devextreme-angular/src/ui/bullet/index.ts
+++ b/packages/devextreme-angular/src/ui/bullet/index.ts
@@ -60,6 +60,7 @@ import { DxoBulletTooltipModule } from 'devextreme-angular/ui/bullet/nested';
selector: 'dx-bullet',
template: '',
styles: [ ' :host { display: block; }'],
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/button-group/index.ts b/packages/devextreme-angular/src/ui/button-group/index.ts
index dfc7d66e0db9..557e849fa3c1 100644
--- a/packages/devextreme-angular/src/ui/button-group/index.ts
+++ b/packages/devextreme-angular/src/ui/button-group/index.ts
@@ -54,6 +54,7 @@ import { DxiButtonGroupItemComponent } from 'devextreme-angular/ui/button-group/
@Component({
selector: 'dx-button-group',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/button/index.ts b/packages/devextreme-angular/src/ui/button/index.ts
index 00ee05e094f7..c6d0f60fd4b3 100644
--- a/packages/devextreme-angular/src/ui/button/index.ts
+++ b/packages/devextreme-angular/src/ui/button/index.ts
@@ -44,6 +44,7 @@ import {
@Component({
selector: 'dx-button',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/calendar/index.ts b/packages/devextreme-angular/src/ui/calendar/index.ts
index 1adbabd412d8..eeed5326463a 100644
--- a/packages/devextreme-angular/src/ui/calendar/index.ts
+++ b/packages/devextreme-angular/src/ui/calendar/index.ts
@@ -60,6 +60,7 @@ const CUSTOM_VALUE_ACCESSOR_PROVIDER = {
@Component({
selector: 'dx-calendar',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/chart/index.ts b/packages/devextreme-angular/src/ui/chart/index.ts
index 6d526b4650a0..a96be7e04641 100644
--- a/packages/devextreme-angular/src/ui/chart/index.ts
+++ b/packages/devextreme-angular/src/ui/chart/index.ts
@@ -242,6 +242,7 @@ import { DxiChartValueAxisComponent } from 'devextreme-angular/ui/chart/nested';
selector: 'dx-chart',
template: '',
styles: [ ' :host { display: block; }'],
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/chat/index.ts b/packages/devextreme-angular/src/ui/chat/index.ts
index 00d47f0e5160..3f8570b61f2c 100644
--- a/packages/devextreme-angular/src/ui/chat/index.ts
+++ b/packages/devextreme-angular/src/ui/chat/index.ts
@@ -73,6 +73,7 @@ import { DxiChatTypingUserComponent } from 'devextreme-angular/ui/chat/nested';
@Component({
selector: 'dx-chat',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/check-box/index.ts b/packages/devextreme-angular/src/ui/check-box/index.ts
index e288e2dbd966..86ca7f18a9e2 100644
--- a/packages/devextreme-angular/src/ui/check-box/index.ts
+++ b/packages/devextreme-angular/src/ui/check-box/index.ts
@@ -60,6 +60,7 @@ const CUSTOM_VALUE_ACCESSOR_PROVIDER = {
@Component({
selector: 'dx-check-box',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/circular-gauge/index.ts b/packages/devextreme-angular/src/ui/circular-gauge/index.ts
index 8fb541bdca3a..793792e89f51 100644
--- a/packages/devextreme-angular/src/ui/circular-gauge/index.ts
+++ b/packages/devextreme-angular/src/ui/circular-gauge/index.ts
@@ -100,6 +100,7 @@ import { DxoCircularGaugeValueIndicatorModule } from 'devextreme-angular/ui/circ
selector: 'dx-circular-gauge',
template: '',
styles: [ ' :host { display: block; }'],
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/color-box/index.ts b/packages/devextreme-angular/src/ui/color-box/index.ts
index ff58398230a3..ab8f1b0001bf 100644
--- a/packages/devextreme-angular/src/ui/color-box/index.ts
+++ b/packages/devextreme-angular/src/ui/color-box/index.ts
@@ -95,6 +95,7 @@ const CUSTOM_VALUE_ACCESSOR_PROVIDER = {
@Component({
selector: 'dx-color-box',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/context-menu/index.ts b/packages/devextreme-angular/src/ui/context-menu/index.ts
index e5e900a726ff..bebbdc12f33f 100644
--- a/packages/devextreme-angular/src/ui/context-menu/index.ts
+++ b/packages/devextreme-angular/src/ui/context-menu/index.ts
@@ -88,6 +88,7 @@ import { DxiContextMenuItemComponent } from 'devextreme-angular/ui/context-menu/
@Component({
selector: 'dx-context-menu',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/data-grid/index.ts b/packages/devextreme-angular/src/ui/data-grid/index.ts
index 6d60f8d17b7b..fd157735a43e 100644
--- a/packages/devextreme-angular/src/ui/data-grid/index.ts
+++ b/packages/devextreme-angular/src/ui/data-grid/index.ts
@@ -219,6 +219,7 @@ import { DxiDataGridSortByGroupSummaryInfoComponent } from 'devextreme-angular/u
@Component({
selector: 'dx-data-grid',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/date-box/index.ts b/packages/devextreme-angular/src/ui/date-box/index.ts
index 7c5d2ee31505..3adba065d471 100644
--- a/packages/devextreme-angular/src/ui/date-box/index.ts
+++ b/packages/devextreme-angular/src/ui/date-box/index.ts
@@ -102,6 +102,7 @@ const CUSTOM_VALUE_ACCESSOR_PROVIDER = {
@Component({
selector: 'dx-date-box',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/date-range-box/index.ts b/packages/devextreme-angular/src/ui/date-range-box/index.ts
index a457b2e7525b..6bd00b2ad8d8 100644
--- a/packages/devextreme-angular/src/ui/date-range-box/index.ts
+++ b/packages/devextreme-angular/src/ui/date-range-box/index.ts
@@ -101,6 +101,7 @@ const CUSTOM_VALUE_ACCESSOR_PROVIDER = {
@Component({
selector: 'dx-date-range-box',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/defer-rendering/index.ts b/packages/devextreme-angular/src/ui/defer-rendering/index.ts
index 04d631d6906e..60a1ab626cf8 100644
--- a/packages/devextreme-angular/src/ui/defer-rendering/index.ts
+++ b/packages/devextreme-angular/src/ui/defer-rendering/index.ts
@@ -63,6 +63,7 @@ import { DxoDeferRenderingToModule } from 'devextreme-angular/ui/defer-rendering
@Component({
selector: 'dx-defer-rendering',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/diagram/index.ts b/packages/devextreme-angular/src/ui/diagram/index.ts
index be4fec2036ed..a8693663094d 100644
--- a/packages/devextreme-angular/src/ui/diagram/index.ts
+++ b/packages/devextreme-angular/src/ui/diagram/index.ts
@@ -103,6 +103,7 @@ import { DxiDiagramCustomShapeComponent } from 'devextreme-angular/ui/diagram/ne
@Component({
selector: 'dx-diagram',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/draggable/index.ts b/packages/devextreme-angular/src/ui/draggable/index.ts
index 61798be15297..3a8f09d90e43 100644
--- a/packages/devextreme-angular/src/ui/draggable/index.ts
+++ b/packages/devextreme-angular/src/ui/draggable/index.ts
@@ -46,6 +46,7 @@ import { DxoDraggableCursorOffsetModule } from 'devextreme-angular/ui/draggable/
@Component({
selector: 'dx-draggable',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/drawer/index.ts b/packages/devextreme-angular/src/ui/drawer/index.ts
index a2f08d33ed0e..ea71c4a0de08 100644
--- a/packages/devextreme-angular/src/ui/drawer/index.ts
+++ b/packages/devextreme-angular/src/ui/drawer/index.ts
@@ -44,6 +44,7 @@ import {
@Component({
selector: 'dx-drawer',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/drop-down-box/index.ts b/packages/devextreme-angular/src/ui/drop-down-box/index.ts
index e7b8e5162ff4..2b0fe88fb92b 100644
--- a/packages/devextreme-angular/src/ui/drop-down-box/index.ts
+++ b/packages/devextreme-angular/src/ui/drop-down-box/index.ts
@@ -100,6 +100,7 @@ const CUSTOM_VALUE_ACCESSOR_PROVIDER = {
@Component({
selector: 'dx-drop-down-box',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/drop-down-button/index.ts b/packages/devextreme-angular/src/ui/drop-down-button/index.ts
index 38dca07540d6..68725ed60f0b 100644
--- a/packages/devextreme-angular/src/ui/drop-down-button/index.ts
+++ b/packages/devextreme-angular/src/ui/drop-down-button/index.ts
@@ -83,6 +83,7 @@ import { DxiDropDownButtonItemComponent } from 'devextreme-angular/ui/drop-down-
@Component({
selector: 'dx-drop-down-button',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/file-manager/index.ts b/packages/devextreme-angular/src/ui/file-manager/index.ts
index 2858ec4b50cf..c74700c1c44f 100644
--- a/packages/devextreme-angular/src/ui/file-manager/index.ts
+++ b/packages/devextreme-angular/src/ui/file-manager/index.ts
@@ -71,6 +71,7 @@ import { DxoFileManagerUploadModule } from 'devextreme-angular/ui/file-manager/n
@Component({
selector: 'dx-file-manager',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/file-uploader/index.ts b/packages/devextreme-angular/src/ui/file-uploader/index.ts
index d3d48e667c76..e6ef3d12e0cc 100644
--- a/packages/devextreme-angular/src/ui/file-uploader/index.ts
+++ b/packages/devextreme-angular/src/ui/file-uploader/index.ts
@@ -61,6 +61,7 @@ const CUSTOM_VALUE_ACCESSOR_PROVIDER = {
@Component({
selector: 'dx-file-uploader',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/filter-builder/index.ts b/packages/devextreme-angular/src/ui/filter-builder/index.ts
index e841274bae15..d3b90b378789 100644
--- a/packages/devextreme-angular/src/ui/filter-builder/index.ts
+++ b/packages/devextreme-angular/src/ui/filter-builder/index.ts
@@ -77,6 +77,7 @@ const CUSTOM_VALUE_ACCESSOR_PROVIDER = {
@Component({
selector: 'dx-filter-builder',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/form/index.ts b/packages/devextreme-angular/src/ui/form/index.ts
index 505cdf3b5e6f..81e95cb10e62 100644
--- a/packages/devextreme-angular/src/ui/form/index.ts
+++ b/packages/devextreme-angular/src/ui/form/index.ts
@@ -86,6 +86,7 @@ import { DxiFormTabbedItemComponent } from 'devextreme-angular/ui/form/nested';
@Component({
selector: 'dx-form',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/funnel/index.ts b/packages/devextreme-angular/src/ui/funnel/index.ts
index c691dba9fc12..9ebf1370ffa5 100644
--- a/packages/devextreme-angular/src/ui/funnel/index.ts
+++ b/packages/devextreme-angular/src/ui/funnel/index.ts
@@ -100,6 +100,7 @@ import { DxoFunnelTooltipBorderModule } from 'devextreme-angular/ui/funnel/neste
selector: 'dx-funnel',
template: '',
styles: [ ' :host { display: block; }'],
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/gallery/index.ts b/packages/devextreme-angular/src/ui/gallery/index.ts
index 93a21ebd9d68..7bdb1787159b 100644
--- a/packages/devextreme-angular/src/ui/gallery/index.ts
+++ b/packages/devextreme-angular/src/ui/gallery/index.ts
@@ -57,6 +57,7 @@ import { DxiGalleryItemComponent } from 'devextreme-angular/ui/gallery/nested';
@Component({
selector: 'dx-gallery',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/gantt/index.ts b/packages/devextreme-angular/src/ui/gantt/index.ts
index ae2633e6fd0f..2c3211e05047 100644
--- a/packages/devextreme-angular/src/ui/gantt/index.ts
+++ b/packages/devextreme-angular/src/ui/gantt/index.ts
@@ -101,6 +101,7 @@ import { DxiGanttStripLineComponent } from 'devextreme-angular/ui/gantt/nested';
@Component({
selector: 'dx-gantt',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/html-editor/index.ts b/packages/devextreme-angular/src/ui/html-editor/index.ts
index 90c0ec1c2e94..959037be7f75 100644
--- a/packages/devextreme-angular/src/ui/html-editor/index.ts
+++ b/packages/devextreme-angular/src/ui/html-editor/index.ts
@@ -88,6 +88,7 @@ const CUSTOM_VALUE_ACCESSOR_PROVIDER = {
@Component({
selector: 'dx-html-editor',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/linear-gauge/index.ts b/packages/devextreme-angular/src/ui/linear-gauge/index.ts
index 1e5c288ef831..6ed91b5cff7c 100644
--- a/packages/devextreme-angular/src/ui/linear-gauge/index.ts
+++ b/packages/devextreme-angular/src/ui/linear-gauge/index.ts
@@ -102,6 +102,7 @@ import { DxoLinearGaugeWidthModule } from 'devextreme-angular/ui/linear-gauge/ne
selector: 'dx-linear-gauge',
template: '',
styles: [ ' :host { display: block; }'],
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/list/index.ts b/packages/devextreme-angular/src/ui/list/index.ts
index e33195b6ceb5..dc789e0b541e 100644
--- a/packages/devextreme-angular/src/ui/list/index.ts
+++ b/packages/devextreme-angular/src/ui/list/index.ts
@@ -74,6 +74,7 @@ import { DxiListMenuItemComponent } from 'devextreme-angular/ui/list/nested';
@Component({
selector: 'dx-list',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/load-indicator/index.ts b/packages/devextreme-angular/src/ui/load-indicator/index.ts
index 0265b2f66fb2..6d7477c7783e 100644
--- a/packages/devextreme-angular/src/ui/load-indicator/index.ts
+++ b/packages/devextreme-angular/src/ui/load-indicator/index.ts
@@ -43,6 +43,7 @@ import {
@Component({
selector: 'dx-load-indicator',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/load-panel/index.ts b/packages/devextreme-angular/src/ui/load-panel/index.ts
index 95fb08fa0afc..dc7dc80ab50f 100644
--- a/packages/devextreme-angular/src/ui/load-panel/index.ts
+++ b/packages/devextreme-angular/src/ui/load-panel/index.ts
@@ -68,6 +68,7 @@ import { DxoLoadPanelToModule } from 'devextreme-angular/ui/load-panel/nested';
@Component({
selector: 'dx-load-panel',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/lookup/index.ts b/packages/devextreme-angular/src/ui/lookup/index.ts
index 38b4de5b29ab..a419b60cc694 100644
--- a/packages/devextreme-angular/src/ui/lookup/index.ts
+++ b/packages/devextreme-angular/src/ui/lookup/index.ts
@@ -100,6 +100,7 @@ const CUSTOM_VALUE_ACCESSOR_PROVIDER = {
@Component({
selector: 'dx-lookup',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/map/index.ts b/packages/devextreme-angular/src/ui/map/index.ts
index 904488efc7ca..baf731e86deb 100644
--- a/packages/devextreme-angular/src/ui/map/index.ts
+++ b/packages/devextreme-angular/src/ui/map/index.ts
@@ -69,6 +69,7 @@ import { DxiMapRouteComponent } from 'devextreme-angular/ui/map/nested';
@Component({
selector: 'dx-map',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/menu/index.ts b/packages/devextreme-angular/src/ui/menu/index.ts
index cd91855cf623..5abcb8d008df 100644
--- a/packages/devextreme-angular/src/ui/menu/index.ts
+++ b/packages/devextreme-angular/src/ui/menu/index.ts
@@ -87,6 +87,7 @@ import { DxiMenuItemComponent } from 'devextreme-angular/ui/menu/nested';
@Component({
selector: 'dx-menu',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/multi-view/index.ts b/packages/devextreme-angular/src/ui/multi-view/index.ts
index b586263e14b2..096003653f38 100644
--- a/packages/devextreme-angular/src/ui/multi-view/index.ts
+++ b/packages/devextreme-angular/src/ui/multi-view/index.ts
@@ -57,6 +57,7 @@ import { DxiMultiViewItemComponent } from 'devextreme-angular/ui/multi-view/nest
@Component({
selector: 'dx-multi-view',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/number-box/index.ts b/packages/devextreme-angular/src/ui/number-box/index.ts
index da92d1b40943..7b7d7a54b534 100644
--- a/packages/devextreme-angular/src/ui/number-box/index.ts
+++ b/packages/devextreme-angular/src/ui/number-box/index.ts
@@ -71,6 +71,7 @@ const CUSTOM_VALUE_ACCESSOR_PROVIDER = {
@Component({
selector: 'dx-number-box',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/pagination/index.ts b/packages/devextreme-angular/src/ui/pagination/index.ts
index 9dff7b407b9f..9f3f483386e4 100644
--- a/packages/devextreme-angular/src/ui/pagination/index.ts
+++ b/packages/devextreme-angular/src/ui/pagination/index.ts
@@ -48,6 +48,7 @@ import {
@Component({
selector: 'dx-pagination',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/pie-chart/index.ts b/packages/devextreme-angular/src/ui/pie-chart/index.ts
index 204333de521e..3f8d1b435358 100644
--- a/packages/devextreme-angular/src/ui/pie-chart/index.ts
+++ b/packages/devextreme-angular/src/ui/pie-chart/index.ts
@@ -123,6 +123,7 @@ import { DxiPieChartSeriesComponent } from 'devextreme-angular/ui/pie-chart/nest
selector: 'dx-pie-chart',
template: '',
styles: [ ' :host { display: block; }'],
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/pivot-grid-field-chooser/index.ts b/packages/devextreme-angular/src/ui/pivot-grid-field-chooser/index.ts
index e07b7e51a860..1ccbfaa197ed 100644
--- a/packages/devextreme-angular/src/ui/pivot-grid-field-chooser/index.ts
+++ b/packages/devextreme-angular/src/ui/pivot-grid-field-chooser/index.ts
@@ -58,6 +58,7 @@ import { DxoPivotGridFieldChooserTextsModule } from 'devextreme-angular/ui/pivot
@Component({
selector: 'dx-pivot-grid-field-chooser',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/pivot-grid/index.ts b/packages/devextreme-angular/src/ui/pivot-grid/index.ts
index bf37de7fa9af..6258e1745313 100644
--- a/packages/devextreme-angular/src/ui/pivot-grid/index.ts
+++ b/packages/devextreme-angular/src/ui/pivot-grid/index.ts
@@ -73,6 +73,7 @@ import { DxoPivotGridTextsModule } from 'devextreme-angular/ui/pivot-grid/nested
@Component({
selector: 'dx-pivot-grid',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/polar-chart/index.ts b/packages/devextreme-angular/src/ui/polar-chart/index.ts
index 4882b6ca7db3..d6f6ae50e9f3 100644
--- a/packages/devextreme-angular/src/ui/polar-chart/index.ts
+++ b/packages/devextreme-angular/src/ui/polar-chart/index.ts
@@ -180,6 +180,7 @@ import { DxiPolarChartSeriesComponent } from 'devextreme-angular/ui/polar-chart/
selector: 'dx-polar-chart',
template: '',
styles: [ ' :host { display: block; }'],
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/popover/index.ts b/packages/devextreme-angular/src/ui/popover/index.ts
index ecc68f7f6d96..f38c2a941a58 100644
--- a/packages/devextreme-angular/src/ui/popover/index.ts
+++ b/packages/devextreme-angular/src/ui/popover/index.ts
@@ -81,6 +81,7 @@ import { DxiPopoverToolbarItemComponent } from 'devextreme-angular/ui/popover/ne
@Component({
selector: 'dx-popover',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/popup/component.ts b/packages/devextreme-angular/src/ui/popup/component.ts
index 5605258d13af..e83b48c0b46f 100644
--- a/packages/devextreme-angular/src/ui/popup/component.ts
+++ b/packages/devextreme-angular/src/ui/popup/component.ts
@@ -77,6 +77,7 @@ import { DxiPopupToolbarItemComponent } from 'devextreme-angular/ui/popup/nested
@Component({
selector: 'dx-popup',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/progress-bar/index.ts b/packages/devextreme-angular/src/ui/progress-bar/index.ts
index 3f044ff271fd..2163cc0b929d 100644
--- a/packages/devextreme-angular/src/ui/progress-bar/index.ts
+++ b/packages/devextreme-angular/src/ui/progress-bar/index.ts
@@ -60,6 +60,7 @@ const CUSTOM_VALUE_ACCESSOR_PROVIDER = {
@Component({
selector: 'dx-progress-bar',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/radio-group/index.ts b/packages/devextreme-angular/src/ui/radio-group/index.ts
index d427bc25e307..bf077ec5b170 100644
--- a/packages/devextreme-angular/src/ui/radio-group/index.ts
+++ b/packages/devextreme-angular/src/ui/radio-group/index.ts
@@ -70,6 +70,7 @@ const CUSTOM_VALUE_ACCESSOR_PROVIDER = {
@Component({
selector: 'dx-radio-group',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/range-selector/index.ts b/packages/devextreme-angular/src/ui/range-selector/index.ts
index 67a0615b7a5f..ae2e732fc709 100644
--- a/packages/devextreme-angular/src/ui/range-selector/index.ts
+++ b/packages/devextreme-angular/src/ui/range-selector/index.ts
@@ -199,6 +199,7 @@ const CUSTOM_VALUE_ACCESSOR_PROVIDER = {
selector: 'dx-range-selector',
template: '',
styles: [ ' :host { display: block; }'],
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/range-slider/index.ts b/packages/devextreme-angular/src/ui/range-slider/index.ts
index b32fd8c57c62..519e4a27ac24 100644
--- a/packages/devextreme-angular/src/ui/range-slider/index.ts
+++ b/packages/devextreme-angular/src/ui/range-slider/index.ts
@@ -67,6 +67,7 @@ const CUSTOM_VALUE_ACCESSOR_PROVIDER = {
@Component({
selector: 'dx-range-slider',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/recurrence-editor/index.ts b/packages/devextreme-angular/src/ui/recurrence-editor/index.ts
index 9ac1c162f741..72e8f7288680 100644
--- a/packages/devextreme-angular/src/ui/recurrence-editor/index.ts
+++ b/packages/devextreme-angular/src/ui/recurrence-editor/index.ts
@@ -60,6 +60,7 @@ const CUSTOM_VALUE_ACCESSOR_PROVIDER = {
@Component({
selector: 'dx-recurrence-editor',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/resizable/index.ts b/packages/devextreme-angular/src/ui/resizable/index.ts
index fc96dbd393b9..631898d4b2e1 100644
--- a/packages/devextreme-angular/src/ui/resizable/index.ts
+++ b/packages/devextreme-angular/src/ui/resizable/index.ts
@@ -43,6 +43,7 @@ import {
@Component({
selector: 'dx-resizable',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/responsive-box/index.ts b/packages/devextreme-angular/src/ui/responsive-box/index.ts
index c869137924e5..821fbaea7f2c 100644
--- a/packages/devextreme-angular/src/ui/responsive-box/index.ts
+++ b/packages/devextreme-angular/src/ui/responsive-box/index.ts
@@ -67,6 +67,7 @@ import { DxiResponsiveBoxRowComponent } from 'devextreme-angular/ui/responsive-b
@Component({
selector: 'dx-responsive-box',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/sankey/index.ts b/packages/devextreme-angular/src/ui/sankey/index.ts
index 84c56ba43dfb..c638513ef740 100644
--- a/packages/devextreme-angular/src/ui/sankey/index.ts
+++ b/packages/devextreme-angular/src/ui/sankey/index.ts
@@ -90,6 +90,7 @@ import { DxoSankeyTooltipBorderModule } from 'devextreme-angular/ui/sankey/neste
selector: 'dx-sankey',
template: '',
styles: [ ' :host { display: block; }'],
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/scheduler/index.ts b/packages/devextreme-angular/src/ui/scheduler/index.ts
index b1ceeb417a34..bb153b8eb94d 100644
--- a/packages/devextreme-angular/src/ui/scheduler/index.ts
+++ b/packages/devextreme-angular/src/ui/scheduler/index.ts
@@ -71,6 +71,7 @@ import { DxiSchedulerViewComponent } from 'devextreme-angular/ui/scheduler/neste
@Component({
selector: 'dx-scheduler',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/scroll-view/index.ts b/packages/devextreme-angular/src/ui/scroll-view/index.ts
index 569a548556d9..7b8e398b5b21 100644
--- a/packages/devextreme-angular/src/ui/scroll-view/index.ts
+++ b/packages/devextreme-angular/src/ui/scroll-view/index.ts
@@ -44,6 +44,7 @@ import {
@Component({
selector: 'dx-scroll-view',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/select-box/index.ts b/packages/devextreme-angular/src/ui/select-box/index.ts
index 1f924f35bf68..b9ef32423707 100644
--- a/packages/devextreme-angular/src/ui/select-box/index.ts
+++ b/packages/devextreme-angular/src/ui/select-box/index.ts
@@ -103,6 +103,7 @@ const CUSTOM_VALUE_ACCESSOR_PROVIDER = {
@Component({
selector: 'dx-select-box',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/slider/index.ts b/packages/devextreme-angular/src/ui/slider/index.ts
index e358987f24fb..f291b731df75 100644
--- a/packages/devextreme-angular/src/ui/slider/index.ts
+++ b/packages/devextreme-angular/src/ui/slider/index.ts
@@ -67,6 +67,7 @@ const CUSTOM_VALUE_ACCESSOR_PROVIDER = {
@Component({
selector: 'dx-slider',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/sortable/index.ts b/packages/devextreme-angular/src/ui/sortable/index.ts
index 345f5819d19b..a2a0ffc65e34 100644
--- a/packages/devextreme-angular/src/ui/sortable/index.ts
+++ b/packages/devextreme-angular/src/ui/sortable/index.ts
@@ -46,6 +46,7 @@ import { DxoSortableCursorOffsetModule } from 'devextreme-angular/ui/sortable/ne
@Component({
selector: 'dx-sortable',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/sparkline/index.ts b/packages/devextreme-angular/src/ui/sparkline/index.ts
index daa6feffe5a6..7460f35df156 100644
--- a/packages/devextreme-angular/src/ui/sparkline/index.ts
+++ b/packages/devextreme-angular/src/ui/sparkline/index.ts
@@ -67,6 +67,7 @@ import { DxoSparklineTooltipModule } from 'devextreme-angular/ui/sparkline/neste
selector: 'dx-sparkline',
template: '',
styles: [ ' :host { display: block; }'],
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/speed-dial-action/index.ts b/packages/devextreme-angular/src/ui/speed-dial-action/index.ts
index 5c680f51653f..462d82de287c 100644
--- a/packages/devextreme-angular/src/ui/speed-dial-action/index.ts
+++ b/packages/devextreme-angular/src/ui/speed-dial-action/index.ts
@@ -43,6 +43,7 @@ import {
@Component({
selector: 'dx-speed-dial-action',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/splitter/index.ts b/packages/devextreme-angular/src/ui/splitter/index.ts
index c700134759db..bb5b91622f79 100644
--- a/packages/devextreme-angular/src/ui/splitter/index.ts
+++ b/packages/devextreme-angular/src/ui/splitter/index.ts
@@ -59,6 +59,7 @@ import { DxiSplitterItemComponent } from 'devextreme-angular/ui/splitter/nested'
@Component({
selector: 'dx-splitter',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/switch/index.ts b/packages/devextreme-angular/src/ui/switch/index.ts
index b453ec276451..9cef3bc96635 100644
--- a/packages/devextreme-angular/src/ui/switch/index.ts
+++ b/packages/devextreme-angular/src/ui/switch/index.ts
@@ -60,6 +60,7 @@ const CUSTOM_VALUE_ACCESSOR_PROVIDER = {
@Component({
selector: 'dx-switch',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/tab-panel/index.ts b/packages/devextreme-angular/src/ui/tab-panel/index.ts
index 35b1cad60c16..bafa5d73762f 100644
--- a/packages/devextreme-angular/src/ui/tab-panel/index.ts
+++ b/packages/devextreme-angular/src/ui/tab-panel/index.ts
@@ -58,6 +58,7 @@ import { DxiTabPanelItemComponent } from 'devextreme-angular/ui/tab-panel/nested
@Component({
selector: 'dx-tab-panel',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/tabs/index.ts b/packages/devextreme-angular/src/ui/tabs/index.ts
index ce5b4da56dbe..1642087e88fd 100644
--- a/packages/devextreme-angular/src/ui/tabs/index.ts
+++ b/packages/devextreme-angular/src/ui/tabs/index.ts
@@ -58,6 +58,7 @@ import { DxiTabsItemComponent } from 'devextreme-angular/ui/tabs/nested';
@Component({
selector: 'dx-tabs',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/tag-box/index.ts b/packages/devextreme-angular/src/ui/tag-box/index.ts
index 1af6813afe7f..e1244d620a96 100644
--- a/packages/devextreme-angular/src/ui/tag-box/index.ts
+++ b/packages/devextreme-angular/src/ui/tag-box/index.ts
@@ -103,6 +103,7 @@ const CUSTOM_VALUE_ACCESSOR_PROVIDER = {
@Component({
selector: 'dx-tag-box',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/text-area/index.ts b/packages/devextreme-angular/src/ui/text-area/index.ts
index 0673d72a6986..329494d95994 100644
--- a/packages/devextreme-angular/src/ui/text-area/index.ts
+++ b/packages/devextreme-angular/src/ui/text-area/index.ts
@@ -60,6 +60,7 @@ const CUSTOM_VALUE_ACCESSOR_PROVIDER = {
@Component({
selector: 'dx-text-area',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/text-box/index.ts b/packages/devextreme-angular/src/ui/text-box/index.ts
index bf2abe7ff1e5..1c571a9e2e40 100644
--- a/packages/devextreme-angular/src/ui/text-box/index.ts
+++ b/packages/devextreme-angular/src/ui/text-box/index.ts
@@ -68,6 +68,7 @@ const CUSTOM_VALUE_ACCESSOR_PROVIDER = {
@Component({
selector: 'dx-text-box',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/tile-view/index.ts b/packages/devextreme-angular/src/ui/tile-view/index.ts
index b910b5558da5..a6f8795e48cb 100644
--- a/packages/devextreme-angular/src/ui/tile-view/index.ts
+++ b/packages/devextreme-angular/src/ui/tile-view/index.ts
@@ -58,6 +58,7 @@ import { DxiTileViewItemComponent } from 'devextreme-angular/ui/tile-view/nested
@Component({
selector: 'dx-tile-view',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/toast/index.ts b/packages/devextreme-angular/src/ui/toast/index.ts
index 161fd1e18d51..71aa90ea233c 100644
--- a/packages/devextreme-angular/src/ui/toast/index.ts
+++ b/packages/devextreme-angular/src/ui/toast/index.ts
@@ -67,6 +67,7 @@ import { DxoToastToModule } from 'devextreme-angular/ui/toast/nested';
@Component({
selector: 'dx-toast',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/toolbar/index.ts b/packages/devextreme-angular/src/ui/toolbar/index.ts
index 86537b50411a..58e419ec184f 100644
--- a/packages/devextreme-angular/src/ui/toolbar/index.ts
+++ b/packages/devextreme-angular/src/ui/toolbar/index.ts
@@ -57,6 +57,7 @@ import { DxiToolbarItemComponent } from 'devextreme-angular/ui/toolbar/nested';
@Component({
selector: 'dx-toolbar',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/tooltip/index.ts b/packages/devextreme-angular/src/ui/tooltip/index.ts
index eac27fa9a018..8b73b18e3217 100644
--- a/packages/devextreme-angular/src/ui/tooltip/index.ts
+++ b/packages/devextreme-angular/src/ui/tooltip/index.ts
@@ -72,6 +72,7 @@ import { DxoTooltipToModule } from 'devextreme-angular/ui/tooltip/nested';
@Component({
selector: 'dx-tooltip',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/tree-list/index.ts b/packages/devextreme-angular/src/ui/tree-list/index.ts
index c86e64430245..78828dac4018 100644
--- a/packages/devextreme-angular/src/ui/tree-list/index.ts
+++ b/packages/devextreme-angular/src/ui/tree-list/index.ts
@@ -195,6 +195,7 @@ import { DxiTreeListColumnComponent } from 'devextreme-angular/ui/tree-list/nest
@Component({
selector: 'dx-tree-list',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/tree-map/index.ts b/packages/devextreme-angular/src/ui/tree-map/index.ts
index 265d37a315e2..0050c51fad0c 100644
--- a/packages/devextreme-angular/src/ui/tree-map/index.ts
+++ b/packages/devextreme-angular/src/ui/tree-map/index.ts
@@ -92,6 +92,7 @@ import { DxoTreeMapTreeMapborderModule } from 'devextreme-angular/ui/tree-map/ne
selector: 'dx-tree-map',
template: '',
styles: [ ' :host { display: block; }'],
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/tree-view/index.ts b/packages/devextreme-angular/src/ui/tree-view/index.ts
index f55cc0577a4f..c999ec9568a9 100644
--- a/packages/devextreme-angular/src/ui/tree-view/index.ts
+++ b/packages/devextreme-angular/src/ui/tree-view/index.ts
@@ -65,6 +65,7 @@ import { DxiTreeViewItemComponent } from 'devextreme-angular/ui/tree-view/nested
@Component({
selector: 'dx-tree-view',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/validation-group/index.ts b/packages/devextreme-angular/src/ui/validation-group/index.ts
index 75da65aa2bff..e16f0c502cdd 100644
--- a/packages/devextreme-angular/src/ui/validation-group/index.ts
+++ b/packages/devextreme-angular/src/ui/validation-group/index.ts
@@ -43,6 +43,7 @@ import {
@Component({
selector: 'dx-validation-group',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/validation-summary/index.ts b/packages/devextreme-angular/src/ui/validation-summary/index.ts
index b60e12402b7b..4d9f6b16aa90 100644
--- a/packages/devextreme-angular/src/ui/validation-summary/index.ts
+++ b/packages/devextreme-angular/src/ui/validation-summary/index.ts
@@ -55,6 +55,7 @@ import { DxiValidationSummaryItemComponent } from 'devextreme-angular/ui/validat
@Component({
selector: 'dx-validation-summary',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/validator/index.ts b/packages/devextreme-angular/src/ui/validator/index.ts
index e2a7c2a6f7db..17126d986bd7 100644
--- a/packages/devextreme-angular/src/ui/validator/index.ts
+++ b/packages/devextreme-angular/src/ui/validator/index.ts
@@ -77,6 +77,7 @@ import { DxiValidatorValidationRuleComponent } from 'devextreme-angular/ui/valid
@Component({
selector: 'dx-validator',
template: '',
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/src/ui/vector-map/index.ts b/packages/devextreme-angular/src/ui/vector-map/index.ts
index 2261d6215ba7..ab619868965b 100644
--- a/packages/devextreme-angular/src/ui/vector-map/index.ts
+++ b/packages/devextreme-angular/src/ui/vector-map/index.ts
@@ -108,6 +108,7 @@ import { DxiVectorMapLegendComponent } from 'devextreme-angular/ui/vector-map/ne
selector: 'dx-vector-map',
template: '',
styles: [ ' :host { display: block; }'],
+ host: { ngSkipHydration: 'true' },
providers: [
DxTemplateHost,
WatcherHelper,
diff --git a/packages/devextreme-angular/tests/src/server/hydration.spec.ts b/packages/devextreme-angular/tests/src/server/hydration.spec.ts
new file mode 100644
index 000000000000..eb95e328e75a
--- /dev/null
+++ b/packages/devextreme-angular/tests/src/server/hydration.spec.ts
@@ -0,0 +1,140 @@
+import { BrowserModule, provideClientHydration } from '@angular/platform-browser';
+import {
+ Component, destroyPlatform, NgModule, PLATFORM_ID, VERSION, importProvidersFrom,
+} from '@angular/core';
+import { provideServerRendering, ServerModule } from '@angular/platform-server';
+import { DxServerModule } from 'devextreme-angular/server';
+import infernoRenderer from 'devextreme/core/inferno_renderer';
+import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
+import { DevExtremeModule } from 'devextreme-angular';
+import { componentNames } from './component-names';
+
+const containerClass = 'container';
+const containerSelector = `.${containerClass}`;
+
+@Component({
+ selector: 'app-root',
+ template: `
+ ${componentNames.map((name) => ``).join('\n')}
+
`,
+})
+class AppComponent {}
+
+@NgModule({
+ declarations: [AppComponent],
+ imports: [BrowserModule, DevExtremeModule],
+ bootstrap: [AppComponent],
+ providers: [provideClientHydration()],
+})
+class AppBrowserModule {}
+
+@NgModule({
+ declarations: [AppComponent],
+ imports: [ServerModule, DevExtremeModule],
+ bootstrap: [AppComponent],
+ providers: [
+ provideClientHydration(),
+ provideServerRendering(),
+ { provide: PLATFORM_ID, useValue: 'server' },
+ importProvidersFrom(DxServerModule),
+ ],
+})
+class AppSSRModule {}
+
+class TestHelpers {
+ static createSSRBodyMarkup(ssrComponentsHTML: string): string {
+ const nghData = '[{}]';
+ return `${ssrComponentsHTML}
+ `;
+ }
+
+ static normalizeClassNames(element: HTMLElement): void {
+ const classNames = Array.from(element.classList).sort();
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+ // @ts-expect-error
+ element.classList.remove(...element.classList);
+ element.classList.add(...classNames);
+ }
+
+ static compareContainers(ssrContainer: HTMLElement, hydratedContainer: HTMLElement): [string, string] {
+ const selector = `${containerSelector} > *`;
+
+ [ssrContainer, hydratedContainer].forEach((container) => {
+ container.querySelectorAll(selector).forEach((el) => {
+ this.normalizeClassNames(el as HTMLElement);
+ });
+ });
+
+ return [ssrContainer.innerHTML, hydratedContainer.innerHTML];
+ }
+
+ static hasConsoleMessage(spy: jasmine.Spy, messages: string[]): boolean {
+ return spy.calls.allArgs().some((args) => messages.some((msg) => args[0].toLowerCase().includes(msg.toLowerCase())));
+ }
+}
+
+describe('Angular Components Hydration Test', () => {
+ let consoleSpies: {
+ warn: jasmine.Spy;
+ error: jasmine.Spy;
+ log: jasmine.Spy;
+ };
+ const ssrState: {
+ body: HTMLElement | null;
+ containerHtml: string;
+ } = {
+ body: null,
+ containerHtml: '',
+ };
+
+ beforeAll(() => {
+ consoleSpies = {
+ warn: spyOn(console, 'warn').and.callThrough(),
+ error: spyOn(console, 'error').and.callThrough(),
+ log: spyOn(console, 'log').and.callThrough(),
+ };
+ });
+
+ beforeEach(() => {
+ destroyPlatform();
+ });
+
+ afterEach(() => {
+ expect(consoleSpies.error).not.toHaveBeenCalled();
+ expect(TestHelpers.hasConsoleMessage(consoleSpies.warn, ['exception', 'hydration'])).toBeFalsy();
+ });
+
+ it('should generate correct SSR HTML', async () => {
+ document.body.innerHTML = '';
+
+ // Act
+ await platformBrowserDynamic().bootstrapModule(AppSSRModule);
+
+ // Assert
+ ssrState.body = document.body;
+ ssrState.containerHtml = document.querySelector(`${containerSelector}`)?.outerHTML ?? '';
+
+ expect(ssrState.containerHtml).toBeTruthy();
+ });
+
+ it('should correctly hydrate server-rendered HTML', async () => {
+ infernoRenderer.resetInjection();
+ document.body.innerHTML = TestHelpers.createSSRBodyMarkup(ssrState.containerHtml);
+
+ // Act
+ await platformBrowserDynamic().bootstrapModule(AppBrowserModule);
+
+ // Assert
+ const [ssrResult, hydratedResult] = TestHelpers.compareContainers(
+ ssrState.body.querySelector(`${containerSelector}`),
+ document.querySelector(`${containerSelector}`),
+ );
+
+ expect(TestHelpers.hasConsoleMessage(
+ consoleSpies.log,
+ ['Angular hydrated 1 component(s)'],
+ )).toBeTruthy();
+
+ expect(ssrResult).toEqual(hydratedResult);
+ });
+});