Skip to content

chore: Improve ability to override Checkbox and Radio styles#26004

Closed
behowell wants to merge 4 commits intomicrosoft:masterfrom
behowell:checkbox/css-internal-vars
Closed

chore: Improve ability to override Checkbox and Radio styles#26004
behowell wants to merge 4 commits intomicrosoft:masterfrom
behowell:checkbox/css-internal-vars

Conversation

@behowell
Copy link
Contributor

@behowell behowell commented Dec 14, 2022

Previous Behavior

The styles for Checkbox and Radio use complex state and sibling selectors, which can be tricky to override correctly. See #25483 for more details.

New Behavior

For any color set via a selector in Checkbox and Radio, set the value of a CSS variable rather than the CSS property directly. Then in that slot's base styles (no selectors), apply the current value of the CSS variable.

This eliminates any specificity issues when overriding the CSS properties for any given slot. Users can now override the values for any slot using any selector they would like. For example:

const useStyles = makeStyles({
  labelUnchecked: {
    color: tokens.colorPaletteRedForeground1,
  },
  labelChecked: {
    color: tokens.colorPaletteGreenForeground1,
  },
  indicatorUnchecked: {
    backgroundColor: tokens.colorPaletteRedBackground1,
    ...shorthands.borderColor(tokens.colorPaletteRedBorder1),
  },
  indicatorChecked: {
    color: tokens.colorPaletteGreenForeground1,
    backgroundColor: tokens.colorPaletteGreenBackground1,
    ...shorthands.borderColor(tokens.colorPaletteGreenBorder1),
  },
});

export const ColorfulCheckbox = (props: CheckboxProps) => {
  const [checked, setChecked] = useControllableState({
    defaultState: props.defaultChecked,
    state: props.checked,
    initialState: false,
  });

  const styles = useStyles();

  return (
    <Checkbox
      checked={checked}
      onChange={(_ev, data) => setChecked(data.checked)}
      label={resolveShorthand(props.label, {
        required: true,
        defaultProps: { className: mergeClasses(checked ? styles.labelChecked : styles.labelUnchecked) },
      })}
      indicator={resolveShorthand(props.indicator, {
        required: true,
        defaultProps: { className: mergeClasses(checked ? styles.indicatorChecked : styles.indicatorUnchecked) },
      })}
    />
  );
};

image

Related Issue(s)

@behowell behowell self-assigned this Dec 14, 2022
@size-auditor
Copy link

size-auditor bot commented Dec 15, 2022

Asset size changes

⚠️ Insufficient baseline data to detect size changes

Unable to find bundle size details for Baseline commit: a98c062

Possible causes

  • The baseline build a98c062 is broken
  • The Size Auditor run for the baseline build a98c062 was not triggered

Recommendations

  • Please merge your branch for this Pull request with the latest master build and commit your changes once again

@codesandbox-ci
Copy link

codesandbox-ci bot commented Dec 15, 2022

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit fbba566:

Sandbox Source
@fluentui/react 8 starter Configuration
@fluentui/react-components 9 starter Configuration

@fabricteam
Copy link
Collaborator

fabricteam commented Dec 15, 2022

Perf Analysis (@fluentui/react-components)

No significant results to display.

All results

Scenario Render type Master Ticks PR Ticks Iterations Status
Avatar mount 1271 1277 5000
Button mount 909 908 5000
FluentProvider mount 1501 1480 5000
FluentProviderWithTheme mount 575 582 10
FluentProviderWithTheme virtual-rerender 538 548 10
FluentProviderWithTheme virtual-rerender-with-unmount 579 581 10
MakeStyles mount 1972 1946 50000
Persona mount 2785 2814 5000
SpinButton mount 2299 2358 5000

@fabricteam
Copy link
Collaborator

fabricteam commented Dec 15, 2022

📊 Bundle size report

Package & Exports Baseline (minified/GZIP) PR Change
react-checkbox
Checkbox
29.026 kB
9.249 kB
30.21 kB
9.3 kB
1.184 kB
51 B
react-checkbox
CheckboxField
35.455 kB
11.019 kB
36.639 kB
11.066 kB
1.184 kB
47 B
react-radio
Radio
32.247 kB
10.468 kB
34.119 kB
10.644 kB
1.872 kB
176 B
Unchanged fixtures
Package & Exports Size (minified/GZIP)
react-components
react-components: Button, FluentProvider & webLightTheme
59.888 kB
16.652 kB
react-components
react-components: Accordion, Button, FluentProvider, Image, Menu, Popover
187.851 kB
52.699 kB
react-components
react-components: FluentProvider & webLightTheme
34.379 kB
11.322 kB
react-portal-compat
PortalCompatProvider
6.069 kB
2.053 kB
react-radio
RadioGroup
14.718 kB
5.886 kB
react-radio
RadioGroupField
24.024 kB
8.796 kB
🤖 This report was generated against f91f5ed6c5e1a8c5015828da9d1828355c3d9661

@fabricteam
Copy link
Collaborator

fabricteam commented Dec 15, 2022

🕵 fluentuiv9 No visual regressions between this PR and main

@behowell
Copy link
Contributor Author

behowell commented Jan 9, 2023

I made another PR with an alternative way to make styles easier to override. Only one of the two PRs will be merged, pending discussion with interested people:

@behowell
Copy link
Contributor Author

After discussing with the team, we decided to go with #26247 instead.

@behowell behowell closed this Jan 10, 2023
@behowell behowell deleted the checkbox/css-internal-vars branch February 15, 2024 21:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants