Skip to content

Commit

Permalink
Merge branch 'main' into refactor/teaser-a11y-problem
Browse files Browse the repository at this point in the history
  • Loading branch information
jeripeierSBB committed Nov 28, 2024
2 parents 853f39b + 0f0066d commit 1b5013e
Show file tree
Hide file tree
Showing 44 changed files with 530 additions and 863 deletions.
7 changes: 6 additions & 1 deletion .storybook/preview-head.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@

<style>
/* Classes used for the custom sbb-header story. */
.last-element {
.last-element,
.sbb-header-spacer-logo {
display: none;
}

Expand All @@ -41,6 +42,10 @@
.sbb-header-spacer {
display: none;
}

.sbb-header-spacer-logo {
display: block;
}
}

.sbdocs-content {
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@
"octokit": "4.0.2",
"playwright": "1.47.2",
"postcss": "8.4.49",
"prettier": "3.4.0",
"prettier": "3.4.1",
"react": "18.3.1",
"rollup-plugin-postcss-lit": "2.1.0",
"sass": "1.81.0",
Expand All @@ -144,7 +144,7 @@
"typescript": "5.7.2",
"typescript-eslint": "8.16.0",
"urlpattern-polyfill": "10.0.0",
"vite": "5.4.11",
"vite": "6.0.1",
"vite-plugin-dts": "4.3.0"
},
"resolutions": {
Expand All @@ -154,7 +154,7 @@
"jackspeak": "2.1.1",
"lit": "3.2.1",
"playwright": "1.47.2",
"prettier": "3.4.0"
"prettier": "3.4.1"
},
"prettier": {
"singleQuote": true,
Expand Down
5 changes: 4 additions & 1 deletion src/elements/autocomplete/autocomplete-base-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,10 @@ export abstract class SbbAutocompleteBaseElement extends SbbNegativeMixin(

if (this.triggerElement) {
// Set the option value
this.triggerElement.value = target.value as string;
// In order to support React onChange event, we have to get the setter and call it.
// https://github.com/facebook/react/issues/11600#issuecomment-345813130
const setValue = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value')!.set!;
setValue.call(this.triggerElement, target.value);

// Manually trigger the change events
this.triggerElement.dispatchEvent(new Event('change', { bubbles: true }));
Expand Down
1 change: 0 additions & 1 deletion src/elements/button/mini-button.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
export * from './mini-button/mini-button-base-element.js';
export * from './mini-button/mini-button.js';
16 changes: 0 additions & 16 deletions src/elements/button/mini-button/mini-button-base-element.ts

This file was deleted.

17 changes: 13 additions & 4 deletions src/elements/button/mini-button/mini-button.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import type { CSSResultGroup } from 'lit';
import type { CSSResultGroup, TemplateResult } from 'lit';
import { customElement } from 'lit/decorators.js';

import { SbbDisabledTabIndexActionMixin } from '../../core/mixins.js';
import { SbbButtonBaseElement } from '../../core/base-elements.js';
import { slotState } from '../../core/decorators.js';
import { SbbDisabledTabIndexActionMixin, SbbNegativeMixin } from '../../core/mixins.js';
import { SbbIconNameMixin } from '../../icon.js';

import { SbbMiniButtonBaseElement } from './mini-button-base-element.js';
import style from './mini-button.scss?lit&inline';

/**
Expand All @@ -14,8 +16,15 @@ import style from './mini-button.scss?lit&inline';
*/
export
@customElement('sbb-mini-button')
class SbbMiniButtonElement extends SbbDisabledTabIndexActionMixin(SbbMiniButtonBaseElement) {
@slotState()
class SbbMiniButtonElement extends SbbDisabledTabIndexActionMixin(
SbbNegativeMixin(SbbIconNameMixin(SbbButtonBaseElement)),
) {
public static override styles: CSSResultGroup = style;

protected override renderTemplate(): TemplateResult {
return super.renderIconSlot();
}
}

declare global {
Expand Down
2 changes: 0 additions & 2 deletions src/elements/checkbox/checkbox-panel/checkbox-panel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ export type SbbCheckboxPanelStateChange = Extract<
* @slot subtext - Slot used to render a subtext under the label (only visible within a selection panel).
* @slot suffix - Slot used to render additional content after the label (only visible within a selection panel).
* @slot badge - Use this slot to provide a `sbb-card-badge` (optional).
* @event {CustomEvent<void>} didChange - Deprecated. used for React. Will probably be removed once React 19 is available.
* @event {Event} change - Event fired on change.
* @event {InputEvent} input - Event fired on input.
*/
Expand All @@ -52,7 +51,6 @@ class SbbCheckboxPanelElement extends SbbPanelMixin(

// FIXME using ...super.events requires: https://github.com/sbb-design-systems/lyne-components/issues/2600
public static readonly events = {
didChange: 'didChange',
stateChange: 'stateChange',
panelConnected: 'panelConnected',
} as const;
Expand Down
9 changes: 4 additions & 5 deletions src/elements/checkbox/checkbox-panel/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,10 @@ If you don't want the label to appear next to the checkbox, you can use `aria-la

## Events

| Name | Type | Description | Inherited From |
| ----------- | ------------------- | -------------------------------------------------------------------------------- | -------------- |
| `change` | `Event` | Event fired on change. | |
| `didChange` | `CustomEvent<void>` | Deprecated. used for React. Will probably be removed once React 19 is available. | |
| `input` | `InputEvent` | Event fired on input. | |
| Name | Type | Description | Inherited From |
| -------- | ------------ | ---------------------- | -------------- |
| `change` | `Event` | Event fired on change. | |
| `input` | `InputEvent` | Event fired on input. | |

## Slots

Expand Down
5 changes: 0 additions & 5 deletions src/elements/checkbox/checkbox/checkbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import '../../visual-checkbox.js';
*
* @slot - Use the unnamed slot to add content to the `sbb-checkbox`.
* @slot icon - Slot used to render the checkbox icon (disabled inside a selection panel).
* @event {CustomEvent<void>} didChange - Deprecated. used for React. Will probably be removed once React 19 is available.
* @event {Event} change - Event fired on change.
* @event {InputEvent} input - Event fired on input.
*/
Expand All @@ -29,10 +28,6 @@ export
class SbbCheckboxElement extends SbbCheckboxCommonElementMixin(SbbIconNameMixin(LitElement)) {
public static override styles: CSSResultGroup = [checkboxCommonStyle, checkboxStyle];

public static readonly events = {
didChange: 'didChange',
} as const;

/** Size variant. */
@property({ reflect: true })
@getOverride((i, v) => i.group?.size ?? v)
Expand Down
9 changes: 4 additions & 5 deletions src/elements/checkbox/checkbox/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,10 @@ If you don't want the label to appear next to the checkbox, you can use `aria-la

## Events

| Name | Type | Description | Inherited From |
| ----------- | ------------------- | -------------------------------------------------------------------------------- | -------------- |
| `change` | `Event` | Event fired on change. | |
| `didChange` | `CustomEvent<void>` | Deprecated. used for React. Will probably be removed once React 19 is available. | |
| `input` | `InputEvent` | Event fired on input. | |
| Name | Type | Description | Inherited From |
| -------- | ------------ | ---------------------- | -------------- |
| `change` | `Event` | Event fired on change. | |
| `input` | `InputEvent` | Event fired on input. | |

## Slots

Expand Down
5 changes: 2 additions & 3 deletions src/elements/core/datetime/date-adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ export const YEARS_PER_PAGE: number = 24;
export const FORMAT_DATE =
/(^0?[1-9]?|[12]?[0-9]?|3?[01]?)[.,\\/\-\s](0?[1-9]?|1?[0-2]?)?[.,\\/\-\s](\d{1,4}$)?/;

// TODO(breaking-change): Change undefined return types to null.

/**
* Abstract date functionality.
*
Expand Down Expand Up @@ -139,11 +137,12 @@ export abstract class DateAdapter<T = any> {
* @param value The date in the format DD.MM.YYYY.
* @param now The current date as Date.
*/
public abstract parse(value: string | null | undefined, now: T): T | undefined;
public abstract parse(value: string | null | undefined, now: T): T | null;

/**
* Format the given date as string.
* @param date The date to format.
* @param options options object with weekdayStyle as property
*/
public format(
date: T | null | undefined,
Expand Down
6 changes: 3 additions & 3 deletions src/elements/core/datetime/native-date-adapter.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,9 +194,9 @@ describe('NativeDateAdapter', () => {

it('parseDate should return the correct value', function () {
const now = new Date(2023, 8, 15, 0, 0, 0, 0);
expect(nativeDateAdapter.parse(null, now)).to.be.undefined;
expect(nativeDateAdapter.parse('Test', now)).to.be.undefined;
expect(nativeDateAdapter.parse('1.1', now)).to.be.undefined;
expect(nativeDateAdapter.parse(null, now)).to.be.null;
expect(nativeDateAdapter.parse('Test', now)).to.be.null;
expect(nativeDateAdapter.parse('1.1', now)).to.be.null;
let formattedDate = nativeDateAdapter.parse('1/1/2000', now)!;
expect(formattedDate.getFullYear()).to.be.equal(2000);
expect(formattedDate.getMonth()).to.be.equal(0);
Expand Down
6 changes: 3 additions & 3 deletions src/elements/core/datetime/native-date-adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,9 +173,9 @@ export class NativeDateAdapter extends DateAdapter<Date> {
}

/** Returns the right format for the `valueAsDate` property. */
public parse(value: string | null | undefined, now: Date): Date | undefined {
public parse(value: string | null | undefined, now: Date): Date | null {
if (!value) {
return undefined;
return null;
}

const strippedValue = value.replace(/\D/g, ' ').trim();
Expand All @@ -188,7 +188,7 @@ export class NativeDateAdapter extends DateAdapter<Date> {
match.some((e) => e === undefined) ||
!this.isValid(this.createDate(+match[3], +match[2], +match[1]))
) {
return undefined;
return null;
}

let year = +match[3];
Expand Down
1 change: 0 additions & 1 deletion src/elements/core/mixins/form-associated-checkbox-mixin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,6 @@ export const SbbFormAssociatedCheckboxMixin = <T extends Constructor<LitElement>

this.dispatchEvent(new InputEvent('input', { composed: true, bubbles: true }));
this.dispatchEvent(new Event('change', { bubbles: true }));
this.dispatchEvent(new CustomEvent('didChange', { bubbles: true }));
};
}

Expand Down
39 changes: 11 additions & 28 deletions src/elements/datepicker/common/datepicker-button.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,7 @@ export abstract class SbbDatepickerButton<T = Date> extends SbbNegativeMixin(Sbb
protected abstract iconName: string;
protected abstract i18nOffBoundaryDay: Record<string, string>;
protected abstract i18nSelectOffBoundaryDay: (_currentDate: string) => Record<string, string>;
protected abstract findAvailableDate: (
_date: T,
_dateFilter: ((date: T) => boolean) | null,
_dateAdapter: DateAdapter<T>,
_boundary: string | number | null,
) => T;
protected abstract onInputUpdated(event: CustomEvent<SbbInputUpdateEvent>): void;
protected abstract findAvailableDate(_date: T): T;

public override connectedCallback(): void {
super.connectedCallback();
Expand All @@ -71,21 +65,16 @@ export abstract class SbbDatepickerButton<T = Date> extends SbbNegativeMixin(Sbb
this._datePickerController?.abort();
}

protected setDisabledState(datepicker: SbbDatepickerElement<T> | null | undefined): void {
const pickerValueAsDate = datepicker?.valueAsDate;
private _setDisabledState(): void {
const pickerValueAsDate = this.datePickerElement?.valueAsDate;

if (!pickerValueAsDate) {
this._disabled = true;
this._setDisabledRenderAttributes(true);
return;
}

const availableDate: T = this.findAvailableDate(
pickerValueAsDate,
datepicker?.dateFilter || null,
this._dateAdapter,
this.boundary,
);
const availableDate: T = this.findAvailableDate(pickerValueAsDate);
this._disabled = this._dateAdapter.compareDate(availableDate, pickerValueAsDate) === 0;
this._setDisabledRenderAttributes();
}
Expand All @@ -95,12 +84,7 @@ export abstract class SbbDatepickerButton<T = Date> extends SbbNegativeMixin(Sbb
return;
}
const startingDate: T = this.datePickerElement.valueAsDate ?? this.datePickerElement.now;
const date: T = this.findAvailableDate(
startingDate,
this.datePickerElement.dateFilter,
this._dateAdapter,
this.boundary,
);
const date: T = this.findAvailableDate(startingDate);
if (this._dateAdapter.compareDate(date, startingDate) !== 0) {
this.datePickerElement.valueAsDate = date;
}
Expand All @@ -125,7 +109,7 @@ export abstract class SbbDatepickerButton<T = Date> extends SbbNegativeMixin(Sbb
this._datePickerController?.abort();
this._datePickerController = new AbortController();
this.datePickerElement = getDatePicker(this, picker);
this.setDisabledState(this.datePickerElement);
this._setDisabledState();
if (!this.datePickerElement) {
// If the component is attached to the DOM before the datepicker, it has to listen for the datepicker init,
// assuming that the two components share the same parent element.
Expand All @@ -140,16 +124,16 @@ export abstract class SbbDatepickerButton<T = Date> extends SbbNegativeMixin(Sbb

this.datePickerElement.addEventListener(
'change',
(event: Event) => {
this.setDisabledState(event.target as SbbDatepickerElement<T>);
() => {
this._setDisabledState();
this._setAriaLabel();
},
{ signal: this._datePickerController.signal },
);
this.datePickerElement.addEventListener(
'datePickerUpdated',
(event: Event) => {
this.setDisabledState(event.target as SbbDatepickerElement<T>);
() => {
this._setDisabledState();
this._setAriaLabel();
},
{ signal: this._datePickerController.signal },
Expand All @@ -160,7 +144,7 @@ export abstract class SbbDatepickerButton<T = Date> extends SbbNegativeMixin(Sbb
this._inputDisabled = !!(event.detail.disabled || event.detail.readonly);
this._setDisabledRenderAttributes();
this._setAriaLabel();
this.onInputUpdated(event);
this._setDisabledState();
},
{ signal: this._datePickerController.signal },
);
Expand All @@ -176,7 +160,6 @@ export abstract class SbbDatepickerButton<T = Date> extends SbbNegativeMixin(Sbb
return;
}

// TODO: use toIsoString() instead of toDateString()
const currentDateString =
this.datePickerElement &&
this._dateAdapter.compareDate(this.datePickerElement.now, currentDate) === 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ import { customElement } from 'lit/decorators.js';
import { hostAttributes } from '../../core/decorators.js';
import { i18nNextDay, i18nSelectNextDay } from '../../core/i18n.js';
import { SbbDatepickerButton } from '../common.js';
import { findNextAvailableDate, type SbbInputUpdateEvent } from '../datepicker.js';

import '../../icon.js';
import style from './datepicker-next-day.scss?lit&inline';

/**
Expand All @@ -23,13 +21,10 @@ class SbbDatepickerNextDayElement<T = Date> extends SbbDatepickerButton<T> {
protected iconName: string = 'chevron-small-right-small';
protected i18nOffBoundaryDay: Record<string, string> = i18nNextDay;
protected i18nSelectOffBoundaryDay = i18nSelectNextDay;
protected findAvailableDate = findNextAvailableDate;

protected onInputUpdated(event: CustomEvent<SbbInputUpdateEvent>): void {
if (this.boundary !== event.detail.max) {
this.boundary = event.detail.max!;
this.setDisabledState(this.datePickerElement!);
}
protected findAvailableDate(date: T): T {
// When calling findAvailableDate, datepickerElement is always defined.
return this.datePickerElement!.findNextAvailableDate(date);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import { customElement } from 'lit/decorators.js';
import { hostAttributes } from '../../core/decorators.js';
import { i18nPreviousDay, i18nSelectPreviousDay } from '../../core/i18n.js';
import { SbbDatepickerButton } from '../common.js';
import { findPreviousAvailableDate, type SbbInputUpdateEvent } from '../datepicker.js';
import '../../icon.js';

import style from './datepicker-previous-day.scss?lit&inline';

Expand All @@ -23,13 +21,10 @@ class SbbDatepickerPreviousDayElement<T = Date> extends SbbDatepickerButton<T> {
protected iconName: string = 'chevron-small-left-small';
protected i18nOffBoundaryDay: Record<string, string> = i18nPreviousDay;
protected i18nSelectOffBoundaryDay = i18nSelectPreviousDay;
protected findAvailableDate = findPreviousAvailableDate;

protected onInputUpdated(event: CustomEvent<SbbInputUpdateEvent>): void {
if (this.boundary !== event.detail.min) {
this.boundary = event.detail.min!;
this.setDisabledState(this.datePickerElement!);
}
protected findAvailableDate(date: T): T {
// When calling findAvailableDate, datepickerElement is always defined.
return this.datePickerElement!.findPreviousAvailableDate(date);
}
}

Expand Down
Loading

0 comments on commit 1b5013e

Please sign in to comment.