Skip to content

Commit edfdd3b

Browse files
committed
only inherit components with only styles
1 parent 1717890 commit edfdd3b

File tree

6 files changed

+155
-139
lines changed

6 files changed

+155
-139
lines changed

packages/mui-joy/src/Autocomplete/Autocomplete.tsx

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import ClearIcon from '../internal/svg-icons/Close';
1313
import ArrowDropDownIcon from '../internal/svg-icons/ArrowDropDown';
1414
import styled from '../styles/styled';
1515
// slot components
16-
import { IconButtonRoot } from '../IconButton/IconButton';
16+
import { StyledIconButton } from '../IconButton/IconButton';
1717
// default render components
1818
import Chip, { chipClasses } from '../Chip';
1919
import ChipDelete from '../ChipDelete';
@@ -31,8 +31,8 @@ import {
3131
AutocompleteOwnerState,
3232
} from './AutocompleteProps';
3333
import FormControlContext from '../FormControl/FormControlContext';
34-
import { AutocompleteOptionRoot } from '../AutocompleteOption/AutocompleteOption';
35-
import { AutocompleteListboxRoot } from '../AutocompleteListbox/AutocompleteListbox';
34+
import { StyledAutocompleteListbox } from '../AutocompleteListbox/AutocompleteListbox';
35+
import { StyledAutocompleteOption } from '../AutocompleteOption/AutocompleteOption';
3636
import useSlot from '../utils/useSlot';
3737

3838
type OwnerState = Omit<AutocompleteOwnerState<any, any, any, any>, 'onChange' | 'defaultValue'>;
@@ -133,18 +133,18 @@ const AutocompleteRoot = styled('div', {
133133
];
134134
});
135135

136-
const AutocompleteClearIndicator = styled(IconButtonRoot, {
136+
const AutocompleteClearIndicator = styled(StyledIconButton, {
137137
name: 'JoyAutocomplete',
138138
slot: 'ClearIndicator',
139139
overridesResolver: (props, styles) => styles.clearIndicator,
140140
})<{ ownerState: OwnerState & IconButtonOwnerState }>(({ ownerState }) => ({
141141
...(!ownerState.freeSolo && {
142-
marginInlineEnd: 0, // prevent the automatic adjustment between Input and IconButtonRoot
142+
marginInlineEnd: 0, // prevent the automatic adjustment between Input and IconButton
143143
}),
144144
visibility: ownerState.focused ? 'visible' : 'hidden',
145145
}));
146146

147-
const AutocompletePopupIndicator = styled(IconButtonRoot, {
147+
const AutocompletePopupIndicator = styled(StyledIconButton, {
148148
name: 'JoyAutocomplete',
149149
slot: 'PopupIndicator',
150150
overridesResolver: (props, styles) => styles.popupIndicator,
@@ -153,14 +153,13 @@ const AutocompletePopupIndicator = styled(IconButtonRoot, {
153153
transform: 'rotate(180deg)',
154154
}),
155155
}));
156-
157-
const AutocompleteListbox = styled(AutocompleteListboxRoot, {
156+
const AutocompleteListbox = styled(StyledAutocompleteListbox, {
158157
name: 'JoyAutocomplete',
159158
slot: 'Listbox',
160159
overridesResolver: (props, styles) => styles.listbox,
161160
})<{ ownerState: OwnerState }>({});
162161

163-
const AutocompleteOption = styled(AutocompleteOptionRoot, {
162+
const AutocompleteOption = styled(StyledAutocompleteOption, {
164163
name: 'JoyAutocomplete',
165164
slot: 'Option',
166165
overridesResolver: (props, styles) => styles.option,
@@ -343,7 +342,7 @@ const Autocomplete = React.forwardRef(function Autocomplete(
343342
const [SlotClearIndicator, clearIndicatorProps] = useSlot('clearIndicator', {
344343
className: classes.clearIndicator,
345344
elementType: AutocompleteClearIndicator,
346-
getSlotProps: getClearProps as unknown as () => React.HTMLAttributes<HTMLButtonElement>,
345+
getSlotProps: getClearProps,
347346
externalForwardedProps: other,
348347
ownerState,
349348
getSlotOwnerState: (mergedProps) => ({
@@ -360,8 +359,7 @@ const Autocomplete = React.forwardRef(function Autocomplete(
360359
const [SlotPopupIndicator, popupIndicatorProps] = useSlot('popupIndicator', {
361360
className: classes.popupIndicator,
362361
elementType: AutocompletePopupIndicator,
363-
getSlotProps:
364-
getPopupIndicatorProps as unknown as () => React.HTMLAttributes<HTMLButtonElement>,
362+
getSlotProps: getPopupIndicatorProps,
365363
externalForwardedProps: other,
366364
ownerState,
367365
getSlotOwnerState: (mergedProps) => ({

packages/mui-joy/src/AutocompleteListbox/AutocompleteListbox.tsx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { OverridableComponent } from '@mui/types';
44
import { unstable_capitalize as capitalize } from '@mui/utils';
55
import { useSlotProps } from '@mui/base/utils';
66
import composeClasses from '@mui/base/composeClasses';
7-
import { ListRoot } from '../List/List';
7+
import { StyledList } from '../List/List';
88
import { styled, useThemeProps } from '../styles';
99
import { getAutocompleteListboxUtilityClass } from './autocompleteListboxClasses';
1010
import {
@@ -29,11 +29,9 @@ const useUtilityClasses = (ownerState: AutocompleteListboxOwnerState) => {
2929
return composeClasses(slots, getAutocompleteListboxUtilityClass, {});
3030
};
3131

32-
export const AutocompleteListboxRoot = styled(ListRoot, {
33-
name: 'JoyAutocompleteListbox',
34-
slot: 'Root',
35-
overridesResolver: (props, styles) => styles.root,
36-
})<{ ownerState: AutocompleteListboxOwnerState }>(({ theme, ownerState }) => {
32+
export const StyledAutocompleteListbox = styled(StyledList)<{
33+
ownerState: AutocompleteListboxOwnerState;
34+
}>(({ theme, ownerState }) => {
3735
const variantStyle = theme.variants[ownerState.variant!]?.[ownerState.color!];
3836
return {
3937
'--focus-outline-offset': `calc(${theme.vars.focus.thickness} * -1)`, // to prevent the focus outline from being cut by overflow
@@ -66,6 +64,12 @@ export const AutocompleteListboxRoot = styled(ListRoot, {
6664
};
6765
});
6866

67+
const AutocompleteListboxRoot = styled(StyledAutocompleteListbox, {
68+
name: 'JoyAutocompleteListbox',
69+
slot: 'Root',
70+
overridesResolver: (props, styles) => styles.root,
71+
})({});
72+
6973
const AutocompleteListbox = React.forwardRef(function AutocompleteListbox(inProps, ref) {
7074
const props = useThemeProps<typeof inProps & { component?: React.ElementType }>({
7175
props: inProps,

packages/mui-joy/src/AutocompleteOption/AutocompleteOption.tsx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
44
import { OverridableComponent } from '@mui/types';
55
import { unstable_capitalize as capitalize } from '@mui/utils';
66
import composeClasses from '@mui/base/composeClasses';
7-
import { ListItemButtonRoot } from '../ListItemButton/ListItemButton';
7+
import { StyledListItemButton } from '../ListItemButton/ListItemButton';
88
import { styled, useThemeProps } from '../styles';
99
import autocompleteOptionClasses, {
1010
getAutocompleteOptionUtilityClass,
@@ -25,11 +25,9 @@ const useUtilityClasses = (ownerState: AutocompleteOptionOwnerState) => {
2525
return composeClasses(slots, getAutocompleteOptionUtilityClass, {});
2626
};
2727

28-
export const AutocompleteOptionRoot = styled(ListItemButtonRoot as unknown as 'li', {
29-
name: 'JoyAutocompleteOption',
30-
slot: 'Root',
31-
overridesResolver: (props, styles) => styles.root,
32-
})<{ ownerState: AutocompleteOptionOwnerState }>(({ theme, ownerState }) => ({
28+
export const StyledAutocompleteOption = styled(StyledListItemButton as unknown as 'li')<{
29+
ownerState: AutocompleteOptionOwnerState;
30+
}>(({ theme, ownerState }) => ({
3331
'&:not(:hover)': {
3432
transition: 'none', // prevent flicker when using keyboard arrows to move between options
3533
},
@@ -46,6 +44,12 @@ export const AutocompleteOptionRoot = styled(ListItemButtonRoot as unknown as 'l
4644
},
4745
}));
4846

47+
const AutocompleteOptionRoot = styled(StyledAutocompleteOption, {
48+
name: 'JoyAutocompleteOption',
49+
slot: 'Root',
50+
overridesResolver: (props, styles) => styles.root,
51+
})({});
52+
4953
const AutocompleteOption = React.forwardRef(function AutocompleteOption(inProps, ref) {
5054
const props = useThemeProps<typeof inProps & { component?: React.ElementType }>({
5155
props: inProps,

packages/mui-joy/src/IconButton/IconButton.tsx

Lines changed: 56 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -31,61 +31,65 @@ const useUtilityClasses = (ownerState: IconButtonOwnerState) => {
3131
return composedClasses;
3232
};
3333

34-
export const IconButtonRoot = styled('button', {
34+
export const StyledIconButton = styled('button')<{ ownerState: IconButtonOwnerState }>(
35+
({ theme, ownerState }) => [
36+
{
37+
'--Icon-margin': 'initial', // reset the icon's margin.
38+
'--CircularProgress-size': 'var(--Icon-fontSize)',
39+
...(ownerState.size === 'sm' && {
40+
'--Icon-fontSize': 'calc(var(--IconButton-size, 2rem) / 1.6)', // 1.25rem by default
41+
minWidth: 'var(--IconButton-size, 2rem)', // use min-width instead of height to make the button resilient to its content
42+
minHeight: 'var(--IconButton-size, 2rem)', // use min-height instead of height to make the button resilient to its content
43+
fontSize: theme.vars.fontSize.sm,
44+
paddingInline: '2px', // add a gap, in case the content is long, e.g. multiple icons
45+
}),
46+
...(ownerState.size === 'md' && {
47+
'--Icon-fontSize': 'calc(var(--IconButton-size, 2.5rem) / 1.667)', // 1.5rem by default
48+
minWidth: 'var(--IconButton-size, 2.5rem)',
49+
minHeight: 'var(--IconButton-size, 2.5rem)',
50+
fontSize: theme.vars.fontSize.md,
51+
paddingInline: '0.25rem',
52+
}),
53+
...(ownerState.size === 'lg' && {
54+
'--Icon-fontSize': 'calc(var(--IconButton-size, 3rem) / 1.714)', // 1.75rem by default
55+
minWidth: 'var(--IconButton-size, 3rem)',
56+
minHeight: 'var(--IconButton-size, 3rem)',
57+
fontSize: theme.vars.fontSize.lg,
58+
paddingInline: '0.375rem',
59+
}),
60+
WebkitTapHighlightColor: 'transparent',
61+
paddingBlock: 0,
62+
fontFamily: theme.vars.fontFamily.body,
63+
fontWeight: theme.vars.fontWeight.md,
64+
margin: `var(--IconButton-margin)`, // to be controlled by other components, eg. Input
65+
borderRadius: `var(--IconButton-radius, ${theme.vars.radius.sm})`, // to be controlled by other components, eg. Input
66+
border: 'none',
67+
boxSizing: 'border-box',
68+
backgroundColor: 'transparent',
69+
display: 'inline-flex',
70+
alignItems: 'center',
71+
justifyContent: 'center',
72+
position: 'relative',
73+
// TODO: discuss the transition approach in a separate PR. This value is copied from mui-material Button.
74+
transition:
75+
'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',
76+
[theme.focus.selector]: theme.focus.default,
77+
},
78+
theme.variants[ownerState.variant!]?.[ownerState.color!],
79+
{ '&:hover': theme.variants[`${ownerState.variant!}Hover`]?.[ownerState.color!] },
80+
{ '&:active': theme.variants[`${ownerState.variant!}Active`]?.[ownerState.color!] },
81+
{
82+
[`&.${iconButtonClasses.disabled}`]:
83+
theme.variants[`${ownerState.variant!}Disabled`]?.[ownerState.color!],
84+
},
85+
],
86+
);
87+
88+
export const IconButtonRoot = styled(StyledIconButton, {
3589
name: 'JoyIconButton',
3690
slot: 'Root',
3791
overridesResolver: (props, styles) => styles.root,
38-
})<{ ownerState: IconButtonOwnerState }>(({ theme, ownerState }) => [
39-
{
40-
'--Icon-margin': 'initial', // reset the icon's margin.
41-
'--CircularProgress-size': 'var(--Icon-fontSize)',
42-
...(ownerState.size === 'sm' && {
43-
'--Icon-fontSize': 'calc(var(--IconButton-size, 2rem) / 1.6)', // 1.25rem by default
44-
minWidth: 'var(--IconButton-size, 2rem)', // use min-width instead of height to make the button resilient to its content
45-
minHeight: 'var(--IconButton-size, 2rem)', // use min-height instead of height to make the button resilient to its content
46-
fontSize: theme.vars.fontSize.sm,
47-
paddingInline: '2px', // add a gap, in case the content is long, e.g. multiple icons
48-
}),
49-
...(ownerState.size === 'md' && {
50-
'--Icon-fontSize': 'calc(var(--IconButton-size, 2.5rem) / 1.667)', // 1.5rem by default
51-
minWidth: 'var(--IconButton-size, 2.5rem)',
52-
minHeight: 'var(--IconButton-size, 2.5rem)',
53-
fontSize: theme.vars.fontSize.md,
54-
paddingInline: '0.25rem',
55-
}),
56-
...(ownerState.size === 'lg' && {
57-
'--Icon-fontSize': 'calc(var(--IconButton-size, 3rem) / 1.714)', // 1.75rem by default
58-
minWidth: 'var(--IconButton-size, 3rem)',
59-
minHeight: 'var(--IconButton-size, 3rem)',
60-
fontSize: theme.vars.fontSize.lg,
61-
paddingInline: '0.375rem',
62-
}),
63-
WebkitTapHighlightColor: 'transparent',
64-
paddingBlock: 0,
65-
fontFamily: theme.vars.fontFamily.body,
66-
fontWeight: theme.vars.fontWeight.md,
67-
margin: `var(--IconButton-margin)`, // to be controlled by other components, eg. Input
68-
borderRadius: `var(--IconButton-radius, ${theme.vars.radius.sm})`, // to be controlled by other components, eg. Input
69-
border: 'none',
70-
boxSizing: 'border-box',
71-
backgroundColor: 'transparent',
72-
display: 'inline-flex',
73-
alignItems: 'center',
74-
justifyContent: 'center',
75-
position: 'relative',
76-
// TODO: discuss the transition approach in a separate PR. This value is copied from mui-material Button.
77-
transition:
78-
'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',
79-
[theme.focus.selector]: theme.focus.default,
80-
},
81-
theme.variants[ownerState.variant!]?.[ownerState.color!],
82-
{ '&:hover': theme.variants[`${ownerState.variant!}Hover`]?.[ownerState.color!] },
83-
{ '&:active': theme.variants[`${ownerState.variant!}Active`]?.[ownerState.color!] },
84-
{
85-
[`&.${iconButtonClasses.disabled}`]:
86-
theme.variants[`${ownerState.variant!}Disabled`]?.[ownerState.color!],
87-
},
88-
]);
92+
})({});
8993

9094
const IconButton = React.forwardRef(function IconButton(inProps, ref) {
9195
const props = useThemeProps<typeof inProps & { component?: React.ElementType }>({

packages/mui-joy/src/List/List.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,7 @@ const useUtilityClasses = (ownerState: ListOwnerState) => {
3131
return composeClasses(slots, getListUtilityClass, {});
3232
};
3333

34-
export const ListRoot = styled('ul', {
35-
name: 'JoyList',
36-
slot: 'Root',
37-
overridesResolver: (props, styles) => styles.root,
38-
})<{ ownerState: ListOwnerState }>(({ theme, ownerState }) => {
34+
export const StyledList = styled('ul')<{ ownerState: ListOwnerState }>(({ theme, ownerState }) => {
3935
function applySizeVars(size: ListProps['size']) {
4036
if (size === 'sm') {
4137
return {
@@ -140,6 +136,12 @@ export const ListRoot = styled('ul', {
140136
];
141137
});
142138

139+
export const ListRoot = styled(StyledList, {
140+
name: 'JoyList',
141+
slot: 'Root',
142+
overridesResolver: (props, styles) => styles.root,
143+
})({});
144+
143145
const List = React.forwardRef(function List(inProps, ref) {
144146
const nesting = React.useContext(NestedListContext);
145147
const menuContext = React.useContext(MenuUnstyledContext);

0 commit comments

Comments
 (0)