Skip to content

Commit ec7cdb2

Browse files
authored
[Stack][material] Use createStack from the system (#33795)
1 parent 7e60a2a commit ec7cdb2

File tree

16 files changed

+97
-602
lines changed

16 files changed

+97
-602
lines changed

docs/pages/material-ui/api/stack.json

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,14 @@
66
"type": {
77
"name": "union",
88
"description": "'column-reverse'<br>&#124;&nbsp;'column'<br>&#124;&nbsp;'row-reverse'<br>&#124;&nbsp;'row'<br>&#124;&nbsp;Array&lt;'column-reverse'<br>&#124;&nbsp;'column'<br>&#124;&nbsp;'row-reverse'<br>&#124;&nbsp;'row'&gt;<br>&#124;&nbsp;object"
9-
},
10-
"default": "'column'"
9+
}
1110
},
1211
"divider": { "type": { "name": "node" } },
1312
"spacing": {
1413
"type": {
1514
"name": "union",
1615
"description": "Array&lt;number<br>&#124;&nbsp;string&gt;<br>&#124;&nbsp;number<br>&#124;&nbsp;object<br>&#124;&nbsp;string"
17-
},
18-
"default": "0"
16+
}
1917
},
2018
"sx": {
2119
"type": {

docs/pages/system/api/stack.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"props": {
33
"children": { "type": { "name": "node" } },
4+
"component": { "type": { "name": "elementType" } },
45
"direction": {
56
"type": {
67
"name": "union",

docs/translations/api-docs/stack/stack.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"componentDescription": "",
33
"propDescriptions": {
44
"children": "The content of the component.",
5+
"component": "The component used for the root node. Either a string to use a HTML element or a component.",
56
"direction": "Defines the <code>flex-direction</code> style property. It is applied for all screen sizes.",
67
"divider": "Add an element between each child.",
78
"spacing": "Defines the space between immediate children.",

packages/eslint-plugin-material-ui/src/rules/mui-name-matches-component-name.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,20 @@ const rule = {
9898
componentName = parent.id.name;
9999
}
100100

101+
if (
102+
parent.type === 'VariableDeclarator' &&
103+
parent.init.type.match(/(CallExpression|TSAsExpression)/)
104+
) {
105+
const callee =
106+
parent.init.type === 'TSAsExpression'
107+
? parent.init.expression.callee
108+
: parent.init.callee;
109+
if (callee.name.includes(parent.id.name)) {
110+
// For component factory, e.g. const Container = createContainer({ ... })
111+
componentName = parent.id.name;
112+
}
113+
}
114+
101115
parent = parent.parent;
102116
}
103117

packages/eslint-plugin-material-ui/src/rules/mui-name-matches-component-name.test.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,34 @@ ruleTester.run('mui-name-matches-component-name', rule, {
1717
useThemeProps({ props: inProps, name: 'MuiCssBaseline' });
1818
}
1919
`,
20+
`
21+
const Container = createContainer({
22+
createStyledComponent: styled('div', {
23+
name: 'MuiContainer',
24+
slot: 'Root',
25+
overridesResolver: (props, styles) => {
26+
const { ownerState } = props;
27+
28+
return [
29+
styles.root,
30+
ownerState.fixed && styles.fixed,
31+
ownerState.disableGutters && styles.disableGutters,
32+
];
33+
},
34+
}),
35+
useThemeProps: (inProps) => useThemeProps({ props: inProps, name: 'MuiContainer' }),
36+
});
37+
`,
38+
`
39+
const Grid2 = createGrid2({
40+
createStyledComponent: styled('div', {
41+
name: 'MuiGrid2',
42+
overridesResolver: (props, styles) => styles.root,
43+
}),
44+
componentName: 'MuiGrid2',
45+
useThemeProps: (inProps) => useThemeProps({ props: inProps, name: 'MuiGrid2' }),
46+
}) as OverridableComponent<Grid2TypeMap>;
47+
`,
2048
{
2149
code: `
2250
const StaticDateRangePicker = React.forwardRef(function StaticDateRangePicker<TDate>(

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ Stack.propTypes /* remove-proptypes */ = {
3333
* The content of the component.
3434
*/
3535
children: PropTypes.node,
36+
/**
37+
* The component used for the root node.
38+
* Either a string to use a HTML element or a component.
39+
*/
40+
component: PropTypes.elementType,
3641
/**
3742
* Defines the `flex-direction` style property.
3843
* It is applied for all screen sizes.

packages/mui-material/src/Container/Container.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
/* eslint-disable material-ui/mui-name-matches-component-name */
21
import PropTypes from 'prop-types';
32
import { createContainer } from '@mui/system';
43
import capitalize from '../utils/capitalize';

packages/mui-material/src/Stack/Stack.d.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import { Theme } from '../styles/createTheme';
66
export interface StackTypeMap<P = {}, D extends React.ElementType = 'div'> {
77
props: P &
88
SystemProps<Theme> & {
9-
ref?: React.Ref<unknown>;
109
/**
1110
* The content of the component.
1211
*/

packages/mui-material/src/Stack/Stack.js

Lines changed: 8 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -1,144 +1,15 @@
1-
import * as React from 'react';
21
import PropTypes from 'prop-types';
3-
import {
4-
createUnarySpacing,
5-
getValue,
6-
handleBreakpoints,
7-
mergeBreakpointsInOrder,
8-
unstable_extendSxProp as extendSxProp,
9-
unstable_resolveBreakpointValues as resolveBreakpointValues,
10-
} from '@mui/system';
11-
import { deepmerge } from '@mui/utils';
2+
import { createStack } from '@mui/system';
123
import styled from '../styles/styled';
134
import useThemeProps from '../styles/useThemeProps';
145

15-
/**
16-
* Return an array with the separator React element interspersed between
17-
* each React node of the input children.
18-
*
19-
* > joinChildren([1,2,3], 0)
20-
* [1,0,2,0,3]
21-
*/
22-
function joinChildren(children, separator) {
23-
const childrenArray = React.Children.toArray(children).filter(Boolean);
24-
25-
return childrenArray.reduce((output, child, index) => {
26-
output.push(child);
27-
28-
if (index < childrenArray.length - 1) {
29-
output.push(React.cloneElement(separator, { key: `separator-${index}` }));
30-
}
31-
32-
return output;
33-
}, []);
34-
}
35-
36-
const getSideFromDirection = (direction) => {
37-
return {
38-
row: 'Left',
39-
'row-reverse': 'Right',
40-
column: 'Top',
41-
'column-reverse': 'Bottom',
42-
}[direction];
43-
};
44-
45-
export const style = ({ ownerState, theme }) => {
46-
let styles = {
47-
display: 'flex',
48-
flexDirection: 'column',
49-
...handleBreakpoints(
50-
{ theme },
51-
resolveBreakpointValues({
52-
values: ownerState.direction,
53-
breakpoints: theme.breakpoints.values,
54-
}),
55-
(propValue) => ({
56-
flexDirection: propValue,
57-
}),
58-
),
59-
};
60-
61-
if (ownerState.spacing) {
62-
const transformer = createUnarySpacing(theme);
63-
64-
const base = Object.keys(theme.breakpoints.values).reduce((acc, breakpoint) => {
65-
if (
66-
(typeof ownerState.spacing === 'object' && ownerState.spacing[breakpoint] != null) ||
67-
(typeof ownerState.direction === 'object' && ownerState.direction[breakpoint] != null)
68-
) {
69-
acc[breakpoint] = true;
70-
}
71-
return acc;
72-
}, {});
73-
74-
const directionValues = resolveBreakpointValues({
75-
values: ownerState.direction,
76-
base,
77-
});
78-
79-
const spacingValues = resolveBreakpointValues({
80-
values: ownerState.spacing,
81-
base,
82-
});
83-
84-
if (typeof directionValues === 'object') {
85-
Object.keys(directionValues).forEach((breakpoint, index, breakpoints) => {
86-
const directionValue = directionValues[breakpoint];
87-
if (!directionValue) {
88-
const previousDirectionValue =
89-
index > 0 ? directionValues[breakpoints[index - 1]] : 'column';
90-
directionValues[breakpoint] = previousDirectionValue;
91-
}
92-
});
93-
}
94-
95-
const styleFromPropValue = (propValue, breakpoint) => {
96-
return {
97-
'& > :not(style) + :not(style)': {
98-
margin: 0,
99-
[`margin${getSideFromDirection(
100-
breakpoint ? directionValues[breakpoint] : ownerState.direction,
101-
)}`]: getValue(transformer, propValue),
102-
},
103-
};
104-
};
105-
styles = deepmerge(styles, handleBreakpoints({ theme }, spacingValues, styleFromPropValue));
106-
}
107-
108-
styles = mergeBreakpointsInOrder(theme.breakpoints, styles);
109-
110-
return styles;
111-
};
112-
113-
const StackRoot = styled('div', {
114-
name: 'MuiStack',
115-
slot: 'Root',
116-
overridesResolver: (props, styles) => {
117-
return [styles.root];
118-
},
119-
})(style);
120-
121-
const Stack = React.forwardRef(function Stack(inProps, ref) {
122-
const themeProps = useThemeProps({ props: inProps, name: 'MuiStack' });
123-
const props = extendSxProp(themeProps);
124-
const {
125-
component = 'div',
126-
direction = 'column',
127-
spacing = 0,
128-
divider,
129-
children,
130-
...other
131-
} = props;
132-
const ownerState = {
133-
direction,
134-
spacing,
135-
};
136-
137-
return (
138-
<StackRoot as={component} ownerState={ownerState} ref={ref} {...other}>
139-
{divider ? joinChildren(children, divider) : children}
140-
</StackRoot>
141-
);
6+
const Stack = createStack({
7+
createStyledComponent: styled('div', {
8+
name: 'MuiStack',
9+
slot: 'Root',
10+
overridesResolver: (props, styles) => styles.root,
11+
}),
12+
useThemeProps: (inProps) => useThemeProps({ props: inProps, name: 'MuiStack' }),
14213
});
14314

14415
Stack.propTypes /* remove-proptypes */ = {

0 commit comments

Comments
 (0)