diff --git a/__snapshots__/custom-select/showcase/chromium-highContrast/DBCustomSelect-should-match-screenshot-1/DBCustomSelect-should-match-screenshot.png b/__snapshots__/custom-select/showcase/chromium-highContrast/DBCustomSelect-should-match-screenshot-1/DBCustomSelect-should-match-screenshot.png index 115157db7b1c..f97cfdcf67ff 100644 Binary files a/__snapshots__/custom-select/showcase/chromium-highContrast/DBCustomSelect-should-match-screenshot-1/DBCustomSelect-should-match-screenshot.png and b/__snapshots__/custom-select/showcase/chromium-highContrast/DBCustomSelect-should-match-screenshot-1/DBCustomSelect-should-match-screenshot.png differ diff --git a/__snapshots__/custom-select/showcase/chromium/DBCustomSelect-should-match-screenshot-1/DBCustomSelect-should-match-screenshot.png b/__snapshots__/custom-select/showcase/chromium/DBCustomSelect-should-match-screenshot-1/DBCustomSelect-should-match-screenshot.png index fb2ce163e9ed..e2270ddcf0f4 100644 Binary files a/__snapshots__/custom-select/showcase/chromium/DBCustomSelect-should-match-screenshot-1/DBCustomSelect-should-match-screenshot.png and b/__snapshots__/custom-select/showcase/chromium/DBCustomSelect-should-match-screenshot-1/DBCustomSelect-should-match-screenshot.png differ diff --git a/__snapshots__/custom-select/showcase/firefox/DBCustomSelect-should-match-screenshot-1/DBCustomSelect-should-match-screenshot.png b/__snapshots__/custom-select/showcase/firefox/DBCustomSelect-should-match-screenshot-1/DBCustomSelect-should-match-screenshot.png index f1c746d2ceb1..2b15f80116af 100644 Binary files a/__snapshots__/custom-select/showcase/firefox/DBCustomSelect-should-match-screenshot-1/DBCustomSelect-should-match-screenshot.png and b/__snapshots__/custom-select/showcase/firefox/DBCustomSelect-should-match-screenshot-1/DBCustomSelect-should-match-screenshot.png differ diff --git a/__snapshots__/custom-select/showcase/mobile-chrome/DBCustomSelect-should-match-screenshot-1/DBCustomSelect-should-match-screenshot.png b/__snapshots__/custom-select/showcase/mobile-chrome/DBCustomSelect-should-match-screenshot-1/DBCustomSelect-should-match-screenshot.png index 4b6adcbe0745..1bca9d2c1be5 100644 Binary files a/__snapshots__/custom-select/showcase/mobile-chrome/DBCustomSelect-should-match-screenshot-1/DBCustomSelect-should-match-screenshot.png and b/__snapshots__/custom-select/showcase/mobile-chrome/DBCustomSelect-should-match-screenshot-1/DBCustomSelect-should-match-screenshot.png differ diff --git a/packages/components/src/components/custom-select-dropdown/custom-select-dropdown.scss b/packages/components/src/components/custom-select-dropdown/custom-select-dropdown.scss index 220e7ab0fdca..15ea53394dd4 100644 --- a/packages/components/src/components/custom-select-dropdown/custom-select-dropdown.scss +++ b/packages/components/src/components/custom-select-dropdown/custom-select-dropdown.scss @@ -4,15 +4,12 @@ @use "@db-ux/core-foundations/build/styles/helpers"; @use "@db-ux/core-foundations/build/styles/animation"; @use "../../styles/internal/form-components"; +@use "../../styles/internal/select-dropdown-components"; .db-custom-select-dropdown { @extend %db-neutral-variables; + @extend %select-dropdown-container; - position: absolute; - z-index: 32; - box-shadow: variables.$db-elevation-md; - min-inline-size: variables.$db-sizing-xl; - max-inline-size: calc(100vw - 2 * #{variables.$db-spacing-fixed-sm}); max-block-size: calc(100vh - 2 * #{variables.$db-spacing-fixed-sm}); &:not([data-width]), diff --git a/packages/components/src/components/custom-select-list-item/custom-select-list-item.scss b/packages/components/src/components/custom-select-list-item/custom-select-list-item.scss index 127e34d9ae00..24ae9f92e5af 100644 --- a/packages/components/src/components/custom-select-list-item/custom-select-list-item.scss +++ b/packages/components/src/components/custom-select-list-item/custom-select-list-item.scss @@ -5,6 +5,7 @@ @use "@db-ux/core-foundations/build/styles/icons"; @use "@db-ux/core-foundations/build/styles/screen-sizes"; @use "../../styles/internal/form-components"; +@use "../../styles/internal/select-dropdown-components"; // web-component workaround db-custom-select-list-item:not(:last-of-type) { @@ -15,23 +16,13 @@ db-custom-select-list-item:not(:last-of-type) { .db-custom-select-list-item { @include helpers.display(flex); + @extend %select-list-item; block-size: 100%; - position: relative; - padding: variables.$db-spacing-fixed-sm; - background-color: colors.$db-adaptive-bg-basic-transparent-full-default; - border-radius: variables.$db-border-radius-xs; - box-sizing: border-box; &:has(> label) { &:not(:has(input[type="radio"]:checked)) { - @include helpers.hover { - background-color: colors.$db-adaptive-bg-basic-transparent-full-hovered; - } - - @include helpers.active { - background-color: colors.$db-adaptive-bg-basic-transparent-full-pressed; - } + @extend %select-list-item-interaction; } } diff --git a/packages/components/src/components/custom-select-list/custom-select-list.scss b/packages/components/src/components/custom-select-list/custom-select-list.scss index 9143f9e7a71a..75a9f53afee7 100644 --- a/packages/components/src/components/custom-select-list/custom-select-list.scss +++ b/packages/components/src/components/custom-select-list/custom-select-list.scss @@ -1,30 +1,19 @@ @use "@db-ux/core-foundations/build/styles/variables"; @use "../../styles/internal/form-components"; @use "@db-ux/core-foundations/build/styles/helpers"; +@use "../../styles/internal/select-dropdown-components"; .db-custom-select-list { all: unset; + + @extend %select-list-container; + padding: variables.$db-spacing-fixed-sm; - overflow-y: auto; - overflow-block: auto; &::-webkit-scrollbar-button:single-button:vertical:decrement { border-start-end-radius: 0; } - /* (checkbox height + list-item padding) * 6 items + list padding */ - max-block-size: calc( - 5.5 * - ( - ( - #{form-components.$font-size-height} - 2 * - #{variables.$db-border-width-3xs} - ) + - 2 * #{variables.$db-spacing-fixed-sm} - ) + - (#{variables.$db-spacing-fixed-sm} * 2) - ); - > ul { all: unset; display: flex; diff --git a/packages/components/src/components/select/select.scss b/packages/components/src/components/select/select.scss index 946b1bbf78ba..23ad8dd4132f 100644 --- a/packages/components/src/components/select/select.scss +++ b/packages/components/src/components/select/select.scss @@ -7,6 +7,7 @@ @use "../../styles/internal/form-components"; @use "../../styles/internal/component"; @use "../../styles/internal/select-components"; +@use "../../styles/internal/select-dropdown-components"; .db-select-placeholder { @extend %select-absolute-placeholder; @@ -67,45 +68,13 @@ /* stylelint-disable-next-line selector-pseudo-element-no-unknown */ :is(::picker(select)) { - @extend %default-card; - - // Adapted from .db-custom-select-dropdown - position: absolute; - z-index: 32; - box-shadow: variables.$db-elevation-md; - min-inline-size: variables.$db-sizing-xl; - max-inline-size: calc( - 100vw - 2 * #{variables.$db-spacing-fixed-sm} - ); - - // Adapted from .db-card - background-color: colors.$db-adaptive-bg-basic-level-1-default; - padding: variables.$db-spacing-fixed-sm; - - // Adapted from .db-custom-select-list - overflow-block: auto; - - /* (option height + padding) * 5.5 items (showing partial item to indicate more content) + list padding */ - max-block-size: calc( - 5.5 * - ( - ( - #{form-components.$font-size-height} - 2 * - #{variables.$db-border-width-3xs} - ) + - 2 * #{variables.$db-spacing-fixed-sm} - ) + - (#{variables.$db-spacing-fixed-sm} * 2) - ); + @extend %select-dropdown-container; + @extend %select-list-container; } option { - // Adapted from .db-custom-select-list-item - position: relative; - padding: variables.$db-spacing-fixed-sm; - background-color: colors.$db-adaptive-bg-basic-transparent-full-default; - border-radius: variables.$db-border-radius-xs; - box-sizing: border-box; + @extend %select-list-item; + justify-content: space-between; // change order of the included text and pseudo-element within this flexbox item, to make sure the icon is always on the right @@ -115,15 +84,8 @@ font-weight: 700; } - // Hover states adapted from .db-custom-select-list-item &:not(:checked) { - @include helpers.hover { - background-color: colors.$db-adaptive-bg-basic-transparent-full-hovered; - } - - @include helpers.active { - background-color: colors.$db-adaptive-bg-basic-transparent-full-pressed; - } + @extend %select-list-item-interaction; } /* stylelint-disable-next-line selector-pseudo-element-no-unknown */ diff --git a/packages/components/src/styles/internal/_select-dropdown-components.scss b/packages/components/src/styles/internal/_select-dropdown-components.scss new file mode 100644 index 000000000000..dc8db956c5c0 --- /dev/null +++ b/packages/components/src/styles/internal/_select-dropdown-components.scss @@ -0,0 +1,58 @@ +@use "@db-ux/core-foundations/build/styles/variables"; +@use "@db-ux/core-foundations/build/styles/colors"; +@use "@db-ux/core-foundations/build/styles/helpers"; +@use "./form-components"; +@use "./component"; + +// Shared styles for dropdown container (used by both CustomSelect and native select ::picker) +%select-dropdown-container { + @extend %default-card; + + position: absolute; + z-index: 32; + box-shadow: variables.$db-elevation-md; + min-inline-size: variables.$db-sizing-xl; + max-inline-size: calc(100vw - 2 * #{variables.$db-spacing-fixed-sm}); + + // Adapted from .db-card + background-color: colors.$db-adaptive-bg-basic-level-1-default; + padding: variables.$db-spacing-fixed-sm; +} + +// Shared styles for list container (used by both CustomSelect list and native select ::picker) +%select-list-container { + overflow-block: auto; + + /* (option height + padding) * 5.5 items (showing partial item to indicate more content) + list padding */ + max-block-size: calc( + 5.5 * + ( + ( + #{form-components.$font-size-height} - 2 * + #{variables.$db-border-width-3xs} + ) + + 2 * #{variables.$db-spacing-fixed-sm} + ) + + (#{variables.$db-spacing-fixed-sm} * 2) + ); +} + +// Shared styles for list items (used by both CustomSelect list items and native select options) +%select-list-item { + position: relative; + padding: variables.$db-spacing-fixed-sm; + background-color: colors.$db-adaptive-bg-basic-transparent-full-default; + border-radius: variables.$db-border-radius-xs; + box-sizing: border-box; +} + +// Shared hover/active states for list items +%select-list-item-interaction { + @include helpers.hover { + background-color: colors.$db-adaptive-bg-basic-transparent-full-hovered; + } + + @include helpers.active { + background-color: colors.$db-adaptive-bg-basic-transparent-full-pressed; + } +} diff --git a/showcases/patternhub/tests/default.spec.ts b/showcases/patternhub/tests/default.spec.ts index de527ecf7ff1..9685ae15ac10 100644 --- a/showcases/patternhub/tests/default.spec.ts +++ b/showcases/patternhub/tests/default.spec.ts @@ -1,16 +1,19 @@ import { expect, type Page, test } from '@playwright/test'; import Components from '../data/components.json' with { type: 'json' }; -const getDefaultScreenshotTest = async ( +const getDefaultScreenshotTest = ( name: string, type: string, path: string, fn: (page: Page) => Promise ) => { test(`${type} should match screenshot`, async ({ page }) => { + // Navigate and wait for network idle to let assets load await page.goto(`${path}`, { waitUntil: 'domcontentloaded' }); + await page.waitForLoadState('networkidle'); + await fn(page); await expect(page).toHaveScreenshot([name, 'patternhub.png']); }); @@ -18,36 +21,40 @@ const getDefaultScreenshotTest = async ( for (const group of Components) { for (const component of group.subNavigation) { - test.describe(component.name, async () => { - await getDefaultScreenshotTest( + // Register tests synchronously (do not use async/await here) + test.describe(component.name, () => { + getDefaultScreenshotTest( component.name, `docs`, `.${group.path}/${component.name}/docs/Angular`, async (page) => { - const firstHeading = page.locator('h1, h2').first(); - await expect(firstHeading).toBeVisible(); + const firstH2 = page.locator('h2').first(); + // Allow more time for CI to render + await expect(firstH2).toBeVisible({ timeout: 60_000 }); } ); }); - test.describe(component.name, async () => { - await getDefaultScreenshotTest( + + test.describe(component.name, () => { + getDefaultScreenshotTest( component.name, `overview`, `.${group.path}/${component.name}/overview?fullscreen=true`, async (page) => { - const firstH2 = page.locator('h1').first(); - await expect(firstH2).toBeVisible(); + const firstH1 = page.locator('h1').first(); + await expect(firstH1).toBeVisible({ timeout: 60_000 }); } ); }); - test.describe(component.name, async () => { - await getDefaultScreenshotTest( + + test.describe(component.name, () => { + getDefaultScreenshotTest( component.name, `properties`, `.${group.path}/${component.name}/properties?fullscreen=true&noh1=true`, async (page) => { const firstH2 = page.locator('h2').first(); - await expect(firstH2).toBeVisible(); + await expect(firstH2).toBeVisible({ timeout: 60_000 }); } ); });