diff --git a/apps/demos/Demos/Stepper/StepTemplate/Angular/app/app.component.html b/apps/demos/Demos/Stepper/StepTemplate/Angular/app/app.component.html
index 0128c7d521dd..e1c08fa86bc7 100644
--- a/apps/demos/Demos/Stepper/StepTemplate/Angular/app/app.component.html
+++ b/apps/demos/Demos/Stepper/StepTemplate/Angular/app/app.component.html
@@ -41,6 +41,11 @@
[elementAttr]="{ 'aria-labelledby': 'label-iconOnly' }"
>
-
+
diff --git a/apps/demos/Demos/Stepper/StepTemplate/React/IconOnly.tsx b/apps/demos/Demos/Stepper/StepTemplate/React/IconOnly.tsx
index d84e95907c85..bb0e60634491 100644
--- a/apps/demos/Demos/Stepper/StepTemplate/React/IconOnly.tsx
+++ b/apps/demos/Demos/Stepper/StepTemplate/React/IconOnly.tsx
@@ -2,10 +2,11 @@ import React from 'react';
interface IconOnlyProps {
icon: string;
+ label: string;
}
-export default function IconOnly({ icon }: IconOnlyProps) {
+export default function IconOnly({ icon, label }: IconOnlyProps) {
return (
-
+
);
}
diff --git a/apps/demos/Demos/Stepper/StepTemplate/ReactJs/IconOnly.js b/apps/demos/Demos/Stepper/StepTemplate/ReactJs/IconOnly.js
index 1344ad909c1d..466eafa507af 100644
--- a/apps/demos/Demos/Stepper/StepTemplate/ReactJs/IconOnly.js
+++ b/apps/demos/Demos/Stepper/StepTemplate/ReactJs/IconOnly.js
@@ -1,5 +1,11 @@
import React from 'react';
-export default function IconOnly({ icon }) {
- return ;
+export default function IconOnly({ icon, label }) {
+ return (
+
+ );
}
diff --git a/apps/demos/Demos/Stepper/StepTemplate/Vue/App.vue b/apps/demos/Demos/Stepper/StepTemplate/Vue/App.vue
index 3906f4b74716..9e18cba26b03 100644
--- a/apps/demos/Demos/Stepper/StepTemplate/Vue/App.vue
+++ b/apps/demos/Demos/Stepper/StepTemplate/Vue/App.vue
@@ -57,7 +57,11 @@
>
-
+
diff --git a/apps/demos/Demos/Stepper/StepTemplate/jQuery/index.js b/apps/demos/Demos/Stepper/StepTemplate/jQuery/index.js
index fd5945874d17..69de8d20fcbc 100644
--- a/apps/demos/Demos/Stepper/StepTemplate/jQuery/index.js
+++ b/apps/demos/Demos/Stepper/StepTemplate/jQuery/index.js
@@ -33,7 +33,7 @@ $(() => {
linear: false,
elementAttr: { 'aria-labelledby': 'label-iconOnly' },
itemTemplate(data) {
- return ``;
+ return ``;
},
});
});
diff --git a/apps/demos/Demos/TabPanel/Overview/Angular/app/app.component.css b/apps/demos/Demos/TabPanel/Overview/Angular/app/app.component.css
index 046af40d3171..320a5f6dc23e 100644
--- a/apps/demos/Demos/TabPanel/Overview/Angular/app/app.component.css
+++ b/apps/demos/Demos/TabPanel/Overview/Angular/app/app.component.css
@@ -104,7 +104,7 @@
::ng-deep .task-item-info {
font-size: 12px;
- opacity: 0.6;
+ opacity: 0.65;
}
::ng-deep .task-item-pseudo-button {
diff --git a/apps/demos/Demos/TabPanel/Overview/React/styles.css b/apps/demos/Demos/TabPanel/Overview/React/styles.css
index 7d2c7f569c05..71ad3ea17b02 100644
--- a/apps/demos/Demos/TabPanel/Overview/React/styles.css
+++ b/apps/demos/Demos/TabPanel/Overview/React/styles.css
@@ -104,7 +104,7 @@
.task-item-info {
font-size: 12px;
- opacity: 0.6;
+ opacity: 0.65;
}
.task-item-pseudo-button {
diff --git a/apps/demos/Demos/TabPanel/Overview/ReactJs/styles.css b/apps/demos/Demos/TabPanel/Overview/ReactJs/styles.css
index 7d2c7f569c05..71ad3ea17b02 100644
--- a/apps/demos/Demos/TabPanel/Overview/ReactJs/styles.css
+++ b/apps/demos/Demos/TabPanel/Overview/ReactJs/styles.css
@@ -104,7 +104,7 @@
.task-item-info {
font-size: 12px;
- opacity: 0.6;
+ opacity: 0.65;
}
.task-item-pseudo-button {
diff --git a/apps/demos/Demos/TabPanel/Overview/Vue/TaskItem.vue b/apps/demos/Demos/TabPanel/Overview/Vue/TaskItem.vue
index bfe6973f9762..76699ee28f0d 100644
--- a/apps/demos/Demos/TabPanel/Overview/Vue/TaskItem.vue
+++ b/apps/demos/Demos/TabPanel/Overview/Vue/TaskItem.vue
@@ -66,7 +66,7 @@ withDefaults(defineProps<{
.task-item-info {
font-size: 12px;
- opacity: 0.6;
+ opacity: 0.65;
}
.task-item-pseudo-button {
diff --git a/apps/demos/Demos/TabPanel/Overview/jQuery/styles.css b/apps/demos/Demos/TabPanel/Overview/jQuery/styles.css
index 7d2c7f569c05..71ad3ea17b02 100644
--- a/apps/demos/Demos/TabPanel/Overview/jQuery/styles.css
+++ b/apps/demos/Demos/TabPanel/Overview/jQuery/styles.css
@@ -104,7 +104,7 @@
.task-item-info {
font-size: 12px;
- opacity: 0.6;
+ opacity: 0.65;
}
.task-item-pseudo-button {
diff --git a/apps/demos/testing/common.test.ts b/apps/demos/testing/common.test.ts
index 0a1c33a8f06c..d26e72db336e 100644
--- a/apps/demos/testing/common.test.ts
+++ b/apps/demos/testing/common.test.ts
@@ -112,6 +112,21 @@ const getIgnoredRules = (testName) => {
'Gantt-Validation': ['aria-required-parent', 'aria-valid-attr-value'],
'Localization-UsingGlobalize': ['label'],
+
+ // Appointments painted with saturated resource colors keep the theme's dark text,
+ // so their title/date contrast drops below AA. Needs a scheduler-level fix.
+ 'Scheduler-AppointmentCountPerCell': ['color-contrast'],
+ 'Scheduler-ContextMenu': ['color-contrast'],
+ 'Scheduler-GroupByDate': ['color-contrast'],
+ 'Scheduler-GroupingByResources': ['color-contrast'],
+ 'Scheduler-RecurringAppointments': ['color-contrast'],
+ 'Scheduler-ResolveTimeConflicts': ['color-contrast'],
+ 'Scheduler-Timelines': ['color-contrast'],
+ 'Scheduler-VirtualScrolling': ['color-contrast'],
+
+ // Icon-only tabs render no text, so they have no accessible name.
+ // Naming them needs Tabs widget support (like Button labels icon-only buttons).
+ 'Tabs-Overview': ['aria-tab-name'],
};
return [
diff --git a/packages/devextreme-scss/scss/widgets/fluent/tabs/layout/tab/_base.scss b/packages/devextreme-scss/scss/widgets/fluent/tabs/layout/tab/_base.scss
index 43392b992139..8df5c299c277 100644
--- a/packages/devextreme-scss/scss/widgets/fluent/tabs/layout/tab/_base.scss
+++ b/packages/devextreme-scss/scss/widgets/fluent/tabs/layout/tab/_base.scss
@@ -31,21 +31,13 @@
}
.dx-tab-text .dx-tab-text-span {
- visibility: visible;
-
- .dx-tab-text-span-pseudo {
- visibility: hidden;
- }
+ font-weight: $fluent-tab-font-weight-accent;
}
}
&.dx-state-disabled {
color: $tabs-tab-disabled-color;
- .dx-tab-text .dx-tab-text-span-pseudo {
- color: $tabs-tab-disabled-color;
- }
-
.dx-icon {
color: $tabs-tab-icon-disabled-color;
}
@@ -61,22 +53,17 @@
line-height: $fluent-line-height;
.dx-tab-text-span {
- position: relative;
display: block;
- font-weight: $fluent-tab-font-weight-accent;
- visibility: hidden;
+ font-weight: $fluent-tab-font-weight-basic;
}
+ // The hidden zero-height pseudo span reserves the accent-weight (selected) width; the visible text span provides the tab's accessible name.
.dx-tab-text-span-pseudo {
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
+ display: block;
+ height: 0;
pointer-events: none;
- color: $tabs-tab-color;
- font-weight: $fluent-tab-font-weight-basic;
- visibility: visible;
+ font-weight: $fluent-tab-font-weight-accent;
+ visibility: hidden;
}
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 6cab23141008..5663ed01503e 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -80,8 +80,8 @@ catalogs:
specifier: 8.52.0
version: 8.52.0
axe-core:
- specifier: 4.11.3
- version: 4.11.3
+ specifier: 4.13.0
+ version: 4.13.0
devexpress-diagram:
specifier: 2.2.29
version: 2.2.29
@@ -258,7 +258,7 @@ importers:
version: 17.0.35
axe-core:
specifier: 'catalog:'
- version: 4.11.3
+ version: 4.13.0
chokidar:
specifier: 5.0.0
version: 5.0.0
@@ -641,7 +641,7 @@ importers:
version: 5.10.0(eslint@9.39.4(jiti@2.6.1)(supports-color@7.2.0))
'@testcafe-community/axe':
specifier: 3.5.0
- version: 3.5.0(axe-core@4.11.3)(testcafe@3.7.5)
+ version: 3.5.0(axe-core@4.13.0)(testcafe@3.7.5)
'@types/eslint':
specifier: 8.56.12
version: 8.56.12
@@ -674,7 +674,7 @@ importers:
version: 0.9.1(typescript@6.0.3)(vue@3.5.32(typescript@6.0.3))
axe-core:
specifier: 'catalog:'
- version: 4.11.3
+ version: 4.13.0
babel-jest:
specifier: 30.4.1
version: 30.4.1(@babel/core@7.29.7)
@@ -1124,7 +1124,7 @@ importers:
version: 5.10.0(eslint@9.39.4(jiti@2.6.1))
'@testcafe-community/axe':
specifier: 3.5.0
- version: 3.5.0(axe-core@4.11.3)(testcafe@3.7.5)
+ version: 3.5.0(axe-core@4.13.0)(testcafe@3.7.5)
'@types/jquery':
specifier: 'catalog:'
version: 4.0.1
@@ -1136,7 +1136,7 @@ importers:
version: 8.52.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)
axe-core:
specifier: 'catalog:'
- version: 4.11.3
+ version: 4.13.0
devextreme:
specifier: workspace:*
version: link:../../packages/devextreme/artifacts/npm/devextreme
@@ -1459,7 +1459,7 @@ importers:
version: 8.52.0(eslint@9.39.4(jiti@2.6.1))(typescript@4.9.5)
axe-core:
specifier: 'catalog:'
- version: 4.11.3
+ version: 4.13.0
babel-plugin-inferno:
specifier: 6.8.5
version: 6.8.5(@babel/core@7.29.7)
@@ -8824,14 +8824,14 @@ packages:
resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==}
engines: {node: '>= 0.4'}
- axe-core@4.11.3:
- resolution: {integrity: sha512-zBQouZixDTbo3jMGqHKyePxYxr1e5W8UdTmBQ7sNtaA9M2bE32daxxPLS/jojhKOHxQ7LWwPjfiwf/fhaJWzlg==}
- engines: {node: '>=4'}
-
axe-core@4.12.1:
resolution: {integrity: sha512-s7iGf5GaVMxEG0ENN9x+xTr7GFZCb1ZP/1uATUpCEK2X78nDB3RwbtFCo9pGAf9ru+VwoQ464DkaLEeRM08wJA==}
engines: {node: '>=4'}
+ axe-core@4.13.0:
+ resolution: {integrity: sha512-UzGt8zg7Ny8djbYMhxl2zuEevVa7r2gJjYY5Lwr1xM7+XU2nd6CkIWFTVcCIbAP63vSz71NaVyyuSk9lHKcy0A==}
+ engines: {node: '>=4'}
+
axios@1.18.1:
resolution: {integrity: sha512-3nTvFlvpn9Zu/RkHUqtc7/+al4UpRW5az71ap5zccp6e8RAYEzhMTecX8Dz1wWDYrPpUoB1HAQEGEAEvUr7S9g==}
@@ -24294,9 +24294,9 @@ snapshots:
dependencies:
'@swc/counter': 0.1.3
- '@testcafe-community/axe@3.5.0(axe-core@4.11.3)(testcafe@3.7.5)':
+ '@testcafe-community/axe@3.5.0(axe-core@4.13.0)(testcafe@3.7.5)':
dependencies:
- axe-core: 4.11.3
+ axe-core: 4.13.0
chalk: 2.4.2
testcafe: 3.7.5(supports-color@7.2.0)
@@ -26366,10 +26366,10 @@ snapshots:
dependencies:
possible-typed-array-names: 1.1.0
- axe-core@4.11.3: {}
-
axe-core@4.12.1: {}
+ axe-core@4.13.0: {}
+
axios@1.18.1:
dependencies:
follow-redirects: 1.16.0(debug@4.4.3)
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
index 0494ceb08b2d..d5122c8485e0 100644
--- a/pnpm-workspace.yaml
+++ b/pnpm-workspace.yaml
@@ -63,7 +63,7 @@ overrides:
"dompurify@<=3.4.12": "^3.4.13"
"nanoid@<3.3.17": "^3.3.17"
catalog:
- axe-core: 4.11.3
+ axe-core: 4.13.0
inferno: ^8.2.3
inferno-hydrate: ^8.2.3
inferno-create-element: ^8.2.3