Skip to content

Commit

Permalink
[@next] refactor setDefaultAria to use ElementInternals as fallba…
Browse files Browse the repository at this point in the history
…ck (#445)

* chore: refactor `setDefaultAria` to always set via `internals` ARIA properties; adjusted global theme colors to fix contrast issues

* chore: cleanup

* chore(linear-progress): fix timing bug when setting determinate state and progress together

* chore: fix button tabindex

* chore: fix text theme colors and update button toggle demo with custom style example

* chore: increase medium text theme to 60% and add contrast ratio validation for dynamic color computation

* chore: remove unused MDC deps

* chore: remove border on text example in theme demo

* chore(expansion-panel): remove internal `aria-expanded` attr
  • Loading branch information
DRiFTy17 authored Dec 14, 2023
1 parent 52404a9 commit e6d69dc
Show file tree
Hide file tree
Showing 43 changed files with 241 additions and 319 deletions.
3 changes: 0 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 0 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@
"@material/card": "^14.0.0",
"@material/checkbox": "^14.0.0",
"@material/chips": "^14.0.0",
"@material/density": "^14.0.0",
"@material/dom": "^14.0.0",
"@material/drawer": "^14.0.0",
"@material/elevation": "^14.0.0",
"@material/feature-targeting": "^14.0.0",
Expand All @@ -54,7 +52,6 @@
"@material/select": "^14.0.0",
"@material/shape": "^14.0.0",
"@material/theme": "^14.0.0",
"@material/touch-target": "^14.0.0",
"@material/typography": "^14.0.0",
"@tylertech/forge-core": "^2.3.0",
"@tylertech/tyler-icons": "^1.12.0",
Expand Down
19 changes: 19 additions & 0 deletions src/dev/pages/button-toggle/button-toggle.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,25 @@
</div>
</forge-card>
</section>

<!-- Legacy -->
<section>
<h3 class="forge-typography--heading2">Legacy (custom)</h3>
<forge-button-toggle-group class="legacy-button-toggle-group" value="email" aria-label="Custom button toggle group">
<forge-button-toggle value="email">
<forge-icon name="email" slot="start"></forge-icon>
By email
</forge-button-toggle>
<forge-button-toggle value="mail">
<forge-icon name="mail" slot="start"></forge-icon>
By mail
</forge-button-toggle>
<forge-button-toggle value="phone">
<forge-icon name="phone" slot="start"></forge-icon>
By phone
</forge-button-toggle>
</forge-button-toggle-group>
</section>
</div>

<script type="module" src="button-toggle.ts"></script>
2 changes: 1 addition & 1 deletion src/dev/pages/button-toggle/button-toggle.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
type: 'select',
label: 'Theme',
id: 'opt-theme',
defaultValue: 'primary',
defaultValue: 'tertiary',
options: [
{ label: 'Primary', value: 'primary' },
{ label: 'Secondary', value: 'secondary' },
Expand Down
37 changes: 37 additions & 0 deletions src/dev/pages/button-toggle/button-toggle.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
@use '../../../lib/button-toggle/button-toggle-group';
@use '../../../lib/button-toggle/button-toggle';
@use '../../../lib/core/styles/theme';

#toolbar-card {
display: inline-block;
Expand All @@ -16,4 +18,39 @@
height: auto;
margin-block: 4px;
}
}

.legacy-button-toggle-group {
@include button-toggle-group.provide-theme((
gap: 1px,
padding: 0
));

forge-button-toggle {
@include button-toggle.provide-theme((
selected-color: theme.variable(on-primary),
selected-background: theme.variable(primary),
focus-indicator-offset: 2px
));

&:first-of-type {
@include button-toggle.provide-theme((
shape-start-end: 0,
shape-end-end: 0
));
}

&:not(:first-of-type):not(:last-of-type) {
@include button-toggle.provide-theme((
shape: 0
));
}

&:last-of-type {
@include button-toggle.provide-theme((
shape-start-start: 0,
shape-end-start: 0
));
}
}
}
29 changes: 21 additions & 8 deletions src/dev/pages/theme/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ interface ISwatchGroup {

interface ISwatch {
text?: string;
background: string;
background?: string;
border?: string;
noBorder?: boolean;
foreground?: string;
}

Expand Down Expand Up @@ -105,17 +107,19 @@ const SWATCH_GROUPS: ISwatchGroup[] = [
{
header: 'Text',
swatches: [
{ text: 'High', background: 'text-high', foreground: 'text-high-inverse' },
{ text: 'Medium', background: 'text-medium', foreground: 'text-high-inverse' },
{ text: 'Low', background: 'text-low', foreground: 'text-high' },
{ text: 'Lowest', background: 'text-lowest', foreground: 'text-high' }
{ text: 'High (87%)', foreground: 'text-high', noBorder: true },
{ text: 'Medium (60%)', foreground: 'text-medium', noBorder: true },
{ text: 'Low (38%)', foreground: 'text-low', noBorder: true },
{ text: 'Lowest (12%)', foreground: 'text-lowest', noBorder: true }
]
},
{
header: 'Utilities',
swatches: [
{ text: 'Outline', background: 'outline', foreground: 'text-high' },
{ text: 'Outline (high)', background: 'outline-high', foreground: 'text-high-inverse' }
{ text: 'Outline (high)', border: 'outline-high' },
{ text: 'Outline (medium)', border: 'outline-medium' },
{ text: 'Outline (low)', border: 'outline-low' },
{ text: 'Outline', border: 'outline' }
]
}
];
Expand Down Expand Up @@ -148,7 +152,16 @@ function createSwatch(config: ISwatch): HTMLElement {
if (config.text) {
swatch.textContent = config.text;
}
swatch.style.setProperty('background-color', `var(--forge-theme-${config.background})`);

if (config.border && !config.noBorder) {
swatch.style.setProperty('border-color', `var(--forge-theme-${config.border})`);
} else if (config.noBorder) {
swatch.style.setProperty('border', 'none');
}

if (config.background) {
swatch.style.setProperty('background-color', `var(--forge-theme-${config.background})`);
}

if (config.foreground) {
swatch.style.setProperty('color', `var(--forge-theme-${config.foreground})`);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { COMPONENT_NAME_PREFIX, Theme } from '../../constants';
import { supportsElementInternalsAria } from '../../core';
import { ARIAAttribute } from '../../core/utils/a11y-utils';

const elementName: keyof HTMLElementTagNameMap = `${COMPONENT_NAME_PREFIX}button-toggle-group`;

Expand All @@ -18,8 +16,6 @@ const observedAttributes = {
THEME: 'theme'
};

const observedAriaAttributes: ARIAAttribute[] = supportsElementInternalsAria() ? [] : ['role', 'aria-label'];

const attributes = {
...observedAttributes
};
Expand All @@ -40,7 +36,6 @@ const events = {
export const BUTTON_TOGGLE_GROUP_CONSTANTS = {
elementName,
observedAttributes,
observedAriaAttributes,
attributes,
classes,
selectors,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export class ButtonToggleGroupFoundation implements IButtonToggleGroupFoundation
private _disabled = false;
private _readonly = false;
private _required = false;
private _theme: ButtonToggleGroupTheme = 'primary';
private _theme: ButtonToggleGroupTheme = 'tertiary';

private _selectListener: (evt: CustomEvent<IButtonToggleSelectEventData>) => void;
private _slotListener: () => void;
Expand Down Expand Up @@ -233,7 +233,7 @@ export class ButtonToggleGroupFoundation implements IButtonToggleGroupFoundation
public set theme(value: ButtonToggleGroupTheme) {
if (this._theme !== value) {
this._theme = value;
this._adapter.toggleHostAttribute(BUTTON_TOGGLE_GROUP_CONSTANTS.attributes.THEME, this._theme !== 'primary', this._theme);
this._adapter.toggleHostAttribute(BUTTON_TOGGLE_GROUP_CONSTANTS.attributes.THEME, this._theme !== 'tertiary', this._theme);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -116,15 +116,15 @@ $_host-tokens: [display];
::slotted(forge-button-toggle) {
@include button-toggle.provide-theme((
selected-background: #{theme.variable(#{$theme}-container-low)},
selected-color: #{theme.variable($theme)},
selected-color: #{theme.variable(on-#{$theme}-container-low)},
focus-indicator-color: #{theme.variable($theme)}
));
}
}
}

@include theme(primary);
@include theme(secondary);
@include theme(tertiary);
@include theme(success);
@include theme(error);
@include theme(warning);
Expand Down
11 changes: 3 additions & 8 deletions src/lib/button-toggle/button-toggle-group/button-toggle-group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { ButtonToggleComponent } from '../button-toggle/button-toggle';
import { ButtonToggleGroupAdapter } from './button-toggle-group-adapter';
import { ButtonToggleGroupTheme, BUTTON_TOGGLE_GROUP_CONSTANTS, IButtonToggleGroupChangeEventData } from './button-toggle-group-constants';
import { ButtonToggleGroupFoundation } from './button-toggle-group-foundation';
import { getFormState, getFormValue, inputType, observedDefaultAriaAttributes, setDefaultAria } from '../../constants';
import { getFormState, getFormValue, inputType, setDefaultAria } from '../../constants';
import { FormValue, FormRestoreState, FormRestoreReason } from '../../core/utils/form-utils';
import { IWithDefaultAria, WithDefaultAria } from '../../core/mixins/internals/with-default-aria';

Expand Down Expand Up @@ -100,14 +100,9 @@ const BaseButtonToggleGroupClass = WithLabelAwareness(WithFormAssociation(WithFo
})
export class ButtonToggleGroupComponent extends BaseButtonToggleGroupClass implements IButtonToggleGroupComponent {
public static get observedAttributes(): string[] {
return [
...Object.values(BUTTON_TOGGLE_GROUP_CONSTANTS.observedAttributes),
...Object.values(BUTTON_TOGGLE_GROUP_CONSTANTS.observedAriaAttributes)
];
return Object.values(BUTTON_TOGGLE_GROUP_CONSTANTS.observedAttributes);
}

public readonly [observedDefaultAriaAttributes] = BUTTON_TOGGLE_GROUP_CONSTANTS.observedAriaAttributes;

private _foundation: ButtonToggleGroupFoundation;

constructor() {
Expand All @@ -118,7 +113,7 @@ export class ButtonToggleGroupComponent extends BaseButtonToggleGroupClass imple
}

public connectedCallback(): void {
this[setDefaultAria]({ role: 'group' });
this[setDefaultAria]({ role: 'group' }, { setAttribute: !this.hasAttribute('role') });
this._foundation.initialize();
}

Expand Down
6 changes: 3 additions & 3 deletions src/lib/button-toggle/button-toggle.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ describe('Button Toggle', () => {
expect(harness.buttonToggles.every(toggle => toggle.getAttribute('aria-pressed') === 'false')).to.be.true;
});

['primary', 'secondary', 'danger', 'success', 'warning', 'info'].forEach((theme: ButtonToggleGroupTheme) => {
['primary', 'secondary', 'tertiary', 'danger', 'success', 'warning', 'info'].forEach((theme: ButtonToggleGroupTheme) => {
it(`should be accessible with selected values for theme ${theme}`, async () => {
const harness = await createFixture({ theme, value: 'two' });

// Primary is the default
if (theme !== 'primary') {
// tertiary is the default
if (theme !== 'tertiary') {
expect(harness.element.getAttribute(BUTTON_TOGGLE_GROUP_CONSTANTS.attributes.THEME)).to.equal(theme);
}

Expand Down
6 changes: 3 additions & 3 deletions src/lib/button-toggle/button-toggle/button-toggle-adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,20 @@ export class ButtonToggleAdapter extends BaseAdapter<IButtonToggleComponent> imp
}

public initialize(): void {
this._component[setDefaultAria]({ role: 'button' }, { setAttribute: !this._component.hasAttribute('role') });
this._component[setDefaultAria]({
role: 'button',
ariaPressed: `${!!this._component.selected}`,
ariaDisabled: `${!!this._component.disabled}`
});
this._component[isFocusable] = !this._component.disabled;
}

public setSelected(value: boolean): void {
this._component[setDefaultAria]({ ariaPressed: `${!!value}` }, { overwrite: true });
this._component[setDefaultAria]({ ariaPressed: `${!!value}` });
}

public setDisabled(value: boolean): void {
this._component[setDefaultAria]({ ariaDisabled: `${!!value}` }, { overwrite: true });
this._component[setDefaultAria]({ ariaDisabled: `${!!value}` });
this._component[isFocusable] = !value;
this._stateLayerElement.disabled = value;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { COMPONENT_NAME_PREFIX } from '../../constants';
import { supportsElementInternalsAria } from '../../core';
import { ARIAAttribute } from '../../core/utils/a11y-utils';

const elementName: keyof HTMLElementTagNameMap = `${COMPONENT_NAME_PREFIX}button-toggle`;

Expand All @@ -12,8 +10,6 @@ const observedAttributes = {
TABINDEX: 'tabindex' // Need this to support the focusable mixin
};

const observedAriaAttributes: ARIAAttribute[] = supportsElementInternalsAria() ? [] : ['role', 'aria-pressed', 'aria-disabled'];

const attributes = {
...observedAttributes
};
Expand All @@ -25,7 +21,6 @@ const events = {
export const BUTTON_TOGGLE_CONSTANTS = {
elementName,
observedAttributes,
observedAriaAttributes,
attributes,
events
};
Expand Down
9 changes: 7 additions & 2 deletions src/lib/button-toggle/button-toggle/button-toggle.scss
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,13 @@ $_host-tokens: [display];

forge-focus-indicator {
@include focus-indicator.provide-theme((
outward-offset: 0px, // Requires unit
color: #{token(focus-indicator-color)}
outward-offset: #{token(focus-indicator-offset)},
color: #{token(focus-indicator-color)},
shape: #{token(shape)},
shape-start-start: #{token(shape-start-start)},
shape-start-end: #{token(shape-start-end)},
shape-end-start: #{token(shape-end-start)},
shape-end-end: #{token(shape-end-end)},
));
}
}
Expand Down
9 changes: 2 additions & 7 deletions src/lib/button-toggle/button-toggle/button-toggle.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { attachShadowTemplate, coerceBoolean, CustomElement, FoundationProperty } from '@tylertech/forge-core';
import { ExperimentalFocusOptions, observedDefaultAriaAttributes } from '../../constants';
import { ExperimentalFocusOptions } from '../../constants';
import { IWithFocusable, WithFocusable } from '../../core/mixins/focus/with-focusable';
import { IWithElementInternals, WithElementInternals } from '../../core/mixins/internals/with-element-internals';
import { FocusIndicatorComponent } from '../../focus-indicator';
Expand Down Expand Up @@ -95,14 +95,9 @@ const BaseButtonToggleClass = WithDefaultAria(WithElementInternals(WithFocusable
})
export class ButtonToggleComponent<T = unknown> extends BaseButtonToggleClass implements IButtonToggleComponent {
public static get observedAttributes(): string[] {
return [
...Object.values(BUTTON_TOGGLE_CONSTANTS.observedAttributes),
...Object.values(BUTTON_TOGGLE_CONSTANTS.observedAriaAttributes)
];
return Object.values(BUTTON_TOGGLE_CONSTANTS.observedAttributes);
}

public readonly [observedDefaultAriaAttributes] = BUTTON_TOGGLE_CONSTANTS.observedAriaAttributes;

private _foundation: ButtonToggleFoundation;

constructor() {
Expand Down
Loading

0 comments on commit e6d69dc

Please sign in to comment.