Skip to content

Commit

Permalink
[utils] Allow state prefix to be configurable (#32972)
Browse files Browse the repository at this point in the history
  • Loading branch information
siriwatknp committed Jun 23, 2022
1 parent ed7972b commit aac7888
Show file tree
Hide file tree
Showing 41 changed files with 79 additions and 62 deletions.
2 changes: 1 addition & 1 deletion packages/mui-joy/src/AspectRatio/aspectRatioClasses.ts
@@ -1,4 +1,4 @@
import { generateUtilityClass, generateUtilityClasses } from '@mui/base';
import { generateUtilityClass, generateUtilityClasses } from '../className';

export interface AspectRatioClasses {
/** Styles applied to the root element. */
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-joy/src/Avatar/avatarClasses.ts
@@ -1,4 +1,4 @@
import { generateUtilityClass, generateUtilityClasses } from '@mui/base';
import { generateUtilityClass, generateUtilityClasses } from '../className';

export interface AvatarClasses {
/** Styles applied to the root element. */
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-joy/src/AvatarGroup/avatarGroupClasses.ts
@@ -1,4 +1,4 @@
import { generateUtilityClass, generateUtilityClasses } from '@mui/base';
import { generateUtilityClass, generateUtilityClasses } from '../className';

export interface AvatarGroupClasses {
/** Styles applied to the root element. */
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-joy/src/Badge/badgeClasses.ts
@@ -1,4 +1,4 @@
import { generateUtilityClass, generateUtilityClasses } from '@mui/base';
import { generateUtilityClass, generateUtilityClasses } from '../className';

export interface BadgeClasses {
/** Class name applied to the root element. */
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-joy/src/Button/buttonClasses.ts
@@ -1,4 +1,4 @@
import { generateUtilityClass, generateUtilityClasses } from '@mui/base';
import { generateUtilityClass, generateUtilityClasses } from '../className';

export interface ButtonClasses {
/** Styles applied to the root element. */
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-joy/src/Card/cardClasses.ts
@@ -1,4 +1,4 @@
import { generateUtilityClass, generateUtilityClasses } from '@mui/base';
import { generateUtilityClass, generateUtilityClasses } from '../className';

export interface CardClasses {
/** Styles applied to the root element. */
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-joy/src/CardContent/cardContentClasses.ts
@@ -1,4 +1,4 @@
import { generateUtilityClass, generateUtilityClasses } from '@mui/base';
import { generateUtilityClass, generateUtilityClasses } from '../className';

export interface CardContentClasses {
/** Styles applied to the root element. */
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-joy/src/CardCover/cardCoverClasses.ts
@@ -1,4 +1,4 @@
import { generateUtilityClass, generateUtilityClasses } from '@mui/base';
import { generateUtilityClass, generateUtilityClasses } from '../className';

export interface CardCoverClasses {
/** Styles applied to the root element. */
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-joy/src/CardOverflow/cardOverflowClasses.ts
@@ -1,4 +1,4 @@
import { generateUtilityClass, generateUtilityClasses } from '@mui/base';
import { generateUtilityClass, generateUtilityClasses } from '../className';

export interface CardOverflowClasses {
/** Styles applied to the root element. */
Expand Down
4 changes: 2 additions & 2 deletions packages/mui-joy/src/Checkbox/Checkbox.tsx
Expand Up @@ -59,12 +59,12 @@ const CheckboxRoot = styled('span', {
display: 'inline-flex',
fontFamily: theme.vars.fontFamily.body,
lineHeight: 'var(--Checkbox-size)', // prevent label from having larger height than the checkbox
'&.Mui-disabled': {
[`&.${checkboxClasses.disabled}`]: {
color: theme.vars.palette[ownerState.color!]?.plainDisabledColor,
},
...(ownerState.disableIcon && {
color: theme.vars.palette[ownerState.color!]?.[`${ownerState.variant!}Color`],
'&.Mui-disabled': {
[`&.${checkboxClasses.disabled}`]: {
color: theme.vars.palette[ownerState.color!]?.[`${ownerState.variant!}DisabledColor`],
},
}),
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-joy/src/Checkbox/checkboxClasses.ts
@@ -1,4 +1,4 @@
import { generateUtilityClass, generateUtilityClasses } from '@mui/base';
import { generateUtilityClass, generateUtilityClasses } from '../className';

export interface CheckboxClasses {
/** Styles applied to the root element. */
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-joy/src/Chip/chipClasses.ts
@@ -1,4 +1,4 @@
import { generateUtilityClass, generateUtilityClasses } from '@mui/base';
import { generateUtilityClass, generateUtilityClasses } from '../className';

export interface ChipClasses {
/** Styles applied to the root element. */
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-joy/src/ChipDelete/chipDeleteClasses.ts
@@ -1,4 +1,4 @@
import { generateUtilityClass, generateUtilityClasses } from '@mui/base';
import { generateUtilityClass, generateUtilityClasses } from '../className';

export interface ChipDeleteClasses {
/** Styles applied to the root element. */
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-joy/src/Container/containerClasses.ts
@@ -1,5 +1,5 @@
import { generateUtilityClass, generateUtilityClasses } from '@mui/base';
import { ContainerClasses } from '@mui/system';
import { generateUtilityClass, generateUtilityClasses } from '../className';

export type { ContainerClassKey } from '@mui/system';
export type { ContainerClasses };
Expand Down
@@ -1,4 +1,4 @@
import { generateUtilityClass, generateUtilityClasses } from '@mui/base';
import { generateUtilityClass, generateUtilityClasses } from '../className';

export interface FormHelperTextClasses {
/** Styles applied to the root element. */
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-joy/src/FormLabel/formLabelClasses.ts
@@ -1,4 +1,4 @@
import { generateUtilityClass, generateUtilityClasses } from '@mui/base';
import { generateUtilityClass, generateUtilityClasses } from '../className';

export interface FormLabelClasses {
/** Styles applied to the root element. */
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-joy/src/IconButton/iconButtonClasses.ts
@@ -1,4 +1,4 @@
import { generateUtilityClass, generateUtilityClasses } from '@mui/base';
import { generateUtilityClass, generateUtilityClasses } from '../className';

export interface IconButtonClasses {
/** Styles applied to the root element. */
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-joy/src/Input/inputClasses.ts
@@ -1,4 +1,4 @@
import { generateUtilityClass, generateUtilityClasses } from '@mui/base';
import { generateUtilityClass, generateUtilityClasses } from '../className';

export interface InputClasses {
/** Styles applied to the root element. */
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-joy/src/Link/Link.tsx
Expand Up @@ -103,7 +103,7 @@ const LinkRoot = styled('a', {
: {
color: `rgba(${theme.vars.palette[ownerState.color!]?.mainChannel} / 1)`,
cursor: 'pointer',
'&.Mui-disabled': {
[`&.${linkClasses.disabled}`]: {
pointerEvents: 'none',
color: `rgba(${theme.vars.palette[ownerState.color!]?.mainChannel} / 0.6)`,
},
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-joy/src/Link/linkClasses.ts
@@ -1,4 +1,4 @@
import { generateUtilityClass, generateUtilityClasses } from '@mui/base';
import { generateUtilityClass, generateUtilityClasses } from '../className';

export interface LinkClasses {
/** Styles applied to the root element. */
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-joy/src/List/listClasses.ts
@@ -1,4 +1,4 @@
import { generateUtilityClass, generateUtilityClasses } from '@mui/base';
import { generateUtilityClass, generateUtilityClasses } from '../className';

export interface ListClasses {
/** Styles applied to the root element. */
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-joy/src/ListDivider/listDividerClasses.ts
@@ -1,4 +1,4 @@
import { generateUtilityClass, generateUtilityClasses } from '@mui/base';
import { generateUtilityClass, generateUtilityClasses } from '../className';

export interface ListDividerClasses {
/** Styles applied to the root element. */
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-joy/src/ListItem/listItemClasses.ts
@@ -1,4 +1,4 @@
import { generateUtilityClass, generateUtilityClasses } from '@mui/base';
import { generateUtilityClass, generateUtilityClasses } from '../className';

export interface ListItemClasses {
/** Styles applied to the root element. */
Expand Down
@@ -1,4 +1,4 @@
import { generateUtilityClass, generateUtilityClasses } from '@mui/base';
import { generateUtilityClass, generateUtilityClasses } from '../className';

export interface ListItemButtonClasses {
/** Styles applied to the root element. */
Expand Down
@@ -1,4 +1,4 @@
import { generateUtilityClass, generateUtilityClasses } from '@mui/base';
import { generateUtilityClass, generateUtilityClasses } from '../className';

export interface ListItemContentClasses {
/** Styles applied to the root element. */
Expand Down
@@ -1,4 +1,4 @@
import { generateUtilityClass, generateUtilityClasses } from '@mui/base';
import { generateUtilityClass, generateUtilityClasses } from '../className';

export interface ListItemDecoratorClasses {
/** Styles applied to the root element. */
Expand Down
4 changes: 2 additions & 2 deletions packages/mui-joy/src/Radio/Radio.tsx
Expand Up @@ -71,12 +71,12 @@ const RadioRoot = styled('span', {
minWidth: 0,
fontFamily: theme.vars.fontFamily.body,
lineHeight: 'var(--Radio-size)', // prevent label from having larger height than the checkbox
'&.Mui-disabled': {
[`&.${radioClasses.disabled}`]: {
color: theme.vars.palette[ownerState.color!]?.plainDisabledColor,
},
...(ownerState.disableIcon && {
color: theme.vars.palette[ownerState.color!]?.[`${ownerState.variant!}Color`],
'&.Mui-disabled': {
[`&.${radioClasses.disabled}`]: {
color: theme.vars.palette[ownerState.color!]?.[`${ownerState.variant!}DisabledColor`],
},
}),
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-joy/src/Radio/radioClasses.ts
@@ -1,4 +1,4 @@
import { generateUtilityClass, generateUtilityClasses } from '@mui/base';
import { generateUtilityClass, generateUtilityClasses } from '../className';

export interface RadioClasses {
/** Styles applied to the root element. */
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-joy/src/RadioGroup/radioGroupClasses.ts
@@ -1,4 +1,4 @@
import { generateUtilityClass, generateUtilityClasses } from '@mui/base';
import { generateUtilityClass, generateUtilityClasses } from '../className';

export interface RadioGroupClasses {
/** Styles applied to the root element. */
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-joy/src/Sheet/sheetClasses.ts
@@ -1,4 +1,4 @@
import { generateUtilityClass, generateUtilityClasses } from '@mui/base';
import { generateUtilityClass, generateUtilityClasses } from '../className';

export interface SheetClasses {
/** Styles applied to the root element. */
Expand Down
10 changes: 8 additions & 2 deletions packages/mui-joy/src/Slider/Slider.tsx
Expand Up @@ -604,7 +604,10 @@ Slider.propTypes /* remove-proptypes */ = {
* The color of the component. It supports those theme colors that make sense for this component.
* @default 'primary'
*/
color: PropTypes.oneOf(['danger', 'info', 'neutral', 'primary', 'success', 'warning']),
color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([
PropTypes.oneOf(['danger', 'info', 'neutral', 'primary', 'success', 'warning']),
PropTypes.string,
]),
/**
* The component used for the root node.
* Either a string to use a HTML element or a component.
Expand Down Expand Up @@ -735,7 +738,10 @@ Slider.propTypes /* remove-proptypes */ = {
* It accepts theme values between 'sm' and 'lg'.
* @default 'md'
*/
size: PropTypes.oneOf(['sm', 'md', 'lg']),
size: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([
PropTypes.oneOf(['sm', 'md', 'lg']),
PropTypes.string,
]),
/**
* The granularity with which the slider can step through values. (A "discrete" slider.)
* The `min` prop serves as the origin for the valid values.
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-joy/src/Slider/sliderClasses.ts
@@ -1,4 +1,4 @@
import { generateUtilityClass, generateUtilityClasses } from '@mui/base';
import { generateUtilityClass, generateUtilityClasses } from '../className';

export interface SliderClasses {
/** Class name applied to the root element. */
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-joy/src/SvgIcon/svgIconClasses.ts
@@ -1,4 +1,4 @@
import { generateUtilityClass, generateUtilityClasses } from '@mui/base';
import { generateUtilityClass, generateUtilityClasses } from '../className';

export interface SvgIconClasses {
/** Styles applied to the root element. */
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-joy/src/Switch/switchClasses.ts
@@ -1,4 +1,4 @@
import { generateUtilityClass, generateUtilityClasses } from '@mui/base';
import { generateUtilityClass, generateUtilityClasses } from '../className';

export interface SwitchClasses {
/** Styles applied to the root element. */
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-joy/src/TextField/textFieldClasses.ts
@@ -1,4 +1,4 @@
import { generateUtilityClass, generateUtilityClasses } from '@mui/base';
import { generateUtilityClass, generateUtilityClasses } from '../className';

export interface TextFieldClasses {
/** Styles applied to the root element. */
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-joy/src/Typography/typographyClasses.ts
@@ -1,4 +1,4 @@
import { generateUtilityClass, generateUtilityClasses } from '@mui/base';
import { generateUtilityClass, generateUtilityClasses } from '../className';

export interface TypographyClasses {
/** Styles applied to the root element. */
Expand Down
17 changes: 8 additions & 9 deletions packages/mui-joy/src/className/index.ts
@@ -1,10 +1,9 @@
/**
* Caution! this module must not include unstyled components import from `@mui/base`, otherwise, it will break the ClassNameGenerator.
* ❌ import { ... } from '@mui/base';
* ✅ import { ... } from '@mui/base/utils'; // must be specific base module
*
* Issue: https://github.com/mui/material-ui/issues/30011#issuecomment-1024993401
*/
import { unstable_generateUtilityClass, unstable_generateUtilityClasses } from '@mui/utils';

// eslint-disable-next-line import/prefer-default-export
export { unstable_ClassNameGenerator } from '@mui/base/className';
export { unstable_ClassNameGenerator } from '@mui/utils';

export const generateUtilityClass = (componentName: string, slot: string) =>
unstable_generateUtilityClass(componentName, slot, 'Joy');

export const generateUtilityClasses = <T extends string>(componentName: string, slots: Array<T>) =>
unstable_generateUtilityClasses(componentName, slots, 'Joy');
3 changes: 2 additions & 1 deletion packages/mui-joy/src/styles/extendTheme.ts
Expand Up @@ -16,6 +16,7 @@ import { TypographySystem, FontSize } from './types/typography';
import { Variants } from './types/variants';
import { Theme, ThemeCSSVar, ThemeScales } from './types';
import { Components } from './components';
import { generateUtilityClass } from '../className';

type CSSProperties = CSS.Properties<number | string>;

Expand Down Expand Up @@ -360,7 +361,7 @@ export default function extendTheme(themeInput?: ThemeInput): Theme {
xl3: 900,
},
focus: {
selector: '&.Mui-focusVisible, &:focus-visible',
selector: `&.${generateUtilityClass('', 'focusVisible')}, &:focus-visible`,
default: {
outlineOffset: 'var(--joy-focus-outlineOffset, 0px)', // reset user agent stylesheet
outline: '4px solid var(--joy-palette-focusVisible)',
Expand Down
Expand Up @@ -48,4 +48,8 @@ describe('generateUtilityClass', () => {
expect(generateUtilityClass('MuiTest', 'selected')).to.equal('Mui-selected');
});
});

it('custom state prefix', () => {
expect(generateUtilityClass('JoyButton', 'focusVisible', 'Joy')).to.equal('Joy-focusVisible');
});
});
30 changes: 18 additions & 12 deletions packages/mui-utils/src/generateUtilityClass/generateUtilityClass.ts
Expand Up @@ -13,19 +13,25 @@ export type GlobalStateSlot =
| 'selected';

const globalStateClassesMapping: Record<GlobalStateSlot, string> = {
active: 'Mui-active',
checked: 'Mui-checked',
completed: 'Mui-completed',
disabled: 'Mui-disabled',
error: 'Mui-error',
expanded: 'Mui-expanded',
focused: 'Mui-focused',
focusVisible: 'Mui-focusVisible',
required: 'Mui-required',
selected: 'Mui-selected',
active: 'active',
checked: 'checked',
completed: 'completed',
disabled: 'disabled',
error: 'error',
expanded: 'expanded',
focused: 'focused',
focusVisible: 'focusVisible',
required: 'required',
selected: 'selected',
};

export default function generateUtilityClass(componentName: string, slot: string): string {
export default function generateUtilityClass(
componentName: string,
slot: string,
globalStatePrefix = 'Mui',
): string {
const globalStateClass = globalStateClassesMapping[slot as GlobalStateSlot];
return globalStateClass || `${ClassNameGenerator.generate(componentName)}-${slot}`;
return globalStateClass
? `${globalStatePrefix}-${globalStateClass}`
: `${ClassNameGenerator.generate(componentName)}-${slot}`;
}
Expand Up @@ -3,11 +3,12 @@ import generateUtilityClass from '../generateUtilityClass';
export default function generateUtilityClasses<T extends string>(
componentName: string,
slots: T[],
globalStatePrefix = 'Mui',
): Record<T, string> {
const result: Record<string, string> = {};

slots.forEach((slot) => {
result[slot] = generateUtilityClass(componentName, slot);
result[slot] = generateUtilityClass(componentName, slot, globalStatePrefix);
});

return result;
Expand Down

0 comments on commit aac7888

Please sign in to comment.