Skip to content

Commit

Permalink
feat(chip): replace always-focusable attribute with new `soft-disab…
Browse files Browse the repository at this point in the history
…led` attribute

PiperOrigin-RevId: 651801616
  • Loading branch information
zelliott authored and copybara-github committed Jul 12, 2024
1 parent 7867674 commit 77ca73d
Show file tree
Hide file tree
Showing 11 changed files with 40 additions and 43 deletions.
20 changes: 8 additions & 12 deletions chips/demo/stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,8 @@ const assist: MaterialStoryInit<StoryKnobs> = {
>${GOOGLE_LOGO}</md-assist-chip
>
<md-assist-chip
label=${label || 'Disabled assist chip (focusable)'}
disabled
always-focusable
label=${label || 'Soft-disabled assist chip (focusable)'}
soft-disabled
?elevated=${elevated}></md-assist-chip>
</md-chip-set>
`;
Expand Down Expand Up @@ -100,9 +99,8 @@ const filters: MaterialStoryInit<StoryKnobs> = {
?elevated=${elevated}
removable></md-filter-chip>
<md-filter-chip
label=${label || 'Disabled filter chip (focusable)'}
disabled
always-focusable
label=${label || 'Soft-disabled filter chip (focusable)'}
soft-disabled
?elevated=${elevated}
removable></md-filter-chip>
</md-chip-set>
Expand Down Expand Up @@ -144,9 +142,8 @@ const inputs: MaterialStoryInit<StoryKnobs> = {
?disabled=${disabled}
remove-only></md-input-chip>
<md-input-chip
label=${label || 'Disabled input chip (focusable)'}
disabled
always-focusable></md-input-chip>
label=${label || 'Soft-disabled input chip (focusable)'}
soft-disabled></md-input-chip>
</md-chip-set>
`;
},
Expand Down Expand Up @@ -177,9 +174,8 @@ const suggestions: MaterialStoryInit<StoryKnobs> = {
>${GOOGLE_LOGO}</md-suggestion-chip
>
<md-suggestion-chip
label=${label || 'Disabled suggestion chip (focusable)'}
disabled
always-focusable
label=${label || 'Soft-disabled suggestion chip (focusable)'}
soft-disabled
?elevated=${elevated}></md-suggestion-chip>
</md-chip-set>
`;
Expand Down
4 changes: 2 additions & 2 deletions chips/internal/_shared.scss
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
);
}

:host([disabled]) {
:host(:is([disabled], [soft-disabled])) {
pointer-events: none;
}

Expand Down Expand Up @@ -242,7 +242,7 @@
}

a,
button:not(:disabled) {
button:not(:disabled, [aria-disabled='true']) {
cursor: inherit;
}
}
7 changes: 4 additions & 3 deletions chips/internal/assist-chip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,14 @@ export class AssistChip extends Chip {

protected override get rippleDisabled() {
// Link chips cannot be disabled
return !this.href && this.disabled;
return !this.href && (this.disabled || this.softDisabled);
}

protected override getContainerClasses() {
return {
...super.getContainerClasses(),
// Link chips cannot be disabled
disabled: !this.href && this.disabled,
disabled: !this.href && (this.disabled || this.softDisabled),
elevated: this.elevated,
link: !!this.href,
};
Expand All @@ -60,7 +60,8 @@ export class AssistChip extends Chip {
class="primary action"
id="button"
aria-label=${ariaLabel || nothing}
?disabled=${this.disabled && !this.alwaysFocusable}
aria-disabled=${this.softDisabled || nothing}
?disabled=${this.disabled}
type="button"
>${content}</button
>
Expand Down
8 changes: 4 additions & 4 deletions chips/internal/chip-set.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,10 @@ export class ChipSet extends LitElement {
// Check if the next sibling is disabled. If so,
// move the index and continue searching.
//
// Some toolbar items may be focusable when disabled for increased
// visibility.
// Some toolbar items may be soft-disabled (disabled but focusable
// increased visibility.
const nextChip = chips[nextIndex];
if (nextChip.disabled && !nextChip.alwaysFocusable) {
if (nextChip.disabled) {
if (forwards) {
nextIndex++;
} else {
Expand All @@ -118,7 +118,7 @@ export class ChipSet extends LitElement {
const {chips} = this;
let chipToFocus: Chip | undefined;
for (const chip of chips) {
const isChipFocusable = chip.alwaysFocusable || !chip.disabled;
const isChipFocusable = !chip.disabled;
const chipIsFocused = chip.matches(':focus-within');
if (chipIsFocused && isChipFocusable) {
// Found the first chip that is actively focused. This overrides the
Expand Down
5 changes: 2 additions & 3 deletions chips/internal/chip-set_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,11 +204,10 @@ describe('Chip set', () => {
});
});

it('should NOT skip over disabled always focusable chips', async () => {
it('should NOT skip over soft-disabled chips', async () => {
const first = new TestAssistChip();
const second = new TestAssistChip();
second.disabled = true;
second.alwaysFocusable = true;
second.softDisabled = true;
const third = new TestAssistChip();
const chipSet = await setupTest([first, second, third]);
await testNavigation({
Expand Down
17 changes: 8 additions & 9 deletions chips/internal/chip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,19 @@ export abstract class Chip extends chipBaseClass {

/**
* Whether or not the chip is disabled.
*
* Disabled chips are not focusable, unless `always-focusable` is set.
*/
@property({type: Boolean, reflect: true}) disabled = false;

/**
* When true, allow disabled chips to be focused with arrow keys.
* Whether or not the chip is "soft-disabled" (disabled but still
* focusable).
*
* Add this when a chip needs increased visibility when disabled. See
* Use this when a chip needs increased visibility when disabled. See
* https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#kbd_disabled_controls
* for more guidance on when this is needed.
*/
@property({type: Boolean, attribute: 'always-focusable'})
alwaysFocusable = false;
@property({type: Boolean, attribute: 'soft-disabled', reflect: true})
softDisabled = false;

/**
* The label of the chip.
Expand All @@ -70,11 +69,11 @@ export abstract class Chip extends chipBaseClass {
* Some chip actions such as links cannot be disabled.
*/
protected get rippleDisabled() {
return this.disabled;
return this.disabled || this.softDisabled;
}

override focus(options?: FocusOptions) {
if (this.disabled && !this.alwaysFocusable) {
if (this.disabled) {
return;
}

Expand All @@ -97,7 +96,7 @@ export abstract class Chip extends chipBaseClass {

protected getContainerClasses(): ClassInfo {
return {
'disabled': this.disabled,
'disabled': this.disabled || this.softDisabled,
'has-icon': this.hasIcon,
};
}
Expand Down
7 changes: 4 additions & 3 deletions chips/internal/filter-chip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ export class FilterChip extends MultiActionChip {
id="button"
aria-label=${ariaLabel || nothing}
aria-pressed=${this.selected}
?disabled=${this.disabled && !this.alwaysFocusable}
aria-disabled=${this.softDisabled || nothing}
?disabled=${this.disabled}
@click=${this.handleClick}
>${content}</button
>
Expand All @@ -88,7 +89,7 @@ export class FilterChip extends MultiActionChip {
return renderRemoveButton({
focusListener,
ariaLabel: this.ariaLabelRemove,
disabled: this.disabled,
disabled: this.disabled || this.softDisabled,
});
}

Expand All @@ -104,7 +105,7 @@ export class FilterChip extends MultiActionChip {
}

private handleClick(event: MouseEvent) {
if (this.disabled) {
if (this.disabled || this.softDisabled) {
return;
}

Expand Down
9 changes: 5 additions & 4 deletions chips/internal/input-chip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export class InputChip extends MultiActionChip {

protected override get rippleDisabled() {
// Link chips cannot be disabled
return !this.href && this.disabled;
return !this.href && (this.disabled || this.softDisabled);
}

protected get primaryAction() {
Expand All @@ -59,7 +59,7 @@ export class InputChip extends MultiActionChip {
...super.getContainerClasses(),
avatar: this.avatar,
// Link chips cannot be disabled
disabled: !this.href && this.disabled,
disabled: !this.href && (this.disabled || this.softDisabled),
link: !!this.href,
selected: this.selected,
'has-trailing': true,
Expand Down Expand Up @@ -94,7 +94,8 @@ export class InputChip extends MultiActionChip {
class="primary action"
id="button"
aria-label=${ariaLabel || nothing}
?disabled=${this.disabled && !this.alwaysFocusable}
aria-disabled=${this.softDisabled || nothing}
?disabled=${this.disabled}
type="button"
>${content}</button
>
Expand All @@ -105,7 +106,7 @@ export class InputChip extends MultiActionChip {
return renderRemoveButton({
focusListener,
ariaLabel: this.ariaLabelRemove,
disabled: !this.href && this.disabled,
disabled: !this.href && (this.disabled || this.softDisabled),
tabbable: this.removeOnly,
});
}
Expand Down
3 changes: 1 addition & 2 deletions chips/internal/multi-action-chip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,7 @@ export abstract class MultiActionChip extends Chip {
}

override focus(options?: FocusOptions & {trailing?: boolean}) {
const isFocusable = this.alwaysFocusable || !this.disabled;
if (isFocusable && options?.trailing && this.trailingAction) {
if (!this.disabled && options?.trailing && this.trailingAction) {
this.trailingAction.focus(options);
return;
}
Expand Down
2 changes: 1 addition & 1 deletion chips/internal/trailing-icons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export function renderRemoveButton({
}

function handleRemoveClick(this: Chip, event: Event) {
if (this.disabled) {
if (this.disabled || this.softDisabled) {
return;
}

Expand Down
1 change: 1 addition & 0 deletions testing/templates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export enum State {
HOVER = 'Hover',
PRESSED = 'Pressed',
SELECTED = 'Selected',
SOFT_DISABLED = 'Soft disabled',
}

/**
Expand Down

0 comments on commit 77ca73d

Please sign in to comment.