Skip to content

Commit

Permalink
[Joy] Miscellaneous fixes (mui#34492)
Browse files Browse the repository at this point in the history
  • Loading branch information
siriwatknp authored and Daniel Rabe committed Nov 29, 2022
1 parent 826f027 commit c7f82f9
Show file tree
Hide file tree
Showing 49 changed files with 226 additions and 79 deletions.
14 changes: 9 additions & 5 deletions docs/data/joy/components/chip/DeleteButtonChip.js
Expand Up @@ -6,14 +6,18 @@ import * as React from 'react';
export default function DeleteButtonChip() {
return (
<Box sx={{ display: 'flex', gap: 1, alignItems: 'center' }}>
<Chip variant="outlined" color="danger" endDecorator={<ChipDelete />}>
Remove
</Chip>
<Chip
variant="soft"
size="sm"
variant="outlined"
color="danger"
endDecorator={<ChipDelete variant="plain" />}
endDecorator={<ChipDelete />}
>
Remove
</Chip>
<Chip variant="soft" color="danger" endDecorator={<ChipDelete />}>
Delete
</Chip>
<Chip size="lg" variant="solid" color="danger" endDecorator={<ChipDelete />}>
Delete
</Chip>
</Box>
Expand Down
14 changes: 9 additions & 5 deletions docs/data/joy/components/chip/DeleteButtonChip.tsx
Expand Up @@ -6,14 +6,18 @@ import * as React from 'react';
export default function DeleteButtonChip() {
return (
<Box sx={{ display: 'flex', gap: 1, alignItems: 'center' }}>
<Chip variant="outlined" color="danger" endDecorator={<ChipDelete />}>
Remove
</Chip>
<Chip
variant="soft"
size="sm"
variant="outlined"
color="danger"
endDecorator={<ChipDelete variant="plain" />}
endDecorator={<ChipDelete />}
>
Remove
</Chip>
<Chip variant="soft" color="danger" endDecorator={<ChipDelete />}>
Delete
</Chip>
<Chip size="lg" variant="solid" color="danger" endDecorator={<ChipDelete />}>
Delete
</Chip>
</Box>
Expand Down
14 changes: 9 additions & 5 deletions docs/data/joy/components/chip/DeleteButtonChip.tsx.preview
@@ -1,10 +1,14 @@
<Chip variant="outlined" color="danger" endDecorator={<ChipDelete />}>
Remove
</Chip>
<Chip
variant="soft"
size="sm"
variant="outlined"
color="danger"
endDecorator={<ChipDelete variant="plain" />}
endDecorator={<ChipDelete />}
>
Remove
</Chip>
<Chip variant="soft" color="danger" endDecorator={<ChipDelete />}>
Delete
</Chip>
<Chip size="lg" variant="solid" color="danger" endDecorator={<ChipDelete />}>
Delete
</Chip>
1 change: 1 addition & 0 deletions docs/data/joy/components/divider/DividerChildPosition.js
Expand Up @@ -22,6 +22,7 @@ export default function DividerChildPosition() {
max={100}
step={1}
valueLabelDisplay="on"
valueLabelFormat={(value) => `${value}%`}
onChange={(event, value) => setPosition(value)}
/>
</Box>
Expand Down
4 changes: 2 additions & 2 deletions docs/data/joy/components/radio/ExampleTiers.js
Expand Up @@ -20,7 +20,7 @@ export default function ExampleTiers() {
name="tiers"
sx={{ gap: 1, '& > div': { p: 1, flexDirection: 'row', gap: 2 } }}
>
<FormControl>
<FormControl size="sm">
<Radio overlay value="small" />
<div>
<FormLabel>Small</FormLabel>
Expand All @@ -38,7 +38,7 @@ export default function ExampleTiers() {
</FormHelperText>
</div>
</FormControl>
<FormControl>
<FormControl size="lg">
<Radio overlay value="large" />
<div>
<FormLabel>Large</FormLabel>
Expand Down
2 changes: 1 addition & 1 deletion docs/data/joy/components/select/SelectDecorators.js
Expand Up @@ -10,7 +10,7 @@ export default function SelectDecorators() {
placeholder="Select a pet…"
startDecorator={<FavoriteBorder />}
endDecorator={
<Chip size="sm" color="danger" variant="soft" sx={{ mr: -1 }}>
<Chip size="sm" color="danger" variant="soft">
+5
</Chip>
}
Expand Down
1 change: 1 addition & 0 deletions packages/mui-joy/src/Button/Button.tsx
Expand Up @@ -90,6 +90,7 @@ export const ButtonRoot = styled('button', {
paddingBlock: '0.375rem',
paddingInline: '1.5rem',
}),
WebkitTapHighlightColor: 'transparent',
borderRadius: `var(--Button-radius, ${theme.vars.radius.sm})`, // to be controlled by other components, eg. Input
margin: `var(--Button-margin)`, // to be controlled by other components, eg. Input
border: 'none',
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-joy/src/Button/ButtonProps.ts
Expand Up @@ -104,7 +104,7 @@ export interface ButtonOwnerState extends ButtonProps {
/**
* If `true`, the button's focus is visible.
*/
focusVisible: boolean;
focusVisible?: boolean;
}

export type ExtendButton<M extends OverridableTypeMap> = ((
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-joy/src/Checkbox/CheckboxProps.ts
Expand Up @@ -112,5 +112,5 @@ export interface CheckboxOwnerState extends CheckboxProps {
/**
* If `true`, the checkbox's focus is visible.
*/
focusVisible: boolean;
focusVisible?: boolean;
}
12 changes: 6 additions & 6 deletions packages/mui-joy/src/Chip/Chip.tsx
Expand Up @@ -57,24 +57,24 @@ const ChipRoot = styled('div', {
'--Chip-gap': '0.25rem',
'--Chip-paddingInline': '0.5rem',
'--Chip-decorator-childHeight':
'calc(min(1.5rem, var(--Chip-minHeight)) - 2 * var(--variant-borderWidth))',
'--Icon-fontSize': '0.875rem',
'calc(min(1.125rem, var(--Chip-minHeight)) - 2 * var(--variant-borderWidth))',
'--Icon-fontSize': 'calc(var(--Chip-minHeight, 1.5rem) / 1.714)', // 0.875rem by default
'--Chip-minHeight': '1.5rem',
fontSize: theme.vars.fontSize.xs,
}),
...(ownerState.size === 'md' && {
'--Chip-gap': '0.375rem',
'--Chip-paddingInline': '0.75rem',
'--Chip-decorator-childHeight': 'min(1.5rem, var(--Chip-minHeight))',
'--Icon-fontSize': '1.125rem',
'--Chip-decorator-childHeight': 'min(1.375rem, var(--Chip-minHeight))',
'--Icon-fontSize': 'calc(var(--Chip-minHeight, 2rem) / 1.778)', // 1.125rem by default
'--Chip-minHeight': '2rem',
fontSize: theme.vars.fontSize.sm,
}),
...(ownerState.size === 'lg' && {
'--Chip-gap': '0.5rem',
'--Chip-paddingInline': '1rem',
'--Chip-decorator-childHeight': 'min(2rem, var(--Chip-minHeight))',
'--Icon-fontSize': '1.25rem',
'--Chip-decorator-childHeight': 'min(1.75rem, var(--Chip-minHeight))',
'--Icon-fontSize': 'calc(var(--Chip-minHeight, 2.5rem) / 2)', // 1.25rem by default
'--Chip-minHeight': '2.5rem',
fontSize: theme.vars.fontSize.md,
}),
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-joy/src/Chip/ChipProps.ts
Expand Up @@ -86,5 +86,5 @@ export interface ChipOwnerState extends ChipProps {
/**
* If `true`, the action slot's focus is visible.
*/
focusVisible: boolean;
focusVisible?: boolean;
}
4 changes: 2 additions & 2 deletions packages/mui-joy/src/ChipDelete/ChipDelete.tsx
Expand Up @@ -6,7 +6,7 @@ import { unstable_composeClasses as composeClasses, useButton } from '@mui/base'
import { useSlotProps } from '@mui/base/utils';
import { useThemeProps } from '../styles';
import styled from '../styles/styled';
import Close from '../internal/svg-icons/Close';
import Cancel from '../internal/svg-icons/Cancel';
import chipDeleteClasses, { getChipDeleteUtilityClass } from './chipDeleteClasses';
import { ChipDeleteProps, ChipDeleteOwnerState, ChipDeleteTypeMap } from './ChipDeleteProps';
import ChipContext from '../Chip/ChipContext';
Expand Down Expand Up @@ -113,7 +113,7 @@ const ChipDelete = React.forwardRef(function ChipDelete(inProps, ref) {
className: classes.root,
});

return <ChipDeleteRoot {...rootProps}>{children ?? <Close />}</ChipDeleteRoot>;
return <ChipDeleteRoot {...rootProps}>{children ?? <Cancel />}</ChipDeleteRoot>;
}) as OverridableComponent<ChipDeleteTypeMap>;

ChipDelete.propTypes /* remove-proptypes */ = {
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-joy/src/ChipDelete/ChipDeleteProps.ts
Expand Up @@ -45,5 +45,5 @@ export interface ChipDeleteOwnerState extends ChipDeleteProps {
/**
* If `true`, the element's focus is visible.
*/
focusVisible: boolean;
focusVisible?: boolean;
}
12 changes: 12 additions & 0 deletions packages/mui-joy/src/FormControl/FormControl.test.tsx
Expand Up @@ -152,6 +152,18 @@ describe('<FormControl />', () => {
expect(getByLabelText('label')).toBeVisible();
});

it('should labeledby form label', () => {
const { container, getByRole } = render(
<FormControl>
<FormLabel>label</FormLabel>
<Select />
</FormControl>,
);

const label = container.querySelector('label');
expect(getByRole('button')).to.have.attribute('aria-labelledby', label?.id);
});

it('should inherit color prop from FormControl', () => {
const { getByTestId } = render(
<FormControl color="success">
Expand Down
3 changes: 2 additions & 1 deletion packages/mui-joy/src/FormControl/FormControl.tsx
Expand Up @@ -32,6 +32,7 @@ export const FormControlRoot = styled('div', {
})<{ ownerState: FormControlOwnerState }>(({ theme, ownerState }) => ({
'--FormLabel-margin':
ownerState.orientation === 'horizontal' ? '0 0.375rem 0 0' : '0 0 0.25rem 0',
'--FormLabel-alignSelf': 'flex-start',
'--FormHelperText-margin': '0.375rem 0 0 0',
'--FormLabel-asterisk-color': theme.vars.palette.danger[500],
'--FormHelperText-color': theme.vars.palette[ownerState.color!]?.[500],
Expand All @@ -45,7 +46,7 @@ export const FormControlRoot = styled('div', {
}),
...(ownerState.size === 'lg' && {
'--FormLabel-fontSize': theme.vars.fontSize.md,
'--FormHelperText-fontSize': theme.vars.fontSize.md,
'--FormHelperText-fontSize': theme.vars.fontSize.sm,
}),
[`&.${formControlClasses.error}`]: {
'--FormHelperText-color': theme.vars.palette.danger[500],
Expand Down
2 changes: 2 additions & 0 deletions packages/mui-joy/src/FormLabel/FormLabel.tsx
Expand Up @@ -22,6 +22,8 @@ const FormLabelRoot = styled('label', {
slot: 'Root',
overridesResolver: (props, styles) => styles.root,
})<{ ownerState: FormLabelProps }>(({ theme }) => ({
WebkitTapHighlightColor: 'transparent',
alignSelf: 'var(--FormLabel-alignSelf)', // to not fill the block space. It seems like a bug when clicking on empty space (within the label area), even though it is not.
display: 'flex',
alignItems: 'center',
flexWrap: 'wrap',
Expand Down
1 change: 1 addition & 0 deletions packages/mui-joy/src/IconButton/IconButton.tsx
Expand Up @@ -60,6 +60,7 @@ export const IconButtonRoot = styled('button', {
fontSize: theme.vars.fontSize.lg,
paddingInline: '0.375rem',
}),
WebkitTapHighlightColor: 'transparent',
paddingBlock: 0,
fontFamily: theme.vars.fontFamily.body,
fontWeight: theme.vars.fontWeight.md,
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-joy/src/IconButton/IconButtonProps.ts
Expand Up @@ -79,7 +79,7 @@ export interface IconButtonOwnerState extends IconButtonProps {
/**
* If `true`, the element's focus is visible.
*/
focusVisible: boolean;
focusVisible?: boolean;
}

export type ExtendIconButton<M extends OverridableTypeMap> = ((
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-joy/src/Input/Input.tsx
Expand Up @@ -40,7 +40,7 @@ const InputRoot = styled('div', {
'--Input-radius': theme.vars.radius.sm,
'--Input-gap': '0.5rem',
'--Input-placeholderOpacity': 0.5,
'--Input-focusedThickness': '2px',
'--Input-focusedThickness': theme.vars.focus.thickness,
'--Input-focusedHighlight':
theme.vars.palette[ownerState.color === 'neutral' ? 'primary' : ownerState.color!]?.[500],
...(ownerState.size === 'sm' && {
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-joy/src/Link/LinkProps.ts
Expand Up @@ -96,7 +96,7 @@ export interface LinkOwnerState extends LinkProps {
/**
* If `true`, the element's focus is visible.
*/
focusVisible: boolean;
focusVisible?: boolean;
/**
* If `true`, the element is rendered by a Typography component.
*/
Expand Down
1 change: 1 addition & 0 deletions packages/mui-joy/src/List/List.tsx
Expand Up @@ -125,6 +125,7 @@ export const ListRoot = styled('ul', {
}),
},
{
boxSizing: 'border-box',
borderRadius: 'var(--List-radius)',
listStyle: 'none',
display: 'flex',
Expand Down
1 change: 1 addition & 0 deletions packages/mui-joy/src/ListItemButton/ListItemButton.tsx
Expand Up @@ -51,6 +51,7 @@ export const ListItemButtonRoot = styled('div', {
'--List-decorator-color':
theme.vars.palette[ownerState.color!]?.[`${ownerState.variant!}DisabledColor`],
}),
WebkitTapHighlightColor: 'transparent',
boxSizing: 'border-box',
position: 'relative',
display: 'flex',
Expand Down
4 changes: 2 additions & 2 deletions packages/mui-joy/src/ListItemButton/ListItemButtonProps.ts
Expand Up @@ -98,12 +98,12 @@ export interface ListItemButtonOwnerState extends ListItemButtonProps {
/**
* If `true`, the element's focus is visible.
*/
focusVisible: boolean;
focusVisible?: boolean;
/**
* If `true`, the element is rendered in a horizontal list.
* @internal
*/
row: boolean;
row?: boolean;
/**
* @internal
* The internal prop for controlling CSS margin of the element.
Expand Down
1 change: 1 addition & 0 deletions packages/mui-joy/src/Menu/Menu.tsx
Expand Up @@ -34,6 +34,7 @@ const MenuRoot = styled(ListRoot, {
})<{ ownerState: MenuOwnerState }>(({ theme, ownerState }) => {
const variantStyle = theme.variants[ownerState.variant!]?.[ownerState.color!];
return {
'--focus-outline-offset': `calc(${theme.vars.focus.thickness} * -1)`, // to prevent the focus outline from being cut by overflow
'--List-radius': theme.vars.radius.sm,
'--List-item-stickyBackground':
variantStyle?.backgroundColor ||
Expand Down
10 changes: 10 additions & 0 deletions packages/mui-joy/src/MenuItem/MenuItem.test.js
Expand Up @@ -50,6 +50,16 @@ describe('Joy <MenuItem />', () => {
skip: ['propsSpread', 'componentsProp', 'classesRoot', 'reactTestRenderer'],
}));

it('should render with the variant class', () => {
const { getByRole } = render(<MenuItem variant="outlined" />);
expect(getByRole('menuitem')).to.have.class(classes.variantOutlined);
});

it('should render with primary color class', () => {
const { getByRole } = render(<MenuItem color="primary" />);
expect(getByRole('menuitem')).to.have.class(classes.colorPrimary);
});

it('should render a focusable menuitem', () => {
render(<MenuItem />);
const menuitem = screen.getByRole('menuitem');
Expand Down
18 changes: 12 additions & 6 deletions packages/mui-joy/src/MenuItem/MenuItem.tsx
@@ -1,5 +1,6 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import { unstable_capitalize as capitalize } from '@mui/utils';
import composeClasses from '@mui/base/composeClasses';
import { useSlotProps } from '@mui/base/utils';
import { useMenuItem } from '@mui/base/MenuItemUnstyled';
Expand All @@ -14,12 +15,17 @@ import {
} from './MenuItemProps';
import RowListContext from '../List/RowListContext';

const useUtilityClasses = (ownerState: MenuItemProps & { focusVisible: boolean }) => {
const { focusVisible, disabled, selected } = ownerState;
// Does not need to create state clases: focusVisible, disabled, and selected because ListItemButton already takes care of them.
// Otherwise, there will be duplicated classes.
const useUtilityClasses = (ownerState: MenuItemProps & { focusVisible?: boolean }) => {
const { focusVisible, disabled, selected, color, variant } = ownerState;
const slots = {
root: ['root', focusVisible && 'focusVisible', disabled && 'disabled', selected && 'selected'],
root: [
'root',
focusVisible && 'focusVisible',
disabled && 'disabled',
selected && 'selected',
color && `color${capitalize(color)}`,
variant && `variant${capitalize(variant)}`,
],
};

const composedClasses = composeClasses(slots, getMenuItemUtilityClass, {});
Expand Down Expand Up @@ -98,7 +104,7 @@ MenuItem.propTypes /* remove-proptypes */ = {
* @default 'neutral'
*/
color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([
PropTypes.oneOf(['context', 'danger', 'info', 'neutral', 'primary', 'success', 'warning']),
PropTypes.oneOf(['danger', 'info', 'neutral', 'primary', 'success', 'warning']),
PropTypes.string,
]),
/**
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-joy/src/MenuItem/MenuItemProps.ts
Expand Up @@ -29,7 +29,7 @@ export interface MenuItemOwnerState extends MenuItemProps {
/**
* If `true`, the element's focus is visible.
*/
focusVisible: boolean;
focusVisible?: boolean;
}

export type ExtendMenuItem<M extends OverridableTypeMap> = ((
Expand Down

0 comments on commit c7f82f9

Please sign in to comment.