Skip to content
Closed
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
20 changes: 18 additions & 2 deletions packages/components/src/components/button/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
Listen,
Element,
Method,
Watch,
} from '@stencil/core';
import classNames from 'classnames';
import { hasShadowDom, ScaleIcon, isScaleIcon } from '../../utils/utils';
Expand All @@ -40,7 +41,7 @@ export class Button {
/** (optional) Button variant */
@Prop() variant?: string = 'primary';
/** (optional) If `true`, the button is disabled */
@Prop({ reflect: true }) disabled?: boolean = false;
@Prop() disabled?: boolean = false;
/** (optional) Button type */
@Prop() type?: 'reset' | 'submit' | 'button';
/** (optional) The name of the button, submitted as a pair with the button's `value` as part of the form data */
Expand All @@ -67,6 +68,11 @@ export class Button {
private focusableElement: HTMLElement;
private fallbackSubmitInputElement: HTMLInputElement;

@Watch('disabled')
onDisabledChange() {
this.syncDisabledAttr();
}

/**
* Prevent clicks from being emitted from the host
* when the component is `disabled`.
Expand Down Expand Up @@ -119,6 +125,7 @@ export class Button {
connectedCallback() {
this.setIconPositionProp();
this.appendEnterKeySubmitFallback();
this.syncDisabledAttr();
}

disconnectedCallback() {
Expand Down Expand Up @@ -226,7 +233,9 @@ export class Button {
ref={(el) => (this.focusableElement = el)}
class={this.getCssClassMap()}
onClick={this.handleClick}
disabled={this.disabled}
disabled={
this.disabled ? true : undefined
} /* Use undefined to properly remove the disabled attribute when false*/
type={this.type}
part={basePart}
tabIndex={this.innerTabindex}
Expand All @@ -253,4 +262,11 @@ export class Button {
this.disabled && `button--disabled`
);
}
private syncDisabledAttr() {
if (this.disabled) {
this.hostElement.setAttribute('disabled', '');
} else {
this.hostElement.removeAttribute('disabled');
}
}
}
142 changes: 96 additions & 46 deletions packages/components/src/components/date-picker/date-picker.tsx
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please remove the changes notrelevent for this PR .

just revert this file in this branch

Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,17 @@ export class DatePicker {
input.setAttribute('placeholder', newValue);
}
}
/**
* Watch `localization` for changes and refresh all DOM bits we set manually
* (buttonLabel/title, custom heading, weekday abbreviations, "today" suffix, etc.).
*/
@Watch('localization')
onLocalizationChange() {
if (this.duetInput && this.localization) {
(this.duetInput as any).localization = this.localization;
}
this.updateDomOnLocalizationChange();
}

componentWillLoad() {
if (this.popupTitle !== 'Pick a date') {
Expand Down Expand Up @@ -334,53 +345,10 @@ export class DatePicker {
input.setAttribute('aria-invalid', 'true');
}

// Remove existing <h2> with `{Month} {Year}` text
const dialog = this.hostElement.querySelector('.duet-date__dialog');
let duetHeadingId: string = '';
if (dialog) {
duetHeadingId = dialog.getAttribute('aria-labelledby');
if (duetHeadingId) {
const duetHeading = this.hostElement.querySelector(`#${duetHeadingId}`);
if (duetHeading) {
duetHeading.parentElement.removeChild(duetHeading);
}
}
}

// Add custom <h2> heading
const dialogContent = this.hostElement.querySelector(
'.duet-date__dialog-content'
);
if (dialogContent) {
const calendarHeading =
this.localization?.calendarHeading || this.popupTitle || 'Pick a date';
const heading = document.createElement('h2');
heading.id = duetHeadingId; // link to .duet-date__dialog[aria-labelledby]
heading.className = 'scale-date-picker__popup-heading';
heading.innerHTML = calendarHeading;
dialogContent.insertBefore(heading, dialogContent.firstChild);
}

// truncate table headings to a single character
const tableHeadings = this.hostElement.querySelectorAll(
'.duet-date__table-header span[aria-hidden="true"]'
);
if (tableHeadings) {
Array.from(tableHeadings).forEach(
(item) => (item.innerHTML = item.innerHTML[0])
);
}

const today = this.hostElement.querySelector(
'.duet-date__day.is-today span.duet-date__vhidden'
);
if (today) {
today.innerHTML = `${today.innerHTML}, ${
this.localization?.today || 'today'
}`;
}

this.adjustButtonsLabelsForA11y();

// Initialize all localized bits
this.updateDomOnLocalizationChange();
}

componentDidRender() {
Expand Down Expand Up @@ -508,4 +476,86 @@ export class DatePicker {
</Host>
);
}
private updateDomOnLocalizationChange = () => {
// Remove Duet’s default <h2> and ensure our custom heading exists/updates
const dialog = this.hostElement.querySelector('.duet-date__dialog');
const dialogContent = this.hostElement.querySelector(
'.duet-date__dialog-content'
);
if (dialog && dialogContent) {
const duetHeadingId = dialog.getAttribute('aria-labelledby') || '';
if (duetHeadingId) {
const duetHeading = this.hostElement.querySelector<HTMLElement>(
'#' + duetHeadingId
);
if (duetHeading && duetHeading.parentElement) {
duetHeading.parentElement.removeChild(duetHeading);
}
}
const calendarHeading =
this.localization?.calendarHeading || this.popupTitle || 'Pick a date';
let heading = this.hostElement.querySelector<HTMLElement>(
'.scale-date-picker__popup-heading'
);
if (!heading) {
heading = document.createElement('h2');
if (duetHeadingId) {
heading.id = duetHeadingId;
heading.className = 'scale-date-picker__popup-heading';
dialogContent.insertBefore(heading, dialogContent.firstChild);
}
}
heading.textContent = calendarHeading;
}

// Toggle button (buttonLabel / title / aria-label)
const toggleBtn =
this.hostElement.querySelector<HTMLButtonElement>('.duet-date__toggle');
const btnLabel = (this.localization as any)?.buttonLabel;
if (toggleBtn && btnLabel) {
toggleBtn.setAttribute('title', btnLabel);
toggleBtn.setAttribute('aria-label', btnLabel);
}

// Truncate weekday headings to one character
// Update weekday headings based on current localization
const short =
(this.localization as any)?.weekdays?.shorthand || // Duet format
(this.localization as any)?.dayNamesShort || // alternative
(this.localization as any)?.dayNames?.map((d: string) => d.slice(0, 1)) ||
[];

// Adjust for firstDayOfWeek (Duet default = Monday = 1)
const start = Number.isInteger(this.firstDayOfWeek)
? Number(this.firstDayOfWeek)
: 1;

const ordered =
short.length === 7
? [...short.slice(start), ...short.slice(0, start)]
: short;

// Apply the correct short labels to the DOM
const tableHeadings = Array.from(
this.hostElement.querySelectorAll<HTMLElement>(
'.duet-date__table-header span[aria-hidden="true"]'
)
);

tableHeadings.forEach((el, i) => {
const label = ordered[i];
// Use the first character if full names are provided
el.textContent = label ? label[0] : (el.textContent || '').slice(0, 1);
});

// "today" visually hidden text
const today = this.hostElement.querySelector(
'.duet-date__day.is-today span.duet-date__vhidden'
);
if (today) {
today.innerHTML = `${today.innerHTML}, ${
this.localization?.today || 'today'
}`;
}
};
}
Loading