Skip to content

Commit

Permalink
chore: Update Switch to use griffel reset styles (#26007)
Browse files Browse the repository at this point in the history
Update the styles to apply base styles with Griffe's makeResetStyles function, which combines all of the base styles into a single class.
  • Loading branch information
behowell authored Jan 10, 2023
1 parent f91f5ed commit 25e3d5b
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 122 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "chore: Update Switch to use griffel reset styles",
"packageName": "@fluentui/react-switch",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { createFocusOutlineStyle } from '@fluentui/react-tabster';
import { tokens } from '@fluentui/react-theme';
import { makeStyles, mergeClasses, shorthands } from '@griffel/react';
import { makeResetStyles, makeStyles, mergeClasses, shorthands } from '@griffel/react';
import type { SlotClassNames } from '@fluentui/react-utilities';
import type { SwitchSlots, SwitchState } from './Switch.types';

Expand All @@ -22,175 +22,172 @@ const trackHeight = 20;
const trackWidth = 40;
const thumbSize = trackHeight - spaceBetweenThumbAndTrack;

const useRootStyles = makeStyles({
base: {
alignItems: 'flex-start',
boxSizing: 'border-box',
display: 'inline-flex',
position: 'relative',
const useRootBaseClassName = makeResetStyles({
alignItems: 'flex-start',
boxSizing: 'border-box',
display: 'inline-flex',
position: 'relative',

...createFocusOutlineStyle({ style: {}, selector: 'focus-within' }),
},
...createFocusOutlineStyle({ style: {}, selector: 'focus-within' }),
});

const useRootStyles = makeStyles({
vertical: {
flexDirection: 'column',
},
});

const useIndicatorStyles = makeStyles({
base: {
...shorthands.borderRadius(tokens.borderRadiusCircular),
...shorthands.borderStyle('solid'),
...shorthands.borderWidth('1px'),
lineHeight: 0,
boxSizing: 'border-box',
fill: 'currentColor',
flexShrink: 0,
fontSize: `${thumbSize}px`,
height: `${trackHeight}px`,
...shorthands.margin(tokens.spacingVerticalS, tokens.spacingHorizontalS),
pointerEvents: 'none',
const useIndicatorBaseClassName = makeResetStyles({
borderRadius: tokens.borderRadiusCircular,
border: '1px solid',
lineHeight: 0,
boxSizing: 'border-box',
fill: 'currentColor',
flexShrink: 0,
fontSize: `${thumbSize}px`,
height: `${trackHeight}px`,
margin: tokens.spacingVerticalS + ' ' + tokens.spacingHorizontalS,
pointerEvents: 'none',
transitionDuration: tokens.durationNormal,
transitionTimingFunction: tokens.curveEasyEase,
transitionProperty: 'background, border, color',
width: `${trackWidth}px`,

'@media screen and (prefers-reduced-motion: reduce)': {
transitionDuration: '0.01ms',
},

'> *': {
transitionDuration: tokens.durationNormal,
transitionTimingFunction: tokens.curveEasyEase,
transitionProperty: 'background, border, color',
width: `${trackWidth}px`,
transitionProperty: 'transform',

'@media screen and (prefers-reduced-motion: reduce)': {
transitionDuration: '0.01ms',
},

'> *': {
transitionDuration: tokens.durationNormal,
transitionTimingFunction: tokens.curveEasyEase,
transitionProperty: 'transform',

'@media screen and (prefers-reduced-motion: reduce)': {
transitionDuration: '0.01ms',
},
},
},
});

const useIndicatorStyles = makeStyles({
labelAbove: {
marginTop: 0,
},
});

const useInputStyles = makeStyles({
base: {
boxSizing: 'border-box',
cursor: 'pointer',
height: '100%',
...shorthands.margin(0),
opacity: 0,
position: 'absolute',
const useInputBaseClassName = makeResetStyles({
boxSizing: 'border-box',
cursor: 'pointer',
height: '100%',
margin: 0,
opacity: 0,
position: 'absolute',

// Calculate the width of the hidden input by taking into account the size of the indicator + the padding around it.
// This is done so that clicking on that "empty space" still toggles the switch.
width: `calc(${trackWidth}px + 2 * ${tokens.spacingHorizontalS})`,

// Checked (both enabled and disabled)
':checked': {
[`& ~ .${switchClassNames.indicator}`]: {
'> *': {
transform: `translateX(${trackWidth - thumbSize - spaceBetweenThumbAndTrack}px)`,
},
},
},

// Calculate the width of the hidden input by taking into account the size of the indicator + the padding around it.
// This is done so that clicking on that "empty space" still toggles the switch.
width: `calc(${trackWidth}px + 2 * ${tokens.spacingHorizontalS})`,
// Disabled (both checked and unchecked)
':disabled': {
cursor: 'default',

// Checked (both enabled and disabled)
':checked': {
[`& ~ .${switchClassNames.indicator}`]: {
'> *': {
transform: `translateX(${trackWidth - thumbSize - spaceBetweenThumbAndTrack}px)`,
},
},
[`& ~ .${switchClassNames.indicator}`]: {
color: tokens.colorNeutralForegroundDisabled,
},

// Disabled (both checked and unchecked)
':disabled': {
[`& ~ .${switchClassNames.label}`]: {
cursor: 'default',
color: tokens.colorNeutralForegroundDisabled,
},
},

[`& ~ .${switchClassNames.indicator}`]: {
color: tokens.colorNeutralForegroundDisabled,
},
// Enabled and unchecked
':enabled:not(:checked)': {
[`& ~ .${switchClassNames.indicator}`]: {
color: tokens.colorNeutralStrokeAccessible,
borderColor: tokens.colorNeutralStrokeAccessible,
},

[`& ~ .${switchClassNames.label}`]: {
cursor: 'default',
color: tokens.colorNeutralForegroundDisabled,
},
[`& ~ .${switchClassNames.label}`]: {
color: tokens.colorNeutralForeground1,
},

// Enabled and unchecked
':enabled:not(:checked)': {
':hover': {
[`& ~ .${switchClassNames.indicator}`]: {
color: tokens.colorNeutralStrokeAccessible,
...shorthands.borderColor(tokens.colorNeutralStrokeAccessible),
},

[`& ~ .${switchClassNames.label}`]: {
color: tokens.colorNeutralForeground1,
color: tokens.colorNeutralStrokeAccessibleHover,
borderColor: tokens.colorNeutralStrokeAccessibleHover,
},
},

':hover': {
[`& ~ .${switchClassNames.indicator}`]: {
color: tokens.colorNeutralStrokeAccessibleHover,
...shorthands.borderColor(tokens.colorNeutralStrokeAccessibleHover),
},
':hover:active': {
[`& ~ .${switchClassNames.indicator}`]: {
color: tokens.colorNeutralStrokeAccessiblePressed,
borderColor: tokens.colorNeutralStrokeAccessiblePressed,
},
},
},

':hover:active': {
[`& ~ .${switchClassNames.indicator}`]: {
color: tokens.colorNeutralStrokeAccessiblePressed,
...shorthands.borderColor(tokens.colorNeutralStrokeAccessiblePressed),
},
},
// Enabled and checked
':enabled:checked': {
[`& ~ .${switchClassNames.indicator}`]: {
backgroundColor: tokens.colorCompoundBrandBackground,
color: tokens.colorNeutralForegroundInverted,
borderColor: tokens.colorTransparentStroke,
},

// Enabled and checked
':enabled:checked': {
':hover': {
[`& ~ .${switchClassNames.indicator}`]: {
backgroundColor: tokens.colorCompoundBrandBackground,
color: tokens.colorNeutralForegroundInverted,
...shorthands.borderColor(tokens.colorTransparentStroke),
backgroundColor: tokens.colorCompoundBrandBackgroundHover,
borderColor: tokens.colorTransparentStrokeInteractive,
},
},

':hover': {
[`& ~ .${switchClassNames.indicator}`]: {
backgroundColor: tokens.colorCompoundBrandBackgroundHover,
...shorthands.borderColor(tokens.colorTransparentStrokeInteractive),
},
':hover:active': {
[`& ~ .${switchClassNames.indicator}`]: {
backgroundColor: tokens.colorCompoundBrandBackgroundPressed,
borderColor: tokens.colorTransparentStrokeInteractive,
},
},
},

':hover:active': {
[`& ~ .${switchClassNames.indicator}`]: {
backgroundColor: tokens.colorCompoundBrandBackgroundPressed,
...shorthands.borderColor(tokens.colorTransparentStrokeInteractive),
},
},
// Disabled and unchecked
':disabled:not(:checked)': {
[`& ~ .${switchClassNames.indicator}`]: {
borderColor: tokens.colorNeutralStrokeDisabled,
},
},

// Disabled and unchecked
':disabled:not(:checked)': {
[`& ~ .${switchClassNames.indicator}`]: {
...shorthands.borderColor(tokens.colorNeutralStrokeDisabled),
},
// Disabled and checked
':disabled:checked': {
[`& ~ .${switchClassNames.indicator}`]: {
backgroundColor: tokens.colorNeutralBackgroundDisabled,
borderColor: tokens.colorTransparentStrokeDisabled,
},
},

// Disabled and checked
':disabled:checked': {
'@media (forced-colors: active)': {
':disabled': {
[`& ~ .${switchClassNames.indicator}`]: {
backgroundColor: tokens.colorNeutralBackgroundDisabled,
...shorthands.borderColor(tokens.colorTransparentStrokeDisabled),
color: 'GrayText',
borderColor: 'GrayText',
},
},
},

highContrast: {
'@media (forced-colors: active)': {
':disabled': {
[`& ~ .${switchClassNames.indicator}`]: {
color: 'GrayText',
...shorthands.borderColor('GrayText'),
},

[`& ~ .${switchClassNames.label}`]: {
color: 'GrayText',
},
[`& ~ .${switchClassNames.label}`]: {
color: 'GrayText',
},
},
},
});

const useInputStyles = makeStyles({
before: {
right: 0,
top: 0,
Expand All @@ -206,6 +203,7 @@ const useInputStyles = makeStyles({
},
});

// Can't use makeResetStyles here because Label is a component that may itself use makeResetStyles.
const useLabelStyles = makeStyles({
base: {
cursor: 'pointer',
Expand Down Expand Up @@ -234,31 +232,33 @@ const useLabelStyles = makeStyles({
* Apply styling to the Switch slots based on the state
*/
export const useSwitchStyles_unstable = (state: SwitchState): SwitchState => {
const rootBaseClassName = useRootBaseClassName();
const rootStyles = useRootStyles();
const indicatorBaseClassName = useIndicatorBaseClassName();
const indicatorStyles = useIndicatorStyles();
const inputBaseClassName = useInputBaseClassName();
const inputStyles = useInputStyles();
const labelStyles = useLabelStyles();

const { label, labelPosition } = state;

state.root.className = mergeClasses(
switchClassNames.root,
rootStyles.base,
rootBaseClassName,
labelPosition === 'above' && rootStyles.vertical,
state.root.className,
);

state.indicator.className = mergeClasses(
switchClassNames.indicator,
indicatorStyles.base,
indicatorBaseClassName,
label && labelPosition === 'above' && indicatorStyles.labelAbove,
state.indicator.className,
);

state.input.className = mergeClasses(
switchClassNames.input,
inputStyles.base,
inputStyles.highContrast,
inputBaseClassName,
label && inputStyles[labelPosition],
state.input.className,
);
Expand Down

0 comments on commit 25e3d5b

Please sign in to comment.