Skip to content

Commit

Permalink
fix(web-components): fix disabled button styles (#31585)
Browse files Browse the repository at this point in the history
Co-authored-by: Chris Holt <13071055+chrisdholt@users.noreply.github.com>
  • Loading branch information
davatron5000 and chrisdholt authored Jun 5, 2024
1 parent 84bf9cc commit 5987b68
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 36 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "prerelease",
"comment": "fix disabled button styles",
"packageName": "@fluentui/web-components",
"email": "rupertdavid@microsoft.com",
"dependentChangeType": "patch"
}
58 changes: 50 additions & 8 deletions packages/web-components/src/button/button.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,14 +104,35 @@ test.describe('Button', () => {
await expect(element).not.toBeFocused();
});

test('should have transparent border when the `disabled` attribute is present', async ({ page }) => {
test('should apply transparency correctly when the `disabled` attribute is present', async ({ page }) => {
const element = page.locator('fluent-button');

const transparent = 'rgba(0, 0, 0, 0)';
await page.setContent(/* html */ `
<fluent-button appearance='primary' disabled>Button</fluent-button>
<fluent-button disabled>Button</fluent-button>
`);

await expect(element).toHaveCSS('border-color', 'rgb(0, 0, 0)');
await expect(element).not.toHaveCSS('border-color', transparent);
await expect(element).not.toHaveCSS('background-color', transparent);

await element.evaluate(node => node.setAttribute('appearance', 'primary'));
await expect(element).toHaveCSS('border-color', transparent);
await expect(element).not.toHaveCSS('background-color', transparent);

await element.evaluate(node => node.setAttribute('appearance', 'secondary'));
await expect(element).not.toHaveCSS('border-color', transparent);
await expect(element).not.toHaveCSS('background-color', transparent);

await element.evaluate(node => node.setAttribute('appearance', 'outline'));
await expect(element).not.toHaveCSS('border-color', transparent);
await expect(element).toHaveCSS('background-color', transparent);

await element.evaluate(node => node.setAttribute('appearance', 'subtle'));
await expect(element).toHaveCSS('border-color', transparent);
await expect(element).toHaveCSS('background-color', transparent);

await element.evaluate(node => node.setAttribute('appearance', 'transparent'));
await expect(element).toHaveCSS('border-color', transparent);
await expect(element).toHaveCSS('background-color', transparent);
});

test('should be focusable when the `disabled-focusable` attribute is present', async ({ page }) => {
Expand All @@ -126,14 +147,35 @@ test.describe('Button', () => {
await expect(element).toBeFocused();
});

test('should have transparent border when the `disabled-focusable` attribute is present', async ({ page }) => {
test('should apply transparency correctly when the `disabled-focusable` attribute is present', async ({ page }) => {
const element = page.locator('fluent-button');

const transparent = 'rgba(0, 0, 0, 0)';
await page.setContent(/* html */ `
<fluent-button appearance='primary' disabled-focusable>Button</fluent-button>
<fluent-button disabled-focusable>Button</fluent-button>
`);

await expect(element).toHaveCSS('border-color', 'rgb(0, 0, 0)');
await expect(element).not.toHaveCSS('border-color', transparent);
await expect(element).not.toHaveCSS('background-color', transparent);

await element.evaluate(node => node.setAttribute('appearance', 'primary'));
await expect(element).toHaveCSS('border-color', transparent);
await expect(element).not.toHaveCSS('background-color', transparent);

await element.evaluate(node => node.setAttribute('appearance', 'secondary'));
await expect(element).not.toHaveCSS('border-color', transparent);
await expect(element).not.toHaveCSS('background-color', transparent);

await element.evaluate(node => node.setAttribute('appearance', 'outline'));
await expect(element).not.toHaveCSS('border-color', transparent);
await expect(element).toHaveCSS('background-color', transparent);

await element.evaluate(node => node.setAttribute('appearance', 'subtle'));
await expect(element).toHaveCSS('border-color', transparent);
await expect(element).toHaveCSS('background-color', transparent);

await element.evaluate(node => node.setAttribute('appearance', 'transparent'));
await expect(element).toHaveCSS('border-color', transparent);
await expect(element).toHaveCSS('background-color', transparent);
});

test('should NOT be clickable when the `disabled` attribute is present', async ({ page }) => {
Expand Down
54 changes: 27 additions & 27 deletions packages/web-components/src/button/button.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ export const styles = css`
:host(:focus-visible) {
border-color: ${colorTransparentStroke};
outline: ${strokeWidthThick}) solid ${colorTransparentStroke};
outline: ${strokeWidthThick} solid ${colorTransparentStroke};
box-shadow: ${shadow4}, 0 0 0 2px ${colorStrokeFocus2};
}
Expand Down Expand Up @@ -213,12 +213,6 @@ export const styles = css`
box-shadow: ${shadow2}, 0 0 0 2px ${colorStrokeFocus2};
}
:host(:is([disabled][appearance='primary'], [disabled-focusabale][appearance='primary'])),
:host(:is([disabled][appearance='primary'], [disabled-focusabale][appearance='primary']):hover),
:host(:is([disabled][appearance='primary'], [disabled-focusabale][appearance='primary']):hover:active) {
border-color: transparent;
}
:host([appearance='outline']) {
background-color: ${colorTransparentBackground};
}
Expand All @@ -231,12 +225,6 @@ export const styles = css`
background-color: ${colorTransparentBackgroundPressed};
}
:host(:is([disabled][appearance='outline'], [disabled-focusabale][appearance='outline'])),
:host(:is([disabled][appearance='outline'], [disabled-focusabale][appearance='outline']):hover),
:host(:is([disabled][appearance='outline'], [disabled-focusabale][appearance='outline']):hover:active) {
background-color: ${colorTransparentBackground};
}
:host([appearance='subtle']) {
background-color: ${colorSubtleBackground};
color: ${colorNeutralForeground2};
Expand All @@ -255,13 +243,6 @@ export const styles = css`
border-color: transparent;
}
:host(:is([disabled][appearance='subtle'], [disabled-focusabale][appearance='subtle'])),
:host(:is([disabled][appearance='subtle'], [disabled-focusabale][appearance='subtle']):hover),
:host(:is([disabled][appearance='subtle'], [disabled-focusabale][appearance='subtle']):hover:active) {
background-color: ${colorTransparentBackground};
border-color: transparent;
}
:host([appearance='subtle']:hover) ::slotted(svg) {
fill: ${colorNeutralForeground2BrandHover};
}
Expand Down Expand Up @@ -291,13 +272,6 @@ export const styles = css`
border-color: transparent;
}
:host(:is([disabled][appearance='transparent'], [disabled-focusabale][appearance='transparent'])),
:host(:is([disabled][appearance='transparent'], [disabled-focusabale][appearance='transparent']):hover),
:host(:is([disabled][appearance='transparent'], [disabled-focusabale][appearance='transparent']):hover:active) {
border-color: transparent;
background-color: ${colorTransparentBackground};
}
:host(:is([disabled], [disabled-focusable], [appearance][disabled], [appearance][disabled-focusable])),
:host(:is([disabled], [disabled-focusable], [appearance][disabled], [appearance][disabled-focusable]):hover),
:host(:is([disabled], [disabled-focusable], [appearance][disabled], [appearance][disabled-focusable]):hover:active) {
Expand All @@ -306,6 +280,32 @@ export const styles = css`
color: ${colorNeutralForegroundDisabled};
cursor: not-allowed;
}
:host(:is([disabled][appearance='primary'], [disabled-focusable][appearance='primary'])),
:host(:is([disabled][appearance='primary'], [disabled-focusable][appearance='primary']):hover),
:host(:is([disabled][appearance='primary'], [disabled-focusable][appearance='primary']):hover:active) {
border-color: transparent;
}
:host(:is([disabled][appearance='outline'], [disabled-focusable][appearance='outline'])),
:host(:is([disabled][appearance='outline'], [disabled-focusable][appearance='outline']):hover),
:host(:is([disabled][appearance='outline'], [disabled-focusable][appearance='outline']):hover:active) {
background-color: ${colorTransparentBackground};
}
:host(:is([disabled][appearance='subtle'], [disabled-focusable][appearance='subtle'])),
:host(:is([disabled][appearance='subtle'], [disabled-focusable][appearance='subtle']):hover),
:host(:is([disabled][appearance='subtle'], [disabled-focusable][appearance='subtle']):hover:active) {
background-color: ${colorTransparentBackground};
border-color: transparent;
}
:host(:is([disabled][appearance='transparent'], [disabled-focusable][appearance='transparent'])),
:host(:is([disabled][appearance='transparent'], [disabled-focusable][appearance='transparent']):hover),
:host(:is([disabled][appearance='transparent'], [disabled-focusable][appearance='transparent']):hover:active) {
border-color: transparent;
background-color: ${colorTransparentBackground};
}
`.withBehaviors(
forcedColorsStylesheetBehavior(css`
:host([appearance='transparent']:hover) {
Expand Down
10 changes: 9 additions & 1 deletion packages/web-components/src/theme/set-theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,15 @@ const tokenNames = Object.keys(tokens) as (keyof Theme)[];
*/
export const setTheme = (theme: Theme) => {
for (const t of tokenNames) {
document.body.style.setProperty(`--${t}`, theme[t] as string);
if ('registerProperty' in CSS) {
CSS.registerProperty({
name: `--${t}`,
inherits: true,
initialValue: theme[t] as string,
});
} else {
document.body.style.setProperty(`--${t}`, theme[t] as string);
}
}
};

Expand Down

0 comments on commit 5987b68

Please sign in to comment.