Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace dropdown with kolPopoverWc in Split-Button #6726

Merged
merged 17 commits into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from 6 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
26 changes: 26 additions & 0 deletions packages/components/src/components/popover/popover.e2e.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { expect } from '@playwright/test';
import { test } from '@stencil/playwright';

test.describe('kol-popover-wc', () => {
test('should display popover when _show is true and hide when _show is false', async ({ page }) => {
await page.setContent(` <button id="trigger">Trigger Button</button> <kol-popover-wc _align="top" >Dropdown-Inhalt</kol-popover-wc> `);
const popover = page.locator('kol-popover-wc');
await expect(popover.locator('.popover')).not.toBeVisible();
await popover.evaluate(() => {
const popover = document.querySelector('kol-popover-wc');

if (popover) {
popover._show = true;
}
});

await expect(popover.locator('.popover')).toBeVisible();
const alignAttr = await popover.evaluate((el) => el.getAttribute('_align'));
expect(alignAttr).toBe('top');
await page.evaluate(() => {
const popover = document.querySelector('kol-popover-wc');
if (popover) popover._show = false;
});
await expect(popover.locator('.popover')).not.toBeVisible();
});
});
10 changes: 5 additions & 5 deletions packages/components/src/components/popover/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,28 @@
font-size: rem(16);
}

.kol-popover {
.kol-popover-wc {
Makko74 marked this conversation as resolved.
Show resolved Hide resolved
height: 0;
position: absolute;
}

.kol-popover .popover {
.kol-popover-wc .popover {
background-color: #fff;
min-height: max-content;
min-width: max-content;
opacity: 0;
position: absolute;
}

.kol-popover .show {
.kol-popover-wc .show {
animation: 0.3s ease-in forwards fadeInOpacity;
}

.kol-popover .disappear {
.kol-popover-wc .disappear {
animation: 0.3s ease-in backwards fadeInOpacity;
}

.kol-popover .arrow {
.kol-popover-wc .arrow {
background-color: inherit;
height: var(--font-size);
position: absolute;
Expand Down
108 changes: 41 additions & 67 deletions packages/components/src/components/split-button/shadow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import type { JSX } from '@stencil/core';
import { Component, h, Host, Prop, State } from '@stencil/core';

import { translate } from '../../i18n';
import { KolButtonWcTag } from '../../core/component-names';
import { KolButtonWcTag, KolPopoverWcTag } from '../../core/component-names';

/**
* @slot - Ermöglicht das Einfügen beliebigen HTMLs in das dropdown.
Expand All @@ -31,9 +31,6 @@ import { KolButtonWcTag } from '../../core/component-names';
shadow: true,
})
export class KolSplitButton implements SplitButtonProps /*, SplitButtonAPI*/ {
private dropdown: HTMLDivElement | undefined;
private dropdownContent: HTMLDivElement | undefined;

private readonly clickButtonHandler = {
onClick: (e: MouseEvent) => {
if (typeof this._on?.onClick === 'function') {
Expand All @@ -46,76 +43,53 @@ export class KolSplitButton implements SplitButtonProps /*, SplitButtonAPI*/ {
};
private readonly clickToggleHandler = { onClick: () => this.toggleDropdown() };

private readonly openDropdown = () => {
if (this.dropdown && this.dropdownContent) {
this.dropdown.style.height = `${this.dropdownContent.clientHeight}px`;
this.state = { ...this.state, _show: true };
}
};
private readonly closeDropdown = () => {
if (this.dropdown && this.dropdownContent) {
this.dropdown.style.height = ``;
this.state = { ...this.state, _show: false };
}
};
private readonly toggleDropdown = (value?: boolean) => {
const openIt = typeof value === 'boolean' ? value : !this.state._show;
if (openIt) this.openDropdown();
else this.closeDropdown();
};

private readonly catchDropdownElements = (e?: HTMLDivElement | null) => {
if (e) {
this.dropdown = e;
setTimeout(() => {
this.dropdownContent = e.firstChild as HTMLDivElement;
});
}
private readonly toggleDropdown = () => {
this.state = { ...this.state, _show: !this.state._show };
};

public render(): JSX.Element {
const i18nDropdownLabel = 'kol-split-button-dropdown-label';
return (
<Host class="kol-split-button">
<KolButtonWcTag
class={{
'main-button': true,
button: true,
[this._variant as string]: this._variant !== 'custom',
[this._customClass as string]: this._variant === 'custom' && typeof this._customClass === 'string' && this._customClass.length > 0,
}}
_ariaControls={this._ariaControls}
_ariaExpanded={this._ariaExpanded}
_ariaSelected={this._ariaSelected}
_customClass={this._customClass}
_disabled={this._disabled}
_icons={this._icons}
_hideLabel={this._hideLabel}
_label={this._label}
_name={this._name}
_on={this.clickButtonHandler}
_role={this._role}
_syncValueBySelector={this._syncValueBySelector}
_tabIndex={this._tabIndex}
_tooltipAlign={this._tooltipAlign}
_type={this._type}
_value={this._value}
_variant={this._variant}
></KolButtonWcTag>
<div class="horizontal-line"></div>
<KolButtonWcTag
class="secondary-button"
_disabled={this._disabled}
_hideLabel
_icons="codicon codicon-triangle-down"
_label={this.state._show ? translate(`${i18nDropdownLabel}-close`) : translate(`${i18nDropdownLabel}-open`)}
_on={this.clickToggleHandler}
></KolButtonWcTag>
<div class="popover" ref={this.catchDropdownElements}>
<div class="popover-content">
<slot />
</div>
<div class="split-button-root">
<KolButtonWcTag
class={{
'main-button': true,
button: true,
[this._variant as string]: this._variant !== 'custom',
[this._customClass as string]: this._variant === 'custom' && typeof this._customClass === 'string' && this._customClass.length > 0,
}}
_ariaControls={this._ariaControls}
_ariaExpanded={this._ariaExpanded}
_ariaSelected={this._ariaSelected}
_customClass={this._customClass}
_disabled={this._disabled}
_icons={this._icons}
_hideLabel={this._hideLabel}
_label={this._label}
_name={this._name}
_on={this.clickButtonHandler}
_role={this._role}
_syncValueBySelector={this._syncValueBySelector}
_tabIndex={this._tabIndex}
_tooltipAlign={this._tooltipAlign}
_type={this._type}
_value={this._value}
_variant={this._variant}
></KolButtonWcTag>
<div class="horizontal-line"></div>
<KolButtonWcTag
class="secondary-button"
_disabled={this._disabled}
_hideLabel
_icons="codicon codicon-triangle-down"
_label={this.state._show ? translate(`${i18nDropdownLabel}-close`) : translate(`${i18nDropdownLabel}-open`)}
_on={this.clickToggleHandler}
></KolButtonWcTag>
</div>
<KolPopoverWcTag _show={this.state._show} _align="bottom">
<slot />
</KolPopoverWcTag>
</Host>
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { expect } from '@playwright/test';
import { test } from '@stencil/playwright';

test.describe('kol-split-button', () => {
test('should display popover when the split button is clicked', async ({ page }) => {
await page.setContent(` <kol-split-button _label="Sample Button">Dropdown-Inhalt</kol-split-button> `);
const splitButton = page.locator('kol-split-button ');

const mainButton = splitButton.locator('.main-button');
const secondaryButton = splitButton.locator('.secondary-button');
const popover = splitButton.locator('kol-popover-wc');

await expect(popover.locator('.popover')).not.toBeVisible();
await secondaryButton.click({ force: true });
await expect(popover.locator('.popover')).toBeVisible();
await secondaryButton.click({ force: true });
await expect(popover.locator('.popover')).not.toBeVisible();

await expect(popover.locator('.popover')).not.toBeVisible();
await mainButton.click({ force: true });
await expect(popover.locator('.popover')).toBeVisible();
await mainButton.click({ force: true });
await expect(popover.locator('.popover')).not.toBeVisible();
});
});
22 changes: 9 additions & 13 deletions packages/components/src/components/split-button/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,21 @@
position: relative;
}

:host .split-button-root {
display: flex;
position: relative;
}

.main-button {
flex-grow: 1;
text-align: left;
}

/* popover */
.popover {
height: 0;
left: 0;
min-width: 100%;
overflow: hidden;
position: absolute;
top: 100%;
transition: height 0.3s ease-in-out;
.kol-popover-wc .popover {
margin-top: rem(2);
}

.popover-content {
inset: 0 0 auto 0;
min-width: 100%;
position: absolute;
.kol-popover-wc .arrow {
display: none;
}
}
48 changes: 24 additions & 24 deletions packages/components/src/components/split-button/test/html.mock.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { SplitButtonProps, SplitButtonStates } from '../../../schema';
import { mixMembers } from 'stencil-awesome-test';
import { KolButtonWcTag } from '../../../core/component-names';
import { KolButtonWcTag, KolPopoverWcTag } from '../../../core/component-names';
import { translate } from '../../../i18n';

export const getSplitButtonHtml = (props: SplitButtonProps): string => {
Expand All @@ -16,32 +16,32 @@ export const getSplitButtonHtml = (props: SplitButtonProps): string => {
return `
<kol-split-button class="kol-split-button">
<mock:shadow-root>
<${KolButtonWcTag}
${props._disabled ? `_disabled=""` : ''}
${typeof props._name === 'string' ? `_name="${props._name}"` : ''}
${props._hideLabel ? `_hidelabel=""` : ''}
${typeof props._icons === 'string' ? `_icons="${props._icons}"` : ''}
${typeof props._label === 'string' ? `_label="${props._label}"` : ''}
_tooltipalign="top"
_type="button"
_variant= ${variant}
class="button main-button ${variant}"
>
</${KolButtonWcTag}>
<div class="horizontal-line"></div>
<${KolButtonWcTag}
<div class="split-button-root">
<${KolButtonWcTag}
${props._disabled ? `_disabled=""` : ''}
_hidelabel=""
_icons="codicon codicon-triangle-down"
_label="${state._show ? translate(`${i18nDropdownLabel}-close`) : translate(`${i18nDropdownLabel}-open`)}"
class="secondary-button"
${typeof props._name === 'string' ? `_name="${props._name}"` : ''}
${props._hideLabel ? `_hidelabel=""` : ''}
${typeof props._icons === 'string' ? `_icons="${props._icons}"` : ''}
${typeof props._label === 'string' ? `_label="${props._label}"` : ''}
_tooltipalign="top"
_type="button"
_variant= ${variant}
class="button main-button ${variant}"
>
</${KolButtonWcTag}>
<div class="popover">
<div class="popover-content">
<slot></slot>
</div>
</div>
<div class="horizontal-line"></div>
<${KolButtonWcTag}
${props._disabled ? `_disabled=""` : ''}
_hidelabel=""
_icons="codicon codicon-triangle-down"
_label="${state._show ? translate(`${i18nDropdownLabel}-close`) : translate(`${i18nDropdownLabel}-open`)}"
class="secondary-button"
>
</${KolButtonWcTag}>
</div>
<${KolPopoverWcTag} ${state._show ? `_show ="${state._show}"` : ''} _align="bottom">
<slot />
</${KolPopoverWcTag}>
</mock:shadow-root>
</kol-split-button>`;
};
Loading