Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,12 @@

&.kbq-dropdown-item_highlighted,
&:hover {
background: var(--kbq-states-background-transparent-active);
background: var(--kbq-list-states-hover-container-background);
}

&:active,
&.kbq-active {
background: var(--kbq-list-states-active-container-background);
}

&.cdk-keyboard-focused {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,12 @@

&.kbq-dropdown-item_highlighted,
&:hover {
background: var(--kbq-states-background-transparent-active);
background: var(--kbq-list-states-hover-container-background);
}

&:active,
&.kbq-active {
background: var(--kbq-list-states-active-container-background);
}

&.cdk-keyboard-focused {
Expand Down
17 changes: 17 additions & 0 deletions packages/components/app-switcher/e2e.playwright-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,23 @@ test.describe('KbqAppSwitcherModule', () => {
await e2eEnableDarkTheme(page);
await expect(getScreenshotTarget(locator)).toHaveScreenshot('01-dark.png');
});

test('pressed', async ({ page }) => {
await page.goto('/E2eAppSwitcherStates');
const locator = getComponent(page);
const items = page.locator('.kbq-app-switcher-list-item');

await items.first().waitFor();
// App rows are generated from data, so the pressed class is applied from the spec rather than the
// fixture template (select/dropdown/tree fake `.kbq-active`/`.kbq-pressed` inline instead).
// `.kbq-app-switcher-list-item` has no `.kbq-active` host binding, so the injected class survives.
await items.nth(0).evaluate((el) => el.classList.add('kbq-active')); // selected + pressed
await items.nth(1).evaluate((el) => el.classList.add('kbq-active')); // pressed

await expect(getScreenshotTarget(locator)).toHaveScreenshot('01-pressed-light.png');
await e2eEnableDarkTheme(page);
await expect(getScreenshotTarget(locator)).toHaveScreenshot('01-pressed-dark.png');
});
});

test.describe('E2eAppSwitcherWithSitesStates', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,29 +130,29 @@

&:hover,
&.kbq-hover {
background: var(--kbq-states-background-transparent-hover);
background: var(--kbq-list-states-hover-container-background);

& .kbq-app-switcher-list-item__toggle {
background: var(--kbq-states-background-transparent-hover);
background: var(--kbq-list-states-hover-container-background);
}
}

&:active,
&.kbq-active {
background: var(--kbq-states-background-transparent-active);
background: var(--kbq-list-states-active-container-background);
}

&.kbq-selected {
background: var(--kbq-background-theme-less);
background: var(--kbq-list-states-selected-container-background);

&:hover,
&.kbq-hover {
background: var(--kbq-states-background-theme-less-hover);
background: var(--kbq-list-states-selected-hover-container-background);
}

&:active,
&.kbq-active {
background: var(--kbq-states-background-theme-less-active);
background: var(--kbq-list-states-selected-active-container-background);
}
}

Expand Down
16 changes: 16 additions & 0 deletions packages/components/core/option/_option-theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,23 @@
@include kbq-option(states-hover);
}

&:active:not(.kbq-disabled),
&.kbq-pressed:not(.kbq-disabled) {
// the active state defines only a background token; the mixin would emit undefined text/icon/caption color vars
background: var(--kbq-list-states-active-container-background);
}

&.kbq-selected:not(.kbq-disabled) {
@include kbq-option(states-selected);

&.kbq-active {
@include kbq-option(states-selected-hover);
}

&:active,
&.kbq-pressed {
background: var(--kbq-list-states-selected-active-container-background);
}
}

&.kbq-disabled {
Expand All @@ -54,6 +65,11 @@
&.kbq-active {
@include kbq-option(multiple-states-selected-hover);
}

&:active,
&.kbq-pressed {
background: var(--kbq-list-multiple-states-selected-active-container-background);
}
}
}
}
Expand Down
Binary file modified packages/components/dropdown/__screenshots__/01-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified packages/components/dropdown/__screenshots__/01-light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions packages/components/dropdown/_dropdown-theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,23 @@
@include _kbq-dropdown-item-state(states-hover);
}

&:active:not(.kbq-disabled),
&.kbq-active:not(.kbq-disabled) {
// the active state defines only a background token; the mixin would emit undefined text/icon color vars
background: var(--kbq-list-states-active-container-background);
}

&.kbq-selected {
@include _kbq-dropdown-item-state(states-selected);

&.cdk-focused:not(.kbq-disabled) {
@include _kbq-dropdown-item-state(states-selected-hover);
}

&:active:not(.kbq-disabled),
&.kbq-active:not(.kbq-disabled) {
background: var(--kbq-list-states-selected-active-container-background);
}
}

&.kbq-disabled {
Expand Down
4 changes: 4 additions & 0 deletions packages/components/dropdown/e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ import { KbqDropdownModule } from './dropdown.module';
<kbq-dropdown #dropdown="kbqDropdown">
<button kbq-dropdown-item>Item</button>

<button kbq-dropdown-item class="kbq-active">Pressed item</button>

<button kbq-dropdown-item class="kbq-active kbq-selected">Selected pressed item</button>

<button kbq-dropdown-item>
<i kbq-icon="kbq-bug_16" [color]="'contrast'"></i>
Item with icon
Expand Down
Binary file modified packages/components/list/__screenshots__/01-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 10 additions & 3 deletions packages/components/list/_list-theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@

&.kbq-active:not(.kbq-disabled),
&:active:not(.kbq-disabled) {
@include _kbq-list-item(states-active);
// the active state defines only a background token; the mixin would emit undefined text/icon/caption color vars
--kbq-option-background: var(--kbq-list-states-active-container-background);

background: var(--kbq-list-states-active-container-background);
}

&.kbq-selected:not(.kbq-disabled) {
Expand All @@ -47,7 +50,9 @@

&.kbq-active,
&:active {
@include _kbq-list-item(states-selected-active);
--kbq-option-background: var(--kbq-list-states-selected-active-container-background);

background: var(--kbq-list-states-selected-active-container-background);
}
}

Expand All @@ -67,7 +72,9 @@

&.kbq-active,
&:active {
@include _kbq-list-item(multiple-states-selected-active);
--kbq-option-background: var(--kbq-list-multiple-states-selected-active-container-background);

background: var(--kbq-list-multiple-states-selected-active-container-background);
}
}
}
Expand Down
Binary file modified packages/components/select/__screenshots__/01-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified packages/components/select/__screenshots__/01-light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified packages/components/select/__screenshots__/02-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified packages/components/select/__screenshots__/02-light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified packages/components/select/__screenshots__/03-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified packages/components/select/__screenshots__/03-light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 5 additions & 2 deletions packages/components/select/e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { KbqSelectModule } from './select.module';
<kbq-option [value]="'default'">default</kbq-option>
<kbq-option [value]="'selected'">selected</kbq-option>
<kbq-option class="kbq-active" [value]="'focused'">focused</kbq-option>
<kbq-option class="kbq-pressed" [value]="'pressed'">pressed</kbq-option>
<kbq-option [disabled]="true" [value]="'disabled'">disabled</kbq-option>
</kbq-optgroup>
</kbq-select>
Expand Down Expand Up @@ -63,6 +64,7 @@ export class E2eSelectStates {}
<kbq-option [value]="'default1'">default1 long name long name long name</kbq-option>
<kbq-option [value]="'selected'">selected</kbq-option>
<kbq-option class="kbq-active" [value]="'focused'">focused</kbq-option>
<kbq-option class="kbq-pressed" [value]="'pressed'">pressed</kbq-option>
<kbq-option [disabled]="true" [value]="'disabled'">disabled</kbq-option>
</kbq-optgroup>
</kbq-select>
Expand All @@ -74,7 +76,7 @@ export class E2eSelectStates {}
flex-direction: row;

width: 350px;
height: 350px;
height: 420px;
gap: 16px;
padding: 8px;
}
Expand Down Expand Up @@ -105,6 +107,7 @@ export class E2eMultiSelectStates {}
<kbq-option [value]="'default1'">default1 long name long name long name</kbq-option>
<kbq-option [value]="'selected'">selected</kbq-option>
<kbq-option class="kbq-active" [value]="'focused'">focused</kbq-option>
<kbq-option class="kbq-pressed" [value]="'pressed'">pressed</kbq-option>
<kbq-option [disabled]="true" [value]="'disabled'">disabled</kbq-option>
</kbq-optgroup>
</kbq-select>
Expand All @@ -116,7 +119,7 @@ export class E2eMultiSelectStates {}
flex-direction: row;

width: 350px;
height: 360px;
height: 410px;
gap: 16px;
padding: 8px;
}
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 22 additions & 0 deletions packages/components/tree-select/_tree-select-theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@
@include tree-theme.kbq-tree-option(states-hover);
}

// `:not(.kbq-disabled)` raises specificity so pressed wins over the heavier `:hover:not(.kbq-focused)` rule
&:active:not(.kbq-disabled),
&.kbq-active:not(.kbq-disabled) {
--kbq-option-background: var(--kbq-tree-states-active-container-background);

background: var(--kbq-tree-states-active-container-background);
}

&.kbq-selected {
&:hover:not(.kbq-focused),
&.kbq-hovered:not(.kbq-focused) {
Expand All @@ -54,6 +62,13 @@
&.kbq-focused {
@include tree-theme.kbq-tree-option(states-selected-hover);
}

&:active:not(.kbq-disabled),
&.kbq-active:not(.kbq-disabled) {
--kbq-option-background: var(--kbq-tree-states-selected-active-container-background);

background: var(--kbq-tree-states-selected-active-container-background);
}
}

&.kbq-checked:not(.kbq-selected),
Expand All @@ -66,6 +81,13 @@
&.kbq-focused {
background: var(--kbq-tree-multiple-states-selected-hover-container-background);
}

&:active:not(.kbq-disabled),
&.kbq-active:not(.kbq-disabled) {
--kbq-option-background: var(--kbq-tree-multiple-states-selected-active-container-background);

background: var(--kbq-tree-multiple-states-selected-active-container-background);
}
}

&.kbq-focused:not(.kbq-action-button-focused) {
Expand Down
41 changes: 41 additions & 0 deletions packages/components/tree-select/e2e.playwright-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,26 @@ test.describe('KbqTreeSelectModule', () => {
await e2eEnableDarkTheme(page);
await expect(getComponent(page)).toHaveScreenshot('01-dark.png');
});

test('pressed', async ({ page }) => {
await page.goto('/E2eTreeSelectStates');
const screenshotTarget = getComponent(page);
const select = getTreeSelect(screenshotTarget);

await select.click();

// Options are data-driven, so the pressed class is applied from the spec. Tree options only bind
// `.kbq-focused`/`.kbq-selected` (never `.kbq-active`), so the injected class is not stripped.
const options = page.locator('.cdk-overlay-pane kbq-tree-option');

await options.first().waitFor();
await options.nth(0).evaluate((el) => el.classList.add('kbq-active')); // selected + pressed
await options.nth(1).evaluate((el) => el.classList.add('kbq-active')); // pressed

await expect(getComponent(page)).toHaveScreenshot('01-pressed-light.png');
await e2eEnableDarkTheme(page);
await expect(getComponent(page)).toHaveScreenshot('01-pressed-dark.png');
});
});

test.describe('E2eMultiTreeSelectStates', () => {
Expand All @@ -109,6 +129,27 @@ test.describe('KbqTreeSelectModule', () => {
await e2eEnableDarkTheme(page);
await expect(getComponent(page)).toHaveScreenshot('02-dark.png');
});

test('pressed', async ({ page }) => {
await page.goto('/E2eMultiTreeSelectStates');
const screenshotTarget = getComponent(page);
const select = getTreeSelect(screenshotTarget);

await select.focus();
await page.keyboard.press('Enter');

// Options are data-driven, so the pressed class is applied from the spec. Tree options only bind
// `.kbq-focused`/`.kbq-selected` (never `.kbq-active`), so the injected class is not stripped.
const options = page.locator('.cdk-overlay-pane kbq-tree-option');

await options.first().waitFor();
await options.nth(0).evaluate((el) => el.classList.add('kbq-active')); // multiple selected + pressed
await options.nth(1).evaluate((el) => el.classList.add('kbq-active')); // pressed

await expect(getComponent(page)).toHaveScreenshot('02-pressed-light.png');
await e2eEnableDarkTheme(page);
await expect(getComponent(page)).toHaveScreenshot('02-pressed-dark.png');
});
});

test.describe('E2eMultilineTreeSelectStates', () => {
Expand Down
Binary file modified packages/components/tree/__screenshots__/01-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified packages/components/tree/__screenshots__/01-light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 21 additions & 0 deletions packages/components/tree/_tree-theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,27 @@
@include kbq-tree-option(states-hover);
}

&:active,
&.kbq-active {
--kbq-option-background: var(--kbq-tree-states-active-container-background);

background: var(--kbq-tree-states-active-container-background);
}

&.kbq-selected {
@include kbq-tree-option(states-selected);

&:hover,
&.kbq-hovered {
@include kbq-tree-option(states-selected-hover);
}

&:active,
&.kbq-active {
--kbq-option-background: var(--kbq-tree-states-selected-active-container-background);

background: var(--kbq-tree-states-selected-active-container-background);
}
}

&.kbq-checked:not(.kbq-selected),
Expand All @@ -58,6 +72,13 @@

background: var(--kbq-tree-multiple-states-selected-hover-container-background);
}

&:active,
&.kbq-active {
--kbq-option-background: var(--kbq-tree-multiple-states-selected-active-container-background);

background: var(--kbq-tree-multiple-states-selected-active-container-background);
}
}
}

Expand Down
Loading