Skip to content

Commit

Permalink
fix(sbb-popover): ensure correct trigger connection after hydration (#…
Browse files Browse the repository at this point in the history
…3016)

Closes #3012
Closes #3014
  • Loading branch information
jeripeierSBB authored Aug 22, 2024
1 parent b614923 commit 5e59b8f
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 17 deletions.
10 changes: 9 additions & 1 deletion src/elements/autocomplete/autocomplete.ssr.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { assert } from '@open-wc/testing';
import { assert, expect } from '@open-wc/testing';
import { html } from 'lit';

import { ssrHydratedFixture } from '../core/testing/private.js';
Expand Down Expand Up @@ -31,4 +31,12 @@ describe(`sbb-autocomplete ssr`, () => {
it('renders', () => {
assert.instanceOf(root.querySelector('sbb-autocomplete'), SbbAutocompleteElement);
});

it('opens autocomplete', () => {
root.querySelector('input')!.focus();

expect(root.querySelector('sbb-autocomplete')!.getAttribute('data-state')).not.to.be.equal(
'closed',
);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,26 @@ describe(`sbb-datepicker-toggle`, () => {
expect(popover).to.have.attribute('data-state', 'opened');
});

it('renders and opens popover programmatically by click', async () => {
const root = await fixture(html`
<div>
<sbb-datepicker-toggle date-picker="datepicker"></sbb-datepicker-toggle>
<sbb-datepicker input="datepicker-input" id="datepicker"></sbb-datepicker>
<input id="datepicker-input" />
</div>
`);
const element: SbbDatepickerToggleElement =
root.querySelector<SbbDatepickerToggleElement>('sbb-datepicker-toggle')!;
const popover: SbbPopoverElement =
element.shadowRoot!.querySelector<SbbPopoverElement>('sbb-popover')!;

expect(popover).to.have.attribute('data-state', 'closed');

element.click();

expect(popover).not.to.have.attribute('data-state', 'closed');
});

it('datepicker is created after the component', async () => {
const root = await fixture(html`
<div id="parent">
Expand Down
18 changes: 12 additions & 6 deletions src/elements/datepicker/datepicker-toggle/datepicker-toggle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ref } from 'lit/directives/ref.js';

import type { CalendarView, SbbCalendarElement } from '../../calendar.js';
import { sbbInputModalityDetector } from '../../core/a11y.js';
import { SbbLanguageController } from '../../core/controllers.js';
import { SbbConnectedAbortController, SbbLanguageController } from '../../core/controllers.js';
import { hostAttributes } from '../../core/decorators.js';
import { i18nShowCalendar } from '../../core/i18n.js';
import { SbbHydrationMixin, SbbNegativeMixin } from '../../core/mixins.js';
Expand Down Expand Up @@ -45,16 +45,12 @@ export class SbbDatepickerToggleElement<T = Date> extends SbbNegativeMixin(
@state() private _renderCalendar = false;

private _datePickerElement: SbbDatepickerElement<T> | null | undefined;

private _calendarElement!: SbbCalendarElement<T>;

private _triggerElement!: SbbPopoverTriggerElement;

private _popoverElement!: SbbPopoverElement;

private _datePickerController!: AbortController;

private _language = new SbbLanguageController(this);
private _abort = new SbbConnectedAbortController(this);

public constructor() {
super();
Expand Down Expand Up @@ -83,6 +79,16 @@ export class SbbDatepickerToggleElement<T = Date> extends SbbNegativeMixin(
if (formField) {
this.negative = formField.hasAttribute('negative');
}

this.addEventListener(
'click',
(event) => {
if (event.composedPath()[0] === this) {
this.open();
}
},
{ signal: this._abort.signal },
);
}

public override willUpdate(changedProperties: PropertyValues<this>): void {
Expand Down
15 changes: 13 additions & 2 deletions src/elements/datepicker/datepicker/datepicker.ssr.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { html } from 'lit';

import { defaultDateAdapter } from '../../core/datetime.js';
import { ssrHydratedFixture } from '../../core/testing/private.js';
import type { SbbDatepickerToggleElement } from '../datepicker-toggle.js';

import { SbbDatepickerElement } from './datepicker.js';

Expand Down Expand Up @@ -42,12 +43,22 @@ describe(`sbb-datepicker ssr`, () => {
],
},
);
const datepicker = root.querySelector('sbb-datepicker')!;

const datepicker = root.querySelector<SbbDatepickerElement>('sbb-datepicker')!;
expect(asIso8601(datepicker.valueAsDate!)).to.equal(asIso8601(new Date(2023, 0, 1)));

const datepickerToggle = root.querySelector('sbb-datepicker-toggle')!;
const datepickerToggle =
root.querySelector<SbbDatepickerToggleElement>('sbb-datepicker-toggle')!;
await datepickerToggle.hydrationComplete;
await datepickerToggle.updateComplete;
expect(datepickerToggle.shadowRoot?.querySelector('sbb-calendar')).to.not.be.null;

// When opening the calendar
datepickerToggle.open();

// Then the calendar should be displayed
expect(
datepickerToggle.shadowRoot?.querySelector('sbb-popover')?.getAttribute('data-state'),
).not.to.be.equal('closed');
});
});
22 changes: 15 additions & 7 deletions src/elements/popover/popover/popover.ssr.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { assert } from '@open-wc/testing';
import { assert, expect } from '@open-wc/testing';
import { html } from 'lit';

import type { SbbButtonElement } from '../../button.js';
import { ssrHydratedFixture } from '../../core/testing/private.js';

import { SbbPopoverElement } from './popover.js';
Expand All @@ -21,9 +22,9 @@ describe(`sbb-popover ssr`, () => {
Popover content.
<sbb-link id="popover-link" href="#" sbb-popover-close>Link</sbb-link>
</sbb-popover>
<sbb-block-link href="#" id="interactive-background-element"
>Other interactive element</sbb-block-link
>
<sbb-block-link href="#" id="interactive-background-element">
Other interactive element
</sbb-block-link>
</span>
`,
{ modules: ['../../button.js', './popover.js', '../../link.js'] },
Expand All @@ -33,6 +34,13 @@ describe(`sbb-popover ssr`, () => {
it('renders', () => {
assert.instanceOf(root.querySelector('sbb-popover'), SbbPopoverElement);
});

it('connects trigger correctly', () => {
root.querySelector<SbbButtonElement>('#popover-trigger')!.click();
expect(root.querySelector('sbb-popover')!.getAttribute('data-state')).not.to.be.equal(
'closed',
);
});
});

describe('hover trigger', () => {
Expand All @@ -45,9 +53,9 @@ describe(`sbb-popover ssr`, () => {
Popover content.
<sbb-link id="popover-link" href="#" sbb-popover-close>Link</sbb-link>
</sbb-popover>
<sbb-block-link href="#" id="interactive-background-element"
>Other interactive element</sbb-block-link
>
<sbb-block-link href="#" id="interactive-background-element">
Other interactive element
</sbb-block-link>
</span>
`,
{ modules: ['../../button.js', './popover.js', '../../link.js'] },
Expand Down
2 changes: 1 addition & 1 deletion src/elements/popover/popover/popover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ export class SbbPopoverElement extends SbbHydrationMixin(SbbOpenCloseBaseElement
if (isServer) {
return;
} else if (this.hydrationRequired) {
this.hydrationComplete.then(() => this._configure);
this.hydrationComplete.then(() => this._configure());
return;
}

Expand Down

0 comments on commit 5e59b8f

Please sign in to comment.