;
} & DefaultTestType;
@@ -49,11 +54,15 @@ const gotoPage = async (
page: Page,
path: string,
color: string,
- fixedHeight?: number
+ fixedHeight?: number,
+ otherDensity?: 'functional' | 'regular' | 'expressive'
) => {
- await page.goto(`./#/${path}?density=${density}&color=${color}`, {
- waitUntil: 'domcontentloaded'
- });
+ await page.goto(
+ `./#/${path}?density=${otherDensity ?? density}&color=${color}`,
+ {
+ waitUntil: 'domcontentloaded'
+ }
+ );
await waitForDBPage(page);
await setScrollViewport(page, fixedHeight)();
@@ -67,7 +76,7 @@ export const getDefaultScreenshotTest = ({
fixedHeight,
preScreenShot
}: DefaultSnapshotTestType) => {
- test(`should match screenshot`, async ({ page }, testInfo) => {
+ test(`should match screenshot`, async ({ page }) => {
const showcase = process.env.showcase;
const diffPixel = process.env.diff;
const maxDiffPixelRatio = process.env.ratio;
@@ -89,7 +98,7 @@ export const getDefaultScreenshotTest = ({
config.maxDiffPixels = 120;
}
- await gotoPage(page, path, 'neutral-bg-basic-level-1', fixedHeight);
+ await gotoPage(page, path, lvl1, fixedHeight);
const header = await page.locator('header').first();
@@ -108,55 +117,60 @@ const shouldSkipA11yTest = (project: FullProject): boolean =>
project.name === 'webkit' ||
project.name.startsWith('mobile');
-export const getA11yTest = ({
+export const runAxeCoreTest = ({
path,
fixedHeight,
axeDisableRules,
skipAxe,
preAxe,
- aCheckerDisableRules,
- preChecker,
- skipChecker
-}: DefaultA11yTestType) => {
- for (const color of COLORS) {
- test(`should not have any A11y issues for color ${color}`, async ({
- page
- }, { project }) => {
- const isLevelOne = color.endsWith('-1');
- // We don't need to check color contrast for every project (just for chrome)
- if (skipAxe ?? (!isLevelOne && shouldSkipA11yTest(project))) {
- test.skip();
- }
+ color = lvl1,
+ density = 'regular'
+}: AxeCoreTestType) => {
+ test(`should not have any A11y issues for density ${density} and color ${color}`, async ({
+ page
+ }, { project }) => {
+ const isLevelOne = color.endsWith('-1');
+ // We don't need to check color contrast for every project (just for chrome)
+ if (skipAxe ?? (!isLevelOne && shouldSkipA11yTest(project))) {
+ test.skip();
+ }
- await gotoPage(page, path, color, fixedHeight);
-
- // This is a workaround for axe for browsers using forcedColors
- // see https://github.com/dequelabs/axe-core-npm/issues/1067
- await page.evaluate(($project) => {
- if ($project.use.contextOptions?.forcedColors === 'active') {
- const style = document.createElement('style');
- document.head.append(style);
- const textColor =
- $project.use.colorScheme === 'dark' ? '#fff' : '#000';
- style.textContent = `* {-webkit-text-stroke-color:${textColor}!important;-webkit-text-fill-color:${textColor}!important;}`;
- }
- }, project);
-
- if (preAxe) {
- await preAxe(page);
+ await gotoPage(page, path, color, fixedHeight, density);
+
+ // This is a workaround for axe for browsers using forcedColors
+ // see https://github.com/dequelabs/axe-core-npm/issues/1067
+ await page.evaluate(($project) => {
+ if ($project.use.contextOptions?.forcedColors === 'active') {
+ const style = document.createElement('style');
+ document.head.append(style);
+ const textColor =
+ $project.use.colorScheme === 'dark' ? '#fff' : '#000';
+ style.textContent = `* {-webkit-text-stroke-color:${textColor}!important;-webkit-text-fill-color:${textColor}!important;}`;
}
+ }, project);
+
+ if (preAxe) {
+ await preAxe(page);
+ }
- const accessibilityScanResults = await new AxeBuilder({
- page
- })
- .include('main')
- .disableRules(axeDisableRules ?? [])
- .analyze();
+ const accessibilityScanResults = await new AxeBuilder({
+ page
+ })
+ .include('main')
+ .disableRules(axeDisableRules ?? [])
+ .analyze();
- expect(accessibilityScanResults.violations).toEqual([]);
- });
- }
+ expect(accessibilityScanResults.violations).toEqual([]);
+ });
+};
+export const runA11yCheckerTest = ({
+ path,
+ fixedHeight,
+ aCheckerDisableRules,
+ preChecker,
+ skipChecker
+}: A11yCheckerTestType) => {
test('test with accessibility checker', async ({ page }, { project }) => {
if (skipChecker ?? shouldSkipA11yTest(project)) {
// Checking complete DOM in Firefox and Webkit takes very long, we skip this test
@@ -166,7 +180,7 @@ export const getA11yTest = ({
test.slow(); // Easy way to triple the default timeout
- await gotoPage(page, path, 'neutral-bg-basic-level-1', fixedHeight);
+ await gotoPage(page, path, lvl1, fixedHeight);
if (preChecker) {
await preChecker(page);
diff --git a/showcases/e2e/divider/divider-a11y.spec.ts b/showcases/e2e/divider/divider-a11y.spec.ts
index 765130c031a..3fe67385abe 100644
--- a/showcases/e2e/divider/divider-a11y.spec.ts
+++ b/showcases/e2e/divider/divider-a11y.spec.ts
@@ -1,7 +1,11 @@
import { test } from '@playwright/test';
// @ts-expect-error - required for playwright
-import { getA11yTest } from '../default.ts';
+import { runA11yCheckerTest, runAxeCoreTest } from '../default.ts';
+import { lvl3 } from '../fixtures/variants';
test.describe('DBDivider', () => {
- getA11yTest({ path: '01/divider' });
+ runAxeCoreTest({ path: '01/divider' });
+ runAxeCoreTest({ path: '01/divider', color: lvl3 });
+ runAxeCoreTest({ path: '01/divider', density: 'functional' });
+ runA11yCheckerTest({ path: '01/divider' });
});
diff --git a/showcases/e2e/divider/divider-snapshots.spec.ts b/showcases/e2e/divider/divider-snapshot.spec.ts
similarity index 100%
rename from showcases/e2e/divider/divider-snapshots.spec.ts
rename to showcases/e2e/divider/divider-snapshot.spec.ts
diff --git a/showcases/e2e/drawer/drawer-a11y.spec.ts b/showcases/e2e/drawer/drawer-a11y.spec.ts
index 4aa5b9638f9..b4aba15aca2 100644
--- a/showcases/e2e/drawer/drawer-a11y.spec.ts
+++ b/showcases/e2e/drawer/drawer-a11y.spec.ts
@@ -1,13 +1,16 @@
-import { test } from '@playwright/test';
+import { type Page, test } from '@playwright/test';
// @ts-expect-error - required for playwright
-import { getA11yTest } from '../default.ts';
+import { runA11yCheckerTest, runAxeCoreTest } from '../default.ts';
+import { lvl3 } from '../fixtures/variants';
+
+const preAxe = async (page: Page) => {
+ await page.locator('main').getByRole('button').first().click();
+ await page.waitForTimeout(1000);
+};
test.describe('DBDrawer', () => {
- getA11yTest({
- path: '01/drawer',
- async preAxe(page) {
- await page.locator('main').getByRole('button').first().click();
- await page.waitForTimeout(1000);
- }
- });
+ runAxeCoreTest({ path: '01/drawer', preAxe });
+ runAxeCoreTest({ path: '01/drawer', preAxe, color: lvl3 });
+ runAxeCoreTest({ path: '01/drawer', preAxe, density: 'functional' });
+ runA11yCheckerTest({ path: '01/drawer' });
});
diff --git a/showcases/e2e/fixtures/variants.ts b/showcases/e2e/fixtures/variants.ts
index 5f1be999ec1..1752dd7c287 100644
--- a/showcases/e2e/fixtures/variants.ts
+++ b/showcases/e2e/fixtures/variants.ts
@@ -1,5 +1,2 @@
-export const COLORS = [
- 'neutral-bg-basic-level-1',
- 'neutral-bg-basic-level-2',
- 'neutral-bg-basic-level-3'
-];
+export const lvl1 = 'neutral-bg-basic-level-1';
+export const lvl3 = 'neutral-bg-basic-level-3';
diff --git a/showcases/e2e/header/header-a11y.spec.ts b/showcases/e2e/header/header-a11y.spec.ts
index 65770f6a5a8..7023c564fe6 100644
--- a/showcases/e2e/header/header-a11y.spec.ts
+++ b/showcases/e2e/header/header-a11y.spec.ts
@@ -1,12 +1,30 @@
import { test } from '@playwright/test';
-// @ts-expect-error - required for playwright
-import { getA11yTest, hasWebComponentSyntax, isStencil } from '../default.ts';
+import {
+ hasWebComponentSyntax,
+ runAxeCoreTest,
+ runA11yCheckerTest
+ // @ts-expect-error - required for playwright
+} from '../default.ts';
+import { lvl3 } from '../fixtures/variants';
test.describe('DBHeader', () => {
- getA11yTest({
+ runAxeCoreTest({
+ path: '01/header',
+ skipAxe: hasWebComponentSyntax(process.env.showcase)
+ });
+ runAxeCoreTest({
+ path: '01/header',
+ color: lvl3,
+ skipAxe: hasWebComponentSyntax(process.env.showcase)
+ });
+ runAxeCoreTest({
+ path: '01/header',
+ density: 'functional',
+ skipAxe: hasWebComponentSyntax(process.env.showcase)
+ });
+ // TODO: We skip this for now until mitosis output is correct
+ runA11yCheckerTest({
path: '01/header',
- skipAxe: hasWebComponentSyntax(process.env.showcase),
- // TODO: We skip this for now until mitosis output is correct
skipChecker: hasWebComponentSyntax(process.env.showcase)
});
});
diff --git a/showcases/e2e/icon/icon-a11y.spec.ts b/showcases/e2e/icon/icon-a11y.spec.ts
index 3b6a594c60a..d6f1598eee5 100644
--- a/showcases/e2e/icon/icon-a11y.spec.ts
+++ b/showcases/e2e/icon/icon-a11y.spec.ts
@@ -1,7 +1,11 @@
import { test } from '@playwright/test';
// @ts-expect-error - required for playwright
-import { getA11yTest } from '../default.ts';
+import { runA11yCheckerTest, runAxeCoreTest } from '../default.ts';
+import { lvl3 } from '../fixtures/variants';
test.describe('DBIcon', () => {
- getA11yTest({ path: '04/icon' });
+ runAxeCoreTest({ path: '04/icon' });
+ runAxeCoreTest({ path: '04/icon', color: lvl3 });
+ runAxeCoreTest({ path: '04/icon', density: 'functional' });
+ runA11yCheckerTest({ path: '04/icon' });
});
diff --git a/showcases/e2e/infotext/infotext-a11y.spec.ts b/showcases/e2e/infotext/infotext-a11y.spec.ts
index cd26a1ebf6e..7a0c5acfb14 100644
--- a/showcases/e2e/infotext/infotext-a11y.spec.ts
+++ b/showcases/e2e/infotext/infotext-a11y.spec.ts
@@ -1,7 +1,11 @@
import { test } from '@playwright/test';
// @ts-expect-error - required for playwright
-import { getA11yTest } from '../default.ts';
+import { runA11yCheckerTest, runAxeCoreTest } from '../default.ts';
+import { lvl3 } from '../fixtures/variants';
test.describe('DBInfotext', () => {
- getA11yTest({ path: '04/infotext' });
+ runAxeCoreTest({ path: '04/infotext' });
+ runAxeCoreTest({ path: '04/infotext', color: lvl3 });
+ runAxeCoreTest({ path: '04/infotext', density: 'functional' });
+ runA11yCheckerTest({ path: '04/infotext' });
});
diff --git a/showcases/e2e/input/input-a11y.spec.ts b/showcases/e2e/input/input-a11y.spec.ts
index 98979b4b568..97915e7c5bc 100644
--- a/showcases/e2e/input/input-a11y.spec.ts
+++ b/showcases/e2e/input/input-a11y.spec.ts
@@ -1,12 +1,18 @@
import { test } from '@playwright/test';
// @ts-expect-error - required for playwright
-import { getA11yTest } from '../default.ts';
+import { runA11yCheckerTest, runAxeCoreTest } from '../default.ts';
+import { lvl3 } from '../fixtures/variants';
+const axeDisableRules = ['color-contrast']; // TODO: Currently disable till we solved https://github.com/db-ui/mono/issues/2587
test.describe('DBInput', () => {
- // TODO: Currently disable till we solved https://github.com/db-ui/mono/issues/2587
- getA11yTest({
+ runAxeCoreTest({ path: '03/input', axeDisableRules });
+ runAxeCoreTest({ path: '03/input', color: lvl3, axeDisableRules });
+ runAxeCoreTest({
path: '03/input',
- axeDisableRules: ['color-contrast'],
- aCheckerDisableRules: ['label_ref_valid'] // TODO: There is an issue with datetime-local - https://github.com/IBMa/equal-access/issues/1910
+ density: 'functional',
+ axeDisableRules
+ });
+ runA11yCheckerTest({
+ path: '03/input'
});
});
diff --git a/showcases/e2e/link/link-a11y.spec.ts b/showcases/e2e/link/link-a11y.spec.ts
index a37f779bdaf..081dfc4d7ca 100644
--- a/showcases/e2e/link/link-a11y.spec.ts
+++ b/showcases/e2e/link/link-a11y.spec.ts
@@ -1,15 +1,19 @@
import { test } from '@playwright/test';
// @ts-expect-error - required for playwright
-import { getA11yTest, isStencil } from '../default.ts';
+import { isStencil, runA11yCheckerTest, runAxeCoreTest } from '../default.ts';
+import { lvl3 } from '../fixtures/variants';
+
+const axeDisableRules = isStencil(process.env.showcase)
+ ? ['color-contrast']
+ : [];
+
+const aCheckerDisableRules = isStencil(process.env.showcase)
+ ? ['text_contrast_sufficient', 'aria_attribute_valid']
+ : ['aria_attribute_valid']; // TODO: This is a false positive -> add an issue in https://github.com/IBMa/equal-access
test.describe('DBLink', () => {
- getA11yTest({
- path: '02/link',
- axeDisableRules: isStencil(process.env.showcase)
- ? ['color-contrast']
- : [],
- aCheckerDisableRules: isStencil(process.env.showcase)
- ? ['text_contrast_sufficient', 'aria_attribute_valid']
- : ['aria_attribute_valid'] // TODO: This is a false positive -> add an issue in https://github.com/IBMa/equal-access
- });
+ runAxeCoreTest({ path: '02/link', axeDisableRules });
+ runAxeCoreTest({ path: '02/link', color: lvl3, axeDisableRules });
+ runAxeCoreTest({ path: '02/link', density: 'functional', axeDisableRules });
+ runA11yCheckerTest({ path: '02/link', aCheckerDisableRules });
});
diff --git a/showcases/e2e/navigation-item/navigation-item-a11y.spec.ts b/showcases/e2e/navigation-item/navigation-item-a11y.spec.ts
index 22f80f8a925..d0e2a900a3e 100644
--- a/showcases/e2e/navigation-item/navigation-item-a11y.spec.ts
+++ b/showcases/e2e/navigation-item/navigation-item-a11y.spec.ts
@@ -1,12 +1,27 @@
import { test } from '@playwright/test';
-// @ts-expect-error - required for playwright
-import { getA11yTest, hasWebComponentSyntax } from '../default.ts';
+import {
+ hasWebComponentSyntax,
+ runAxeCoreTest,
+ runA11yCheckerTest
+ // @ts-expect-error - required for playwright
+} from '../default.ts';
+import { lvl3 } from '../fixtures/variants';
+const fixedHeight = 1800; // Set fixed height, because of issues with angulars `ngAfterContentInit`
+const skipAxe = hasWebComponentSyntax(process.env.showcase);
test.describe('DBNavigationItem', () => {
- // Set fixed height, because of issues with angulars `ngAfterContentInit`
- getA11yTest({
+ runAxeCoreTest({ path: '05/navigation-item', fixedHeight, skipAxe });
+ runAxeCoreTest({
path: '05/navigation-item',
- fixedHeight: 1800,
- skipAxe: hasWebComponentSyntax(process.env.showcase)
+ color: lvl3,
+ fixedHeight,
+ skipAxe
});
+ runAxeCoreTest({
+ path: '05/navigation-item',
+ density: 'functional',
+ fixedHeight,
+ skipAxe
+ });
+ runA11yCheckerTest({ path: '05/navigation-item', fixedHeight });
});
diff --git a/showcases/e2e/navigation/navigation-a11y.spec.ts b/showcases/e2e/navigation/navigation-a11y.spec.ts
index 445e53df589..c96c3abee4e 100644
--- a/showcases/e2e/navigation/navigation-a11y.spec.ts
+++ b/showcases/e2e/navigation/navigation-a11y.spec.ts
@@ -1,10 +1,16 @@
import { expect, test } from '@playwright/test';
-// @ts-expect-error - required for playwright
-import { getA11yTest, hasWebComponentSyntax } from '../default.ts';
+import {
+ hasWebComponentSyntax,
+ runAxeCoreTest,
+ runA11yCheckerTest
+ // @ts-expect-error - required for playwright
+} from '../default.ts';
+import { lvl3 } from '../fixtures/variants';
+const skipAxe = hasWebComponentSyntax(process.env.showcase);
test.describe('DBNavigation', () => {
- getA11yTest({
- path: '05/navigation',
- skipAxe: hasWebComponentSyntax(process.env.showcase)
- });
+ runAxeCoreTest({ path: '05/navigation', skipAxe });
+ runAxeCoreTest({ path: '05/navigation', color: lvl3, skipAxe });
+ runAxeCoreTest({ path: '05/navigation', density: 'functional', skipAxe });
+ runA11yCheckerTest({ path: '05/navigation' });
});
diff --git a/showcases/e2e/notification/notification-a11y.spec.ts b/showcases/e2e/notification/notification-a11y.spec.ts
index 392182c0b88..49c6b2eb4fe 100644
--- a/showcases/e2e/notification/notification-a11y.spec.ts
+++ b/showcases/e2e/notification/notification-a11y.spec.ts
@@ -1,7 +1,11 @@
import { test } from '@playwright/test';
// @ts-expect-error - required for playwright
-import { getA11yTest } from '../default.ts';
+import { runA11yCheckerTest, runAxeCoreTest } from '../default.ts';
+import { lvl3 } from '../fixtures/variants';
test.describe('DBNotification', () => {
- getA11yTest({ path: '06/notification' });
+ runAxeCoreTest({ path: '06/notification' });
+ runAxeCoreTest({ path: '06/notification', color: lvl3 });
+ runAxeCoreTest({ path: '06/notification', density: 'functional' });
+ runA11yCheckerTest({ path: '06/notification' });
});
diff --git a/showcases/e2e/popover/popover-a11y.spec.ts b/showcases/e2e/popover/popover-a11y.spec.ts
index 8dd2bee704b..419b109191c 100644
--- a/showcases/e2e/popover/popover-a11y.spec.ts
+++ b/showcases/e2e/popover/popover-a11y.spec.ts
@@ -1,13 +1,16 @@
-import { test } from '@playwright/test';
+import { type Page, test } from '@playwright/test';
// @ts-expect-error - required for playwright
-import { getA11yTest } from '../default.ts';
+import { runA11yCheckerTest, runAxeCoreTest } from '../default.ts';
import { hoverPre } from '../fixtures/hover';
+import { lvl3 } from '../fixtures/variants';
const selector = '.db-popover';
+const preAxe = async (page: Page) => hoverPre(page, selector);
+
test.describe('DBPopover', () => {
- getA11yTest({
- path: '01/popover',
- preAxe: async (page) => hoverPre(page, selector)
- });
+ runAxeCoreTest({ path: '01/popover', preAxe });
+ runAxeCoreTest({ path: '01/popover', color: lvl3, preAxe });
+ runAxeCoreTest({ path: '01/popover', density: 'functional', preAxe });
+ runA11yCheckerTest({ path: '01/popover' });
});
diff --git a/showcases/e2e/radio/radio-a11y.spec.ts b/showcases/e2e/radio/radio-a11y.spec.ts
index f6c5ad2e92a..70677f5b9a4 100644
--- a/showcases/e2e/radio/radio-a11y.spec.ts
+++ b/showcases/e2e/radio/radio-a11y.spec.ts
@@ -1,9 +1,11 @@
import { test } from '@playwright/test';
// @ts-expect-error - required for playwright
-import { getA11yTest } from '../default.ts';
+import { runA11yCheckerTest, runAxeCoreTest } from '../default.ts';
+import { lvl3 } from '../fixtures/variants';
test.describe('DBRadio', () => {
- getA11yTest({
- path: '03/radio'
- });
+ runAxeCoreTest({ path: '03/radio' });
+ runAxeCoreTest({ path: '03/radio', color: lvl3 });
+ runAxeCoreTest({ path: '03/radio', density: 'functional' });
+ runA11yCheckerTest({ path: '03/radio' });
});
diff --git a/showcases/e2e/section/section-a11y.spec.ts b/showcases/e2e/section/section-a11y.spec.ts
index 0819a384f69..46f021b1339 100644
--- a/showcases/e2e/section/section-a11y.spec.ts
+++ b/showcases/e2e/section/section-a11y.spec.ts
@@ -1,7 +1,11 @@
import { test } from '@playwright/test';
// @ts-expect-error - required for playwright
-import { getA11yTest } from '../default.ts';
+import { runA11yCheckerTest, runAxeCoreTest } from '../default.ts';
+import { lvl3 } from '../fixtures/variants';
test.describe('DBSection', () => {
- getA11yTest({ path: '01/section' });
+ runAxeCoreTest({ path: '01/section' });
+ runAxeCoreTest({ path: '01/section', color: lvl3 });
+ runAxeCoreTest({ path: '01/section', density: 'functional' });
+ runA11yCheckerTest({ path: '01/section' });
});
diff --git a/showcases/e2e/select/select-a11y.spec.ts b/showcases/e2e/select/select-a11y.spec.ts
index 7cfb142648a..a9d9389b93d 100644
--- a/showcases/e2e/select/select-a11y.spec.ts
+++ b/showcases/e2e/select/select-a11y.spec.ts
@@ -1,11 +1,17 @@
import { test } from '@playwright/test';
// @ts-expect-error - required for playwright
-import { getA11yTest } from '../default.ts';
+import { runA11yCheckerTest, runAxeCoreTest } from '../default.ts';
+import { lvl3 } from '../fixtures/variants';
+
+const axeDisableRules = ['color-contrast']; // TODO: Currently disable till we solved https://github.com/db-ui/mono/issues/2587
test.describe('DBSelect', () => {
- // TODO: Currently disable till we solved https://github.com/db-ui/mono/issues/2587
- getA11yTest({
+ runAxeCoreTest({ path: '03/select', axeDisableRules });
+ runAxeCoreTest({ path: '03/select', color: lvl3, axeDisableRules });
+ runAxeCoreTest({
path: '03/select',
- axeDisableRules: ['color-contrast']
+ density: 'functional',
+ axeDisableRules
});
+ runA11yCheckerTest({ path: '03/select' });
});
diff --git a/showcases/e2e/switch/switch-a11y.spec.ts b/showcases/e2e/switch/switch-a11y.spec.ts
index d179874a6fd..173f3cf7178 100644
--- a/showcases/e2e/switch/switch-a11y.spec.ts
+++ b/showcases/e2e/switch/switch-a11y.spec.ts
@@ -1,9 +1,13 @@
import { test } from '@playwright/test';
// @ts-expect-error - required for playwright
-import { getA11yTest } from '../default.ts';
+import { runA11yCheckerTest, runAxeCoreTest } from '../default.ts';
+import { lvl3 } from '../fixtures/variants';
test.describe('DBSwitch', () => {
- getA11yTest({
+ runAxeCoreTest({ path: '03/switch' });
+ runAxeCoreTest({ path: '03/switch', color: lvl3 });
+ runAxeCoreTest({ path: '03/switch', density: 'functional' });
+ runA11yCheckerTest({
path: '03/switch',
// It's an issue in the tool: https://github.com/IBMa/equal-access/issues/842
aCheckerDisableRules: ['aria_attribute_valid']
diff --git a/showcases/e2e/tab-item/tab-item-a11y.spec.ts b/showcases/e2e/tab-item/tab-item-a11y.spec.ts
index bb34d67a2e3..79fc3795140 100644
--- a/showcases/e2e/tab-item/tab-item-a11y.spec.ts
+++ b/showcases/e2e/tab-item/tab-item-a11y.spec.ts
@@ -1,20 +1,31 @@
import { test } from '@playwright/test';
// @ts-expect-error - required for playwright
-import { getA11yTest, isStencil } from '../default.ts';
+import { isStencil, runAxeCoreTest, runA11yCheckerTest } from '../default.ts';
+import { lvl3 } from '../fixtures/variants';
+
+// We need to change tabs anyway, we disable the rules for now
+// TODO: There might be an issue in our implementation of which elements get which roles
+// So we disabled "aria-allowed-role" for now
+const axeDisableRules = ['aria-allowed-role'];
+const aCheckerDisableRules = [
+ 'aria_child_tabbable',
+ 'input_checkboxes_grouped',
+ 'aria_role_valid'
+];
+// TODO: We skip this for now until mitosis output is correct
+const skipChecker = isStencil(process.env.showcase);
test.describe('DBTabItem', () => {
- // TODO: There might be an issue in our implementation of which elements get which roles
- // So we disabled "aria-allowed-role" for now
- getA11yTest({
+ runAxeCoreTest({ path: '04/tab-item', axeDisableRules });
+ runAxeCoreTest({ path: '04/tab-item', color: lvl3, axeDisableRules });
+ runAxeCoreTest({
+ path: '04/tab-item',
+ density: 'functional',
+ axeDisableRules
+ });
+ runA11yCheckerTest({
path: '04/tab-item',
- // We need to change tabs anyway, we disable the rules for now
- axeDisableRules: ['aria-allowed-role'],
- aCheckerDisableRules: [
- 'aria_child_tabbable',
- 'input_checkboxes_grouped',
- 'aria_role_valid'
- ],
- // TODO: We skip this for now until mitosis output is correct
- skipChecker: isStencil(process.env.showcase)
+ aCheckerDisableRules,
+ skipChecker
});
});
diff --git a/showcases/e2e/tabs/tabs-a11y.spec.ts b/showcases/e2e/tabs/tabs-a11y.spec.ts
index ca50947bc7f..0641fea2e81 100644
--- a/showcases/e2e/tabs/tabs-a11y.spec.ts
+++ b/showcases/e2e/tabs/tabs-a11y.spec.ts
@@ -1,16 +1,27 @@
import { test } from '@playwright/test';
// @ts-expect-error - required for playwright
-import { getA11yTest, isStencil } from '../default.ts';
+import { isStencil, runAxeCoreTest, runA11yCheckerTest } from '../default.ts';
+import { lvl3 } from '../fixtures/variants';
+
+// We need to change tabs anyway, we disable the rules for now
+// TODO: There might be an issue in our implementation of which elements get which roles
+// So we disabled "aria-allowed-role" for now
+const axeDisableRules = ['aria-allowed-role'];
+const aCheckerDisableRules = ['input_checkboxes_grouped', 'aria_role_valid'];
+// TODO: We skip this for now until mitosis output is correct
+const skipChecker = isStencil(process.env.showcase);
test.describe('DBTabs', () => {
- // TODO: There might be an issue in our implementation of which elements get which roles
- // So we disabled "aria-allowed-role" for now
- getA11yTest({
+ runAxeCoreTest({ path: '04/tabs', axeDisableRules });
+ runAxeCoreTest({ path: '04/tabs', color: lvl3, axeDisableRules });
+ runAxeCoreTest({
+ path: '04/tabs',
+ density: 'functional',
+ axeDisableRules
+ });
+ runA11yCheckerTest({
path: '04/tabs',
- // We need to change tabs anyway, we disable the rules for now
- axeDisableRules: ['aria-allowed-role'],
- aCheckerDisableRules: ['input_checkboxes_grouped', 'aria_role_valid'],
- // TODO: We skip this for now until mitosis output is correct
- skipChecker: isStencil(process.env.showcase)
+ aCheckerDisableRules,
+ skipChecker
});
});
diff --git a/showcases/e2e/tag/tag-a11y.spec.ts b/showcases/e2e/tag/tag-a11y.spec.ts
index 26f0db387d7..ba61c68883a 100644
--- a/showcases/e2e/tag/tag-a11y.spec.ts
+++ b/showcases/e2e/tag/tag-a11y.spec.ts
@@ -1,9 +1,11 @@
import { test } from '@playwright/test';
// @ts-expect-error - required for playwright
-import { getA11yTest } from '../default.ts';
+import { runA11yCheckerTest, runAxeCoreTest } from '../default.ts';
+import { lvl3 } from '../fixtures/variants';
test.describe('DBTag', () => {
- getA11yTest({
- path: '04/tag'
- });
+ runAxeCoreTest({ path: '04/tag' });
+ runAxeCoreTest({ path: '04/tag', color: lvl3 });
+ runAxeCoreTest({ path: '04/tag', density: 'functional' });
+ runA11yCheckerTest({ path: '04/tag' });
});
diff --git a/showcases/e2e/textarea/textarea-a11y.spec.ts b/showcases/e2e/textarea/textarea-a11y.spec.ts
index 5075da3956b..d094b047ffd 100644
--- a/showcases/e2e/textarea/textarea-a11y.spec.ts
+++ b/showcases/e2e/textarea/textarea-a11y.spec.ts
@@ -1,13 +1,19 @@
import { test } from '@playwright/test';
// @ts-expect-error - required for playwright
-import { getA11yTest } from '../default.ts';
+import { runA11yCheckerTest, runAxeCoreTest } from '../default.ts';
+import { lvl3 } from '../fixtures/variants';
+
+const axeDisableRules = ['color-contrast']; // TODO: Currently disable till we solved https://github.com/db-ui/mono/issues/2587
+// TODO: disabled element_scrollable_tabbable it's a false-positive: https://github.com/IBMa/equal-access/issues/1911
+const aCheckerDisableRules = ['element_scrollable_tabbable'];
test.describe('DBTextarea', () => {
- // TODO: Currently disable till we solved https://github.com/db-ui/mono/issues/2587
- getA11yTest({
+ runAxeCoreTest({ path: '03/textarea', axeDisableRules });
+ runAxeCoreTest({ path: '03/textarea', color: lvl3, axeDisableRules });
+ runAxeCoreTest({
path: '03/textarea',
- axeDisableRules: ['color-contrast'],
- // TODO: disabled element_scrollable_tabbable it's a false-positive: https://github.com/IBMa/equal-access/issues/1911
- aCheckerDisableRules: ['element_scrollable_tabbable']
+ density: 'functional',
+ axeDisableRules
});
+ runA11yCheckerTest({ path: '03/textarea', aCheckerDisableRules });
});
diff --git a/showcases/e2e/tooltip/tooltip-a11y.spec.ts b/showcases/e2e/tooltip/tooltip-a11y.spec.ts
index c60af447e01..44e9ca2172e 100644
--- a/showcases/e2e/tooltip/tooltip-a11y.spec.ts
+++ b/showcases/e2e/tooltip/tooltip-a11y.spec.ts
@@ -1,13 +1,16 @@
-import { test } from '@playwright/test';
+import { type Page, test } from '@playwright/test';
// @ts-expect-error - required for playwright
-import { getA11yTest } from '../default.ts';
+import { runA11yCheckerTest, runAxeCoreTest } from '../default.ts';
import { hoverPre } from '../fixtures/hover';
+import { lvl3 } from '../fixtures/variants';
const selector = '.db-tooltip';
+const preAxe = async (page: Page) => hoverPre(page, selector);
+
test.describe('DBTooltip', () => {
- getA11yTest({
- path: '04/tooltip',
- preAxe: async (page) => hoverPre(page, selector)
- });
+ runAxeCoreTest({ path: '04/tooltip', preAxe });
+ runAxeCoreTest({ path: '04/tooltip', color: lvl3, preAxe });
+ runAxeCoreTest({ path: '04/tooltip', density: 'functional', preAxe });
+ runA11yCheckerTest({ path: '04/tooltip' });
});
diff --git a/showcases/next-showcase/package.json b/showcases/next-showcase/package.json
index 3cb1e39956c..6baeff4ffb2 100644
--- a/showcases/next-showcase/package.json
+++ b/showcases/next-showcase/package.json
@@ -17,7 +17,7 @@
"react-dom": "18.3.1"
},
"devDependencies": {
- "@types/node": "^22.8.4",
+ "@types/node": "^22.9.0",
"@types/react": "^18.3.12",
"npm-run-all": "^4.1.5",
"open-cli": "^8.0.0",
diff --git a/showcases/nuxt-showcase/package.json b/showcases/nuxt-showcase/package.json
index f3faaa3227f..6ccee6bf3ff 100644
--- a/showcases/nuxt-showcase/package.json
+++ b/showcases/nuxt-showcase/package.json
@@ -11,8 +11,8 @@
"preview": "nuxt preview"
},
"dependencies": {
- "nuxt": "^3.13.2",
- "vue": "^3.5.12",
+ "nuxt": "^3.14.159",
+ "vue": "^3.5.13",
"vue-router": "^4.4.5"
}
}
diff --git a/showcases/patternhub/components/old-routing-fallback/index.tsx b/showcases/patternhub/components/old-routing-fallback/index.tsx
index 0de0dcdb77b..6adcbf540ae 100644
--- a/showcases/patternhub/components/old-routing-fallback/index.tsx
+++ b/showcases/patternhub/components/old-routing-fallback/index.tsx
@@ -32,7 +32,8 @@ const OldRoutingFallback = () => {
}
// This is for the old implementation to work with iframes
- const foundRoute = getAllNavigationItems().find((item) =>
+ const allNavigationItems = getAllNavigationItems();
+ const foundRoute = allNavigationItems.find((item) =>
item.path?.endsWith(component)
);
diff --git a/showcases/patternhub/components/version-switcher/version-switcher.tsx b/showcases/patternhub/components/version-switcher/version-switcher.tsx
index 3020f708399..ed7a4489fe7 100644
--- a/showcases/patternhub/components/version-switcher/version-switcher.tsx
+++ b/showcases/patternhub/components/version-switcher/version-switcher.tsx
@@ -1,6 +1,6 @@
import { useEffect, useState } from 'react';
import { useRouter } from 'next/router';
-import { sanitize } from 'dompurify';
+import DOMPurify from 'dompurify';
import { DBSelect } from '../../../../output/react/src';
import { type BranchGroup, type GithubResponse } from './data';
@@ -88,6 +88,10 @@ const VersionSwitcher = () => {
(branch) =>
branch !== 'gh-pages' && !branch.includes('dependabot')
);
+
+ // `latest` isn't a branch, but only existing within gh-pages
+ tags.unshift('latest');
+
setCurrentBranch(branches);
setCurrentBranch(tags);
setGroupByTagsBranches(tags, branches);
@@ -100,9 +104,11 @@ const VersionSwitcher = () => {
const handleChange = (branch: string) => {
const lastPath = router.asPath;
- const isTag = branch.split('.').length === 3 && branch.startsWith('v');
+ const isTag =
+ (branch.split('.').length === 3 && branch.startsWith('v')) ||
+ branch === 'latest';
window.location.replace(
- sanitize(
+ DOMPurify.sanitize(
`https://${owner}.github.io/${repo}${
isTag ? '/version' : '/review'
}/${branch}${lastPath}`
diff --git a/showcases/patternhub/data/routes.tsx b/showcases/patternhub/data/routes.tsx
index 26db9162db0..de9f193419d 100644
--- a/showcases/patternhub/data/routes.tsx
+++ b/showcases/patternhub/data/routes.tsx
@@ -226,7 +226,11 @@ export const ROUTES: NavigationItem[] = [
}
]
},
- { label: 'Testing Overview Table', path: '/foundations/test-table' }
+ {
+ label: 'Testing Overview Table',
+ path: '/foundations/test-table'
+ },
+ { label: 'IDE Support', path: '/foundations/ide' }
]
},
{
@@ -301,7 +305,13 @@ const fillNavigationRecursive = (
export const getAllNavigationItems = (isBreadcrumb?: boolean) => {
const tree: NavigationItem[] = [];
fillNavigationRecursive(ROUTES, tree, isBreadcrumb);
- return tree;
+ return tree.sort((a, b) => {
+ if ((a.path?.length ?? 0) > (b.path?.length ?? 0)) {
+ return -1;
+ }
+
+ return 1;
+ });
};
export const getNavigationList = (path: string) => {
diff --git a/showcases/patternhub/package.json b/showcases/patternhub/package.json
index a869f21068b..5aa27167c71 100644
--- a/showcases/patternhub/package.json
+++ b/showcases/patternhub/package.json
@@ -23,9 +23,9 @@
"test:e2e": "npx playwright test --config=../playwright.patternhub-config.ts"
},
"dependencies": {
- "dompurify": "3.1.7",
+ "dompurify": "3.2.0",
"highlight.js": "^11.10.0",
- "next": "15.0.2",
+ "next": "15.0.3",
"react": "18.3.1",
"react-archer": "^4.4.0",
"react-dom": "18.3.1",
@@ -35,14 +35,14 @@
"devDependencies": {
"@mdx-js/loader": "^3.1.0",
"@mdx-js/react": "^3.1.0",
- "@next/mdx": "^15.0.2",
+ "@next/mdx": "^15.0.3",
"@types/dompurify": "3.0.5",
- "@types/node": "22.8.4",
+ "@types/node": "22.9.0",
"@types/react": "18.3.12",
"@types/react-dom": "18.3.1",
"esbuild": "0.24.0",
"eslint": "8.57.0",
- "eslint-config-next": "15.0.2",
+ "eslint-config-next": "15.0.3",
"iframe-resizer": "^5.3.2",
"open-cli": "^8.0.0",
"sass": "1.77.4",
diff --git a/showcases/patternhub/pages/_app.tsx b/showcases/patternhub/pages/_app.tsx
index 63049a96fea..82c4253e77c 100644
--- a/showcases/patternhub/pages/_app.tsx
+++ b/showcases/patternhub/pages/_app.tsx
@@ -67,12 +67,15 @@ const App = ({ Component, pageProps }: AppProps) => (
/>
)
}}>
-
+ {process.env.NEXT_PUBLIC_BASE_PATH !== '/mono/sub/' && (
+
+ )}
DB UI Mono
diff --git a/showcases/patternhub/pages/foundations/ide/index.mdx b/showcases/patternhub/pages/foundations/ide/index.mdx
new file mode 100644
index 00000000000..06b64d2d50a
--- /dev/null
+++ b/showcases/patternhub/pages/foundations/ide/index.mdx
@@ -0,0 +1,7 @@
+import DefaultPage from "../../../components/default-page";
+
+import Readme from "../../../../../packages/foundations/docs/IDESupport.md";
+
+
+
+export default ({ children }) => {children};
diff --git a/showcases/patternhub/scripts/generate-docs-mdx.js b/showcases/patternhub/scripts/generate-docs-mdx.js
index c813eb5d9ec..acec50f53e0 100644
--- a/showcases/patternhub/scripts/generate-docs-mdx.js
+++ b/showcases/patternhub/scripts/generate-docs-mdx.js
@@ -16,84 +16,91 @@ const Fallback = () => ;
export default Fallback;`;
const generateDocsMdx = async () => {
- const docs = JSON.parse(
- FS.readFileSync('./../../output/docs.json', 'utf8').toString()
+ const webTypes = JSON.parse(
+ FS.readFileSync(
+ './../../output/stencil/dist/web-types.json',
+ 'utf8'
+ ).toString()
);
+ const elements = webTypes?.contributions?.html?.elements;
const components = JSON.parse(
FS.readFileSync('./data/components.json', 'utf8').toString()
);
- for (const key of Object.keys(docs)) {
- const componentName = getComponentName(key);
-
- const componentValue = docs[key].at(0);
- const componentGroup = getComponentGroup(components, componentName);
-
- if (componentValue && componentGroup) {
- const componentOldPath = `${componentsPath}/${componentName}`;
- const componentGroupPath = `${componentsPath}/${componentGroup.name}`;
- const componentPath = `${componentGroupPath}/${componentName}`;
-
- if (!FS.existsSync(componentGroupPath)) {
- FS.mkdirSync(componentGroupPath);
- }
-
- if (!FS.existsSync(componentPath)) {
- FS.mkdirSync(componentPath);
- }
-
- FS.writeFileSync(
- `${componentPath}/properties.mdx`,
- getPropertiesFile(componentValue)
- );
-
- const docsPath = `./../../packages/components/src/components/${componentName}/docs`;
- if (FS.existsSync(docsPath)) {
- FS.cpSync(docsPath, `./${componentPath}/docs`, {
- recursive: true
- });
- }
-
- FS.writeFileSync(
- `${componentPath}/how-to-use.mdx`,
- getHowToFile(componentName, componentValue.displayName)
- );
-
- FS.writeFileSync(
- `${componentPath}/migration.mdx`,
- getMigrationFile(componentName, componentValue.displayName)
+ if (elements) {
+ for (const element of elements) {
+ const componentName = getComponentName(element.name);
+ const componentGroup = getComponentGroup(components, componentName);
+ const displayName = componentGroup?.subNavigation?.find(
+ (component) => component.name === componentName
);
- if (!FS.existsSync('./components/code-docs')) {
- FS.mkdirSync('./components/code-docs');
- }
+ if (componentGroup) {
+ const componentOldPath = `${componentsPath}/${componentName}`;
+ const componentGroupPath = `${componentsPath}/${componentGroup.name}`;
+ const componentPath = `${componentGroupPath}/${componentName}`;
- await writeCodeFiles(
- `./components/code-docs/${componentName}`,
- componentName
- );
+ if (!FS.existsSync(componentGroupPath)) {
+ FS.mkdirSync(componentGroupPath);
+ }
- // Write old files for Marketingportal
+ if (!FS.existsSync(componentPath)) {
+ FS.mkdirSync(componentPath);
+ }
- if (!FS.existsSync(componentOldPath)) {
- FS.mkdirSync(componentOldPath);
- }
+ FS.writeFileSync(
+ `${componentPath}/properties.mdx`,
+ getPropertiesFile(element)
+ );
- if (!FS.existsSync(`${componentOldPath}/docs`)) {
- FS.mkdirSync(`${componentOldPath}/docs`);
- }
+ const docsPath = `./../../packages/components/src/components/${componentName}/docs`;
+ if (FS.existsSync(docsPath)) {
+ FS.cpSync(docsPath, `./${componentPath}/docs`, {
+ recursive: true
+ });
+ }
- for (const framework of ['Angular', 'HTML', 'React', 'Vue']) {
FS.writeFileSync(
- `${componentOldPath}/docs/${framework}.tsx`,
- getRedirectOldFiles('../../../../')
+ `${componentPath}/how-to-use.mdx`,
+ getHowToFile(componentName, displayName)
);
- }
- if (!FS.existsSync(`${componentOldPath}/properties.tsx`)) {
FS.writeFileSync(
- `${componentOldPath}/properties.tsx`,
- getRedirectOldFiles('../../../')
+ `${componentPath}/migration.mdx`,
+ getMigrationFile(componentName, displayName)
+ );
+
+ if (!FS.existsSync('./components/code-docs')) {
+ FS.mkdirSync('./components/code-docs');
+ }
+
+ await writeCodeFiles(
+ `./components/code-docs/${componentName}`,
+ componentName
);
+
+ // Write old files for Marketingportal
+
+ if (!FS.existsSync(componentOldPath)) {
+ FS.mkdirSync(componentOldPath);
+ }
+
+ if (!FS.existsSync(`${componentOldPath}/docs`)) {
+ FS.mkdirSync(`${componentOldPath}/docs`);
+ }
+
+ for (const framework of ['Angular', 'HTML', 'React', 'Vue']) {
+ FS.writeFileSync(
+ `${componentOldPath}/docs/${framework}.tsx`,
+ getRedirectOldFiles('../../../../')
+ );
+ }
+
+ if (!FS.existsSync(`${componentOldPath}/properties.tsx`)) {
+ FS.writeFileSync(
+ `${componentOldPath}/properties.tsx`,
+ getRedirectOldFiles('../../../')
+ );
+ }
}
}
}
diff --git a/showcases/patternhub/scripts/generate-example-jsx.js b/showcases/patternhub/scripts/generate-example-jsx.js
index e4b8b7159f8..0603bcec2b3 100644
--- a/showcases/patternhub/scripts/generate-example-jsx.js
+++ b/showcases/patternhub/scripts/generate-example-jsx.js
@@ -1,38 +1,43 @@
import FS from 'node:fs';
-import { getCodeByFramework, getComponentName } from './utils.js';
+import {
+ getCodeByFramework,
+ getComponentName,
+ transformToUpperComponentName
+} from './utils.js';
const sharedPath = '../shared';
const generateExampleJSX = () => {
- const docs = JSON.parse(
- FS.readFileSync('./../../output/docs.json', 'utf8').toString()
+ const webTypes = JSON.parse(
+ FS.readFileSync(
+ './../../output/stencil/dist/web-types.json',
+ 'utf8'
+ ).toString()
);
+ const elements = webTypes?.contributions?.html?.elements;
const imports = [];
const examples = [];
- for (const key of Object.keys(docs)) {
- const componentName = getComponentName(key);
- const componentValue = docs[key].at(0);
- if (componentValue) {
- imports.push(componentValue.displayName);
- const path = `${sharedPath}/${componentName}.json`;
- if (FS.existsSync(path)) {
- const variants = JSON.parse(FS.readFileSync(path, 'utf8'));
+ for (const { name } of elements) {
+ const componentName = getComponentName(name);
+ imports.push(`DB${transformToUpperComponentName(componentName)}`);
+ const path = `${sharedPath}/${componentName}.json`;
+ if (FS.existsSync(path)) {
+ const variants = JSON.parse(FS.readFileSync(path, 'utf8'));
- for (const variant of variants) {
- for (const example of variant.examples) {
- const code = getCodeByFramework(
- componentName,
- 'react',
- example,
- true,
- variant.children
- );
- examples.push(
- `"${componentName}${variant.name}${
- example.name
- }":renderToString(${code.slice(0, code.length)})`
- );
- }
+ for (const variant of variants) {
+ for (const example of variant.examples) {
+ const code = getCodeByFramework(
+ componentName,
+ 'react',
+ example,
+ true,
+ variant.children
+ );
+ examples.push(
+ `"${componentName}${variant.name}${
+ example.name
+ }":renderToString(${code.slice(0, code.length)})`
+ );
}
}
}
diff --git a/showcases/patternhub/scripts/generate-test-table.js b/showcases/patternhub/scripts/generate-test-table.js
index c5b263a6000..3b6e5ec9d33 100644
--- a/showcases/patternhub/scripts/generate-test-table.js
+++ b/showcases/patternhub/scripts/generate-test-table.js
@@ -2,9 +2,13 @@ import FS from 'node:fs';
import { getComponentName } from './utils.js';
const generateTestTable = () => {
- const docs = JSON.parse(
- FS.readFileSync('./../../output/docs.json', 'utf8').toString()
+ const webTypes = JSON.parse(
+ FS.readFileSync(
+ './../../output/stencil/dist/web-types.json',
+ 'utf8'
+ ).toString()
);
+ const elements = webTypes?.contributions?.html?.elements;
const accessibilityReview = JSON.parse(
FS.readFileSync(
'./../shared/_accessibility-review.json',
@@ -12,8 +16,8 @@ const generateTestTable = () => {
).toString()
);
const data = [];
- for (const key of Object.keys(docs)) {
- const componentName = getComponentName(key);
+ for (const { name } of elements) {
+ const componentName = getComponentName(name);
if (
componentName.endsWith('-list') ||
componentName.endsWith('-panel') ||
diff --git a/showcases/patternhub/scripts/get-properties-file.js b/showcases/patternhub/scripts/get-properties-file.js
index 1bfcee8f5b5..fff756bcb21 100644
--- a/showcases/patternhub/scripts/get-properties-file.js
+++ b/showcases/patternhub/scripts/get-properties-file.js
@@ -1,85 +1,92 @@
-import { getColorVariants, getUnionElements } from './utils.js';
+import { getComponentName, transformToUpperComponentName } from './utils.js';
-const getOptions = (tsType) => {
- switch (tsType.name) {
- case 'literal': {
- return tsType.value;
- }
-
- case 'Array': {
- return `const array:${tsType.raw} = [${tsType.elements
- .map((element) => getOptions(element))
- .join('\n')}]`;
- }
-
- case 'signature': {
- return `${tsType.raw
- .replaceAll('/**\n\t', '')
- .replaceAll('*/\n\t', '')
- .replaceAll('*', '//')
- .replaceAll('{', '{')
- .replaceAll('}', '}')
- .replaceAll('\r\n\t\t', ' ')
- .replaceAll('\t', ' ')
- .replaceAll(/\r\n|\r|\n/g, '
')
- .replaceAll('|', '|')}`;
- }
+const getAllNames = (name) => {
+ const part = transformToUpperComponentName(name);
+ if (!part) {
+ return '';
+ }
- case 'union': {
- const options = [];
- getUnionElements(options, tsType.elements);
- return options.join(' | ');
- }
+ const upperName = `${part[0].toLowerCase()}${part.slice(1)}`;
- case 'COLOR': {
- return getColorVariants().join(' | ');
- }
+ if (name === 'classname') {
+ return 'className';
+ }
- default: {
- return undefined;
- }
+ if (name !== upperName) {
+ return `${name} / ${upperName}`;
}
+
+ return name;
};
/**
*
- * @param componentValue {{description: string, methods: any[], displayName: string, props:any}}
+ * @param componentValue {{description: string, name: string, attributes:any[], slots:any[], events:any[]}}
* @returns {string}
*/
-const getPropertiesFile = ({ displayName, description, props }) => {
- const propertyKeys = Object.keys(props);
-
+const getPropertiesFile = ({ name, attributes, events, slots }) => {
let propertyTable = '';
+ let slotsTable = '';
+ let eventsTable = '';
+ const allSlots = [...slots];
+
+ for (const { name, description, value } of attributes.filter(
+ ({ value }) => !value?.type?.includes('function')
+ )) {
+ const isUnion = value.type.includes('|');
- for (const propertyKey of propertyKeys) {
- const property = props[propertyKey];
- const options = getOptions(property.tsType);
- propertyTable += `| ${propertyKey} `;
+ propertyTable += `| ${getAllNames(name)} `;
propertyTable += `| ${
- property.description.replaceAll(/\r\n|\r|\n/g, '
') ||
- 'No description'
+ description?.replaceAll(/\r\n|\r|\n/g, '
') || 'No description'
} `;
- propertyTable += `| ${property.tsType.type ?? property.tsType.name} `;
+ propertyTable += `| ${isUnion ? 'union' : value.type} `;
- if (['icon', 'iconAfter', 'messageIcon'].includes(propertyKey)) {
+ if (['icon', 'icon-after', 'message-icon'].includes(name)) {
propertyTable += `| [IconTypes](https://db-ui.github.io/mono/review/main/foundations/icons/overview) |\n`;
} else {
propertyTable += `| ${
- options
- ? `${options.replaceAll(
- '',
- ''
+ isUnion
+ ? `${value.type.replaceAll(
+ '|',
+ '|'
)}
`
: ''
} |\n`;
}
}
+ for (const { name, description } of allSlots) {
+ slotsTable += `| ${getAllNames(name)} | ${description?.replaceAll(/\r\n|\r|\n/g, '
')} |\n`;
+ }
+
+ for (const { name, type } of events) {
+ eventsTable += `| ${getAllNames(name)} | ${type} |\n`;
+ }
+
return `
import DefaultPage from "../../../../components/default-page";
-# ${displayName}
-${description}
+# DB${transformToUpperComponentName(getComponentName(name))}
+${
+ allSlots.length > 0
+ ? `## Slots
+
+| Name | Description |
+| ---- | ----------- |
+${slotsTable}
+`
+ : ''
+}
+${
+ events.length > 0
+ ? `## Events
+
+| Name | Type |
+| ---- | ----------- |
+${eventsTable}
+`
+ : ''
+}
## Properties
| Name | Description | Type | Options |
diff --git a/showcases/patternhub/scripts/utils.js b/showcases/patternhub/scripts/utils.js
index 799bfba07b4..e62bdd8e063 100644
--- a/showcases/patternhub/scripts/utils.js
+++ b/showcases/patternhub/scripts/utils.js
@@ -1,23 +1,5 @@
/* eslint-disable import/no-anonymous-default-export */
-/**
- * @param options {string[]}
- * @param elements {{name:string, value?:string, elements?:any[]}[]}
- */
-export const getUnionElements = (options, elements) => {
- if (elements) {
- for (const element of elements) {
- options.push(
- element.name === 'literal'
- ? element.value
- : element.elements
- ? getUnionElements(options, element.elements)
- : element.name
- );
- }
- }
-};
-
/**
* @param props {object}
* @param framework {'angular'|'react'|'vue'}
@@ -197,6 +179,18 @@ export const getCodeByFramework = (
return `<${tag}${className} ${attributes.join(' ')}${reactSlots}/>`;
}
+ // Workaround for tooltip
+ if (componentName === 'tooltip') {
+ return innerContent.replace(
+ '',
+ `<${tag}${className} ${attributes
+ .filter((attr) => attr !== 'content')
+ .join(' ')}>${
+ attributes.find((attr) => attr === 'content') ?? ''
+ }${tag}>`
+ );
+ }
+
return `<${tag}${className} ${attributes.join(' ')}${reactSlots}>
${otherSlots}${innerContent}
${tag}>`;
@@ -224,10 +218,16 @@ export const getColorVariants = () => [
'informational-transparent-semi'
];
-export const getComponentName = (filePath) => {
- let componentName = filePath.split('/').at(-1);
- componentName = componentName.replace('.tsx', '').replaceAll(/\s/g, '');
- return componentName;
+export const transformToUpperComponentName = (componentName) =>
+ componentName
+ ? componentName
+ .split('-')
+ .map((part) => `${part[0].toUpperCase()}${part.slice(1)}`)
+ .join('')
+ : '';
+
+export const getComponentName = (elementName) => {
+ return elementName.replace('db-', '');
};
export const getComponentGroup = (components, componentName) => {
@@ -241,9 +241,9 @@ export const getComponentGroup = (components, componentName) => {
};
export default {
- getUnionElements,
getCodeByFramework,
getColorVariants,
getComponentName,
- getComponentGroup
+ getComponentGroup,
+ transformToUpperComponentName
};
diff --git a/showcases/patternhub/tests/default.spec.ts b/showcases/patternhub/tests/default.spec.ts
index b94f80f0498..71ea90db958 100644
--- a/showcases/patternhub/tests/default.spec.ts
+++ b/showcases/patternhub/tests/default.spec.ts
@@ -9,8 +9,7 @@ const getDefaultScreenshotTest = async (
) => {
test(`${type} should match screenshot`, async ({ page }) => {
await page.goto(`${path}`, {
- waitUntil: 'domcontentloaded',
- timeout: 20_000
+ waitUntil: 'domcontentloaded'
});
await fn(page);
await expect(page).toHaveScreenshot([name, 'patternhub.png']);
@@ -25,7 +24,8 @@ for (const group of Components) {
`docs`,
`./components/${component.name}/docs/Angular`,
async (page) => {
- expect(await page.locator('h2').first().isVisible());
+ const firstH2 = page.locator('h2').first();
+ await expect(firstH2).toBeVisible();
}
);
});
@@ -33,13 +33,10 @@ for (const group of Components) {
await getDefaultScreenshotTest(
component.name,
`overview`,
- `./components/${component.name}/overview?page=density`,
+ `./components/${component.name}/overview?fullscreen=true`,
async (page) => {
- const functionalCount = await page
- .getByText('Functional')
- .first()
- .isVisible();
- expect(functionalCount);
+ const firstH2 = page.locator('h1').first();
+ await expect(firstH2).toBeVisible();
}
);
});
@@ -49,7 +46,8 @@ for (const group of Components) {
`properties`,
`./components/${component.name}/properties?fullscreen=true&noh1=true`,
async (page) => {
- expect(await page.locator('h2').first().isVisible());
+ const firstH2 = page.locator('h2').first();
+ await expect(firstH2).toBeVisible();
}
);
});
diff --git a/showcases/playwright.patternhub-config.ts b/showcases/playwright.patternhub-config.ts
index 734545f5d62..5775aaad8a4 100644
--- a/showcases/playwright.patternhub-config.ts
+++ b/showcases/playwright.patternhub-config.ts
@@ -16,15 +16,15 @@ const patternHubConfig: PlaywrightTestConfig = {
}
],
webServer: {
- command: `cd patternhub && npm run start`,
- port: 3000,
+ command: `npx http-server ../build-showcases${process.env.NEXT_PUBLIC_BASE_PATH ? '' : '/patternhub'}`,
+ port: 8080,
reuseExistingServer: !process.env.CI
},
use: {
/* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
actionTimeout: 0,
/* Base URL to use in actions like `await page.goto('/')`. */
- baseURL: `http://localhost:3000/mono/sub/`,
+ baseURL: `http://localhost:8080${process.env.NEXT_PUBLIC_BASE_PATH ?? ''}/`,
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: process.env.CI ? 'on-first-retry' : 'on'
diff --git a/showcases/react-showcase/package.json b/showcases/react-showcase/package.json
index 0e3472c6634..6680f7bc92b 100644
--- a/showcases/react-showcase/package.json
+++ b/showcases/react-showcase/package.json
@@ -18,7 +18,7 @@
"dependencies": {
"react": "^18.3.1",
"react-dom": "^18.3.1",
- "react-router-dom": "6.27.0",
+ "react-router-dom": "6.28.0",
"sa11y": "3.2.3"
},
"devDependencies": {
@@ -27,6 +27,6 @@
"@vitejs/plugin-react": "^4.3.3",
"cross-env": "^7.0.3",
"typescript": "^5.4.5",
- "vite": "^5.4.10"
+ "vite": "^5.4.11"
}
}
diff --git a/showcases/react-showcase/src/components/drawer/index.tsx b/showcases/react-showcase/src/components/drawer/index.tsx
index db407444e02..699354e102e 100644
--- a/showcases/react-showcase/src/components/drawer/index.tsx
+++ b/showcases/react-showcase/src/components/drawer/index.tsx
@@ -19,7 +19,8 @@ const getDrawer = ({
setOpenDrawer,
direction,
children,
- backdrop
+ backdrop,
+ variant
}: DBDrawerProps & AdditionalDrawerProperties) => (
{
setOpenDrawer(undefined);
diff --git a/showcases/shared/checkbox.json b/showcases/shared/checkbox.json
index 73a39509b8f..dbfdce4fb66 100644
--- a/showcases/shared/checkbox.json
+++ b/showcases/shared/checkbox.json
@@ -97,8 +97,7 @@
"props": {
"name": "States",
"indeterminate": true,
- "required": true,
- "checked": true
+ "required": true
}
}
]
@@ -159,6 +158,16 @@
"name": "Content"
}
},
+ {
+ "name": "Long label",
+ "style": {
+ "width": "100px"
+ },
+ "props": {
+ "checked": true,
+ "name": "Long label"
+ }
+ },
{
"name": "No Label",
"props": {
diff --git a/showcases/shared/drawer.json b/showcases/shared/drawer.json
index 03c7212945c..71c2a3d6184 100644
--- a/showcases/shared/drawer.json
+++ b/showcases/shared/drawer.json
@@ -175,5 +175,26 @@
}
}
]
+ },
+ {
+ "name": "Example",
+ "examples": [
+ {
+ "name": "(Default) As modal",
+ "props": {
+ "variant": "modal",
+ "open": "open",
+ "onClose": "toggleDrawer(false)"
+ }
+ },
+ {
+ "name": "Inside",
+ "props": {
+ "variant": "inside",
+ "open": "open",
+ "onClose": "toggleDrawer(false)"
+ }
+ }
+ ]
}
]
diff --git a/showcases/stencil-showcase/package.json b/showcases/stencil-showcase/package.json
index 65bfacf3635..f683bc2852b 100644
--- a/showcases/stencil-showcase/package.json
+++ b/showcases/stencil-showcase/package.json
@@ -25,7 +25,7 @@
"@angular/router": "17.3.12",
"@stencil/core": "4.22.2",
"rxjs": "~7.8.1",
- "tslib": "^2.7.0",
+ "tslib": "^2.8.1",
"zone.js": "~0.14.10"
},
"devDependencies": {
diff --git a/showcases/vue-showcase/package.json b/showcases/vue-showcase/package.json
index 9755284f742..3266e465a7c 100644
--- a/showcases/vue-showcase/package.json
+++ b/showcases/vue-showcase/package.json
@@ -13,14 +13,14 @@
},
"dependencies": {
"sa11y": "3.2.3",
- "vue": "^3.5.12",
+ "vue": "^3.5.13",
"vue-router": "4.4.5"
},
"devDependencies": {
- "@vitejs/plugin-vue": "^5.1.4",
+ "@vitejs/plugin-vue": "^5.2.0",
"cross-env": "^7.0.3",
"typescript": "^5.4.5",
- "vite": "^5.4.10",
- "vue-tsc": "^2.1.8"
+ "vite": "^5.4.11",
+ "vue-tsc": "^2.1.10"
}
}
diff --git a/showcases/vue-showcase/src/components/drawer/Drawer.vue b/showcases/vue-showcase/src/components/drawer/Drawer.vue
index f7669718189..338d3bbb616 100644
--- a/showcases/vue-showcase/src/components/drawer/Drawer.vue
+++ b/showcases/vue-showcase/src/components/drawer/Drawer.vue
@@ -25,6 +25,7 @@ const toggleDrawer = (example?: string) => {
:width="exampleProps?.width"
:spacing="exampleProps?.spacing"
:direction="exampleProps?.direction"
+ :variant="exampleProps?.variant"
:open="openDrawer && openDrawer === exampleName"
@close="toggleDrawer(undefined)"
>