Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Joy] Add default color to Input and ListItemButton #31826

Merged
merged 13 commits into from
Mar 16, 2022
4 changes: 2 additions & 2 deletions docs/pages/experiments/joy/list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ function MuiNav() {
})
}
>
<ListItemDecorator>
<ListItemDecorator sx={{ color: 'primary.textColor' }}>
<IconComponent fontSize="md" />
</ListItemDecorator>
<ListItemContent sx={{ color: 'text.primary' }}>
Expand Down Expand Up @@ -593,7 +593,7 @@ const Gatsby = () => {
'--joy-palette-neutral-textActiveBg': 'transparent',
'--joy-palette-primary-textHoverBg': 'transparent',
'--joy-palette-primary-textActiveBg': 'transparent',
'[data-mui-color-scheme="light"] &': {
'[data-mui-color-scheme="dark"] &': {
'--joy-palette-text-secondary': '#635e69',
'--joy-palette-primary-textColor': '#d48cff',
},
Expand Down
2 changes: 1 addition & 1 deletion docs/pages/experiments/joy/sheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export default function JoySheet() {
return (
<CssVarsProvider>
<GlobalStyles
styles={{ body: { backgroundColor: 'var(--joy-palette-background-level2)' } }}
styles={{ body: { backgroundColor: 'var(--joy-palette-background-level1)' } }}
/>
<Box sx={{ py: 5, maxWidth: { md: 1152, xl: 1536 }, mx: 'auto' }}>
<Box sx={{ px: 3, pb: 4 }}>
Expand Down
4 changes: 2 additions & 2 deletions packages/mui-joy/src/Avatar/Avatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ const Avatar = React.forwardRef(function Avatar(inProps, ref) {
color = 'neutral',
component = 'div',
size = 'md',
variant = 'contained',
variant = 'light',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason for this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One intention of the global variant is to bring attention. Currently contained brings the most attention and text be the last. My feeling is that Avatar is a complimentary UI, so it should not be contained by default.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gottcha gottcha!

imgProps,
src,
srcSet,
Expand Down Expand Up @@ -250,7 +250,7 @@ Avatar.propTypes /* remove-proptypes */ = {
srcSet: PropTypes.string,
/**
* The variant to use.
* @default 'contained'
* @default 'light'
*/
variant: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([
PropTypes.oneOf(['contained', 'light', 'outlined', 'text']),
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-joy/src/Avatar/AvatarProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export interface AvatarTypeMap<P = {}, D extends React.ElementType = 'div'> {
sx?: SxProps;
/**
* The variant to use.
* @default 'contained'
* @default 'light'
*/
variant?: OverridableStringUnion<Exclude<VariantProp, 'text'>, AvatarPropsVariantOverrides>;
};
Expand Down
4 changes: 2 additions & 2 deletions packages/mui-joy/src/Button/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { useButton } from '@mui/base/ButtonUnstyled';
import composeClasses from '@mui/base/composeClasses';
import { styled, useThemeProps } from '../styles';
import { ExtendButton, ButtonTypeMap, ButtonProps } from './ButtonProps';
import buttonClasses, { getButtonUtilityClass } from './buttonClasses';
import { getButtonUtilityClass } from './buttonClasses';

const useUtilityClasses = (ownerState: ButtonProps & { focusVisible: boolean }) => {
const { color, disabled, focusVisible, focusVisibleClassName, fullWidth, size, variant } =
Expand Down Expand Up @@ -104,11 +104,11 @@ const ButtonRoot = styled('button', {
lineHeight: '1.25rem',
}),
...(ownerState.size === 'lg' && theme.typography.h6),
[`&.${buttonClasses.focusVisible}`]: theme.focus.default,
},
ownerState.fullWidth && {
width: '100%',
},
theme.focus.default,
theme.variants[ownerState.variant!]?.[ownerState.color!],
theme.variants[`${ownerState.variant!}Hover`]?.[ownerState.color!],
theme.variants[`${ownerState.variant!}Active`]?.[ownerState.color!],
Expand Down
4 changes: 2 additions & 2 deletions packages/mui-joy/src/Checkbox/Checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { unstable_capitalize as capitalize } from '@mui/utils';
import { unstable_composeClasses as composeClasses } from '@mui/base';
import { useSwitch } from '@mui/base/SwitchUnstyled';
import { styled, useThemeProps } from '../styles';
import checkboxClasses, { getCheckboxUtilityClass } from './checkboxClasses';
import { getCheckboxUtilityClass } from './checkboxClasses';
import { CheckboxProps, CheckboxTypeMap } from './CheckboxProps';
import CheckIcon from '../internal/svg-icons/Check';
import IndeterminateIcon from '../internal/svg-icons/HorizontalRule';
Expand Down Expand Up @@ -56,8 +56,8 @@ const CheckboxRoot = styled('span', {
justifyContent: 'center',
alignItems: 'center',
verticalAlign: 'middle',
[`&.${checkboxClasses.focusVisible}`]: theme.focus.default,
},
theme.focus.default,
theme.variants[ownerState.variant!]?.[ownerState.color!],
theme.variants[`${ownerState.variant!}Hover`]?.[ownerState.color!],
theme.variants[`${ownerState.variant!}Active`]?.[ownerState.color!],
Expand Down
4 changes: 2 additions & 2 deletions packages/mui-joy/src/IconButton/IconButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { unstable_capitalize as capitalize, unstable_useForkRef as useForkRef }
import { useButton } from '@mui/base/ButtonUnstyled';
import composeClasses from '@mui/base/composeClasses';
import { styled, useThemeProps } from '../styles';
import iconButtonClasses, { getIconButtonUtilityClass } from './iconButtonClasses';
import { getIconButtonUtilityClass } from './iconButtonClasses';
import { IconButtonProps, IconButtonTypeMap, ExtendIconButton } from './IconButtonProps';

const useUtilityClasses = (ownerState: IconButtonProps & { focusVisible: boolean }) => {
Expand Down Expand Up @@ -67,8 +67,8 @@ const IconButtonRoot = styled('button', {
// TODO: discuss the transition approach in a separate PR. This value is copied from mui-material Button.
transition:
'background-color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, border-color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms',
[`&.${iconButtonClasses.focusVisible}`]: theme.focus.default,
},
theme.focus.default,
theme.variants[ownerState.variant!]?.[ownerState.color!],
theme.variants[`${ownerState.variant!}Hover`]?.[ownerState.color!],
theme.variants[`${ownerState.variant!}Active`]?.[ownerState.color!],
Expand Down
22 changes: 11 additions & 11 deletions packages/mui-joy/src/Input/Input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ const InputRoot = styled('div', {
'--Input-placeholderOpacity': 0.5,
'--Input-adornment-offset': 'calc(var(--Input-gutter) / 4)', // negative margin of the start/end adornment
'--Input-focusedThickness': 'calc(var(--variant-outlinedBorderWidth, 1px) + 1px)',
'--Input-focusedHighlight':
theme.palette[ownerState.color === 'neutral' ? 'primary' : ownerState.color!]?.[500],
boxSizing: 'border-box',
height: `var(--Input-height)`,
minWidth: 0, // forces the Input to stay inside a container by default
Expand Down Expand Up @@ -91,17 +93,14 @@ const InputRoot = styled('div', {
margin: 'calc(var(--variant-outlinedBorderWidth) * -1)', // for outlined variant
},
},
theme.variants[`${ownerState.variant!}`]?.[ownerState.color || 'neutral'],
theme.variants[`${ownerState.variant!}Hover`]?.[ownerState.color || 'neutral'],
theme.variants[`${ownerState.variant!}Disabled`]?.[ownerState.color || 'neutral'],
theme.variants[`${ownerState.variant!}`]?.[ownerState.color!],
theme.variants[`${ownerState.variant!}Hover`]?.[ownerState.color!],
theme.variants[`${ownerState.variant!}Disabled`]?.[ownerState.color!],
ownerState.variant !== 'contained' && {
color: theme.vars.palette[ownerState.color || 'neutral']?.overrideTextPrimary,
[`&.${inputClasses.focused}`]: {
backgroundColor: 'initial',
'&:before': {
boxShadow: `inset 0 0 0 var(--Input-focusedThickness) ${
theme.vars.palette[ownerState.color || 'primary']?.[500]
}`,
boxShadow: `inset 0 0 0 var(--Input-focusedThickness) var(--Input-focusedHighlight)`,
},
},
},
Expand All @@ -127,7 +126,7 @@ const InputInput = styled('input', {
fontSize: 'inherit',
'&:-webkit-autofill': {
WebkitBackgroundClip: 'text', // remove autofill background
WebkitTextFillColor: theme.vars.palette[ownerState.color || 'neutral']?.overrideTextPrimary,
WebkitTextFillColor: theme.vars.palette[ownerState.color!]?.overrideTextPrimary,
},
'&::-webkit-input-placeholder': { opacity: 'var(--Input-placeholderOpacity)', color: 'inherit' },
'&::-moz-placeholder': { opacity: 'var(--Input-placeholderOpacity)', color: 'inherit' }, // Firefox 19+
Expand All @@ -146,7 +145,7 @@ const InputStartAdornment = styled('span', {
marginRight: 'var(--Input-gap)',
color: theme.vars.palette.text.tertiary,
...(ownerState.focused && {
color: theme.vars.palette[ownerState.color || 'neutral']?.[`${ownerState.variant!}Color`],
color: theme.vars.palette[ownerState.color!]?.[`${ownerState.variant!}Color`],
}),
}));

Expand All @@ -158,7 +157,7 @@ const InputEndAdornment = styled('span', {
display: 'inherit',
marginLeft: 'var(--Input-gap)',
marginRight: 'calc(var(--Input-adornment-offset) * -1)',
color: theme.vars.palette[ownerState.color || 'neutral']?.[`${ownerState.variant!}Color`],
color: theme.vars.palette[ownerState.color!]?.[`${ownerState.variant!}Color`],
}));

const Input = React.forwardRef(function Input(inProps, ref) {
Expand All @@ -174,7 +173,7 @@ const Input = React.forwardRef(function Input(inProps, ref) {
autoComplete,
autoFocus,
className,
color,
color = 'neutral',
component,
components = {},
componentsProps = {},
Expand Down Expand Up @@ -343,6 +342,7 @@ Input.propTypes /* remove-proptypes */ = {
className: PropTypes.string,
/**
* The color of the component. It supports those theme colors that make sense for this component.
* @default 'neutral'
*/
color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([
PropTypes.oneOf(['danger', 'info', 'neutral', 'primary', 'success', 'warning']),
Expand Down
1 change: 1 addition & 0 deletions packages/mui-joy/src/Input/InputProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export interface InputTypeMap<P = {}, D extends React.ElementType = 'div'> {
classes?: Partial<InputClasses>;
/**
* The color of the component. It supports those theme colors that make sense for this component.
* @default 'neutral'
*/
color?: OverridableStringUnion<
Exclude<ColorPaletteProp, 'context'>,
Expand Down
19 changes: 6 additions & 13 deletions packages/mui-joy/src/ListItemButton/ListItemButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ const ListItemButtonRoot = styled('div', {
...(ownerState.selected && {
fontWeight: theme.vars.fontWeight.md,
}),
'&.Mui-focusVisible': theme.focus.default,
// Can't use :last-child or :first-child selector because ListItemButton can be inside ListItem with start/end action
// We want to be specific on what siblings the gap should be added.
[`& + .${listItemButtonClasses.root}`]: ownerState.row
Expand All @@ -86,14 +85,6 @@ const ListItemButtonRoot = styled('div', {
: {
marginTop: 'var(--List-gap)',
},
// default color & background styles when `color` prop is not specified or set as default
...(!ownerState.color &&
!ownerState.selected && {
color: theme.vars.palette.text.secondary,
'&:hover': {
color: theme.vars.palette.text.primary,
},
}),
},
{
...(ownerState.variant === 'outlined' && {
Expand All @@ -105,10 +96,11 @@ const ListItemButtonRoot = styled('div', {
'calc(var(--List-item-paddingRight) + var(--List-item-endActionWidth, var(--internal-endActionWidth, 0px)) - var(--variant-outlinedBorderWidth))', // --internal variable makes it possible to customize the actionWidth from the top List
}),
},
theme.focus.default,
theme.variants[ownerState.variant!]?.[ownerState.color!],
theme.variants[`${ownerState.variant!}Hover`]?.[ownerState.color || 'neutral'],
theme.variants[`${ownerState.variant!}Active`]?.[ownerState.color || 'neutral'],
theme.variants[`${ownerState.variant!}Disabled`]?.[ownerState.color || 'neutral'],
theme.variants[`${ownerState.variant!}Hover`]?.[ownerState.color!],
theme.variants[`${ownerState.variant!}Active`]?.[ownerState.color!],
theme.variants[`${ownerState.variant!}Disabled`]?.[ownerState.color!],
]);

const ListItemButton = React.forwardRef(function ListItemButton(inProps, ref) {
Expand All @@ -125,7 +117,7 @@ const ListItemButton = React.forwardRef(function ListItemButton(inProps, ref) {
action,
component = 'div',
selected = false,
color = selected ? 'primary' : undefined,
color = selected ? 'primary' : 'neutral',
variant = 'text',
...other
} = props;
Expand Down Expand Up @@ -203,6 +195,7 @@ ListItemButton.propTypes /* remove-proptypes */ = {
className: PropTypes.string,
/**
* The color of the component. It supports those theme colors that make sense for this component.
* @default 'neutral'
*/
color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([
PropTypes.oneOf(['context', 'danger', 'info', 'neutral', 'primary', 'success', 'warning']),
Expand Down
1 change: 1 addition & 0 deletions packages/mui-joy/src/ListItemButton/ListItemButtonProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export interface ListItemButtonTypeMap<P = {}, D extends React.ElementType = 'di
autoFocus?: boolean;
/**
* The color of the component. It supports those theme colors that make sense for this component.
* @default 'neutral'
*/
color?: OverridableStringUnion<ColorPaletteProp, ListItemButtonPropsColorOverrides>;
/**
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-joy/src/Switch/Switch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,8 @@ const SwitchRoot = styled('span', {
backgroundColor: 'initial',
color: 'var(--Switch-thumb-background)',
border: 'none',
[`&.${switchClasses.focusVisible}`]: theme.focus.default,
},
theme.focus.default,
];
});

Expand Down
1 change: 1 addition & 0 deletions packages/mui-joy/src/TextField/TextField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ TextField.propTypes /* remove-proptypes */ = {
className: PropTypes.string,
/**
* The color of the component. It supports those theme colors that make sense for this component.
* @default 'neutral'
*/
color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([
PropTypes.oneOf(['danger', 'info', 'neutral', 'primary', 'success', 'warning']),
Expand Down
5 changes: 5 additions & 0 deletions packages/mui-joy/src/Typography/Typography.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ const Typography = React.forwardRef(function Typography(inProps, ref) {
const {
className,
component,
color, // declare to prevent type error spread to TypographyRoot
gutterBottom = false,
noWrap = false,
level = 'body1',
Expand Down Expand Up @@ -111,6 +112,10 @@ Typography.propTypes /* remove-proptypes */ = {
* @ignore
*/
className: PropTypes.string,
/**
* @ignore
*/
color: PropTypes /* @typescript-to-proptypes-ignore */.any,
/**
* The component used for the root node.
* Either a string to use a HTML element or a component.
Expand Down
Loading