Skip to content

Commit

Permalink
[Stack][material] Use createStack from the system (#33795)
Browse files Browse the repository at this point in the history
  • Loading branch information
mnajdova authored Feb 24, 2023
1 parent 7e60a2a commit ec7cdb2
Show file tree
Hide file tree
Showing 16 changed files with 97 additions and 602 deletions.
6 changes: 2 additions & 4 deletions docs/pages/material-ui/api/stack.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,14 @@
"type": {
"name": "union",
"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"
},
"default": "'column'"
}
},
"divider": { "type": { "name": "node" } },
"spacing": {
"type": {
"name": "union",
"description": "Array&lt;number<br>&#124;&nbsp;string&gt;<br>&#124;&nbsp;number<br>&#124;&nbsp;object<br>&#124;&nbsp;string"
},
"default": "0"
}
},
"sx": {
"type": {
Expand Down
1 change: 1 addition & 0 deletions docs/pages/system/api/stack.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"props": {
"children": { "type": { "name": "node" } },
"component": { "type": { "name": "elementType" } },
"direction": {
"type": {
"name": "union",
Expand Down
1 change: 1 addition & 0 deletions docs/translations/api-docs/stack/stack.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"componentDescription": "",
"propDescriptions": {
"children": "The content of the component.",
"component": "The component used for the root node. Either a string to use a HTML element or a component.",
"direction": "Defines the <code>flex-direction</code> style property. It is applied for all screen sizes.",
"divider": "Add an element between each child.",
"spacing": "Defines the space between immediate children.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,20 @@ const rule = {
componentName = parent.id.name;
}

if (
parent.type === 'VariableDeclarator' &&
parent.init.type.match(/(CallExpression|TSAsExpression)/)
) {
const callee =
parent.init.type === 'TSAsExpression'
? parent.init.expression.callee
: parent.init.callee;
if (callee.name.includes(parent.id.name)) {
// For component factory, e.g. const Container = createContainer({ ... })
componentName = parent.id.name;
}
}

parent = parent.parent;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,34 @@ ruleTester.run('mui-name-matches-component-name', rule, {
useThemeProps({ props: inProps, name: 'MuiCssBaseline' });
}
`,
`
const Container = createContainer({
createStyledComponent: styled('div', {
name: 'MuiContainer',
slot: 'Root',
overridesResolver: (props, styles) => {
const { ownerState } = props;
return [
styles.root,
ownerState.fixed && styles.fixed,
ownerState.disableGutters && styles.disableGutters,
];
},
}),
useThemeProps: (inProps) => useThemeProps({ props: inProps, name: 'MuiContainer' }),
});
`,
`
const Grid2 = createGrid2({
createStyledComponent: styled('div', {
name: 'MuiGrid2',
overridesResolver: (props, styles) => styles.root,
}),
componentName: 'MuiGrid2',
useThemeProps: (inProps) => useThemeProps({ props: inProps, name: 'MuiGrid2' }),
}) as OverridableComponent<Grid2TypeMap>;
`,
{
code: `
const StaticDateRangePicker = React.forwardRef(function StaticDateRangePicker<TDate>(
Expand Down
5 changes: 5 additions & 0 deletions packages/mui-joy/src/Stack/Stack.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ Stack.propTypes /* remove-proptypes */ = {
* The content of the component.
*/
children: PropTypes.node,
/**
* The component used for the root node.
* Either a string to use a HTML element or a component.
*/
component: PropTypes.elementType,
/**
* Defines the `flex-direction` style property.
* It is applied for all screen sizes.
Expand Down
1 change: 0 additions & 1 deletion packages/mui-material/src/Container/Container.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable material-ui/mui-name-matches-component-name */
import PropTypes from 'prop-types';
import { createContainer } from '@mui/system';
import capitalize from '../utils/capitalize';
Expand Down
1 change: 0 additions & 1 deletion packages/mui-material/src/Stack/Stack.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { Theme } from '../styles/createTheme';
export interface StackTypeMap<P = {}, D extends React.ElementType = 'div'> {
props: P &
SystemProps<Theme> & {
ref?: React.Ref<unknown>;
/**
* The content of the component.
*/
Expand Down
145 changes: 8 additions & 137 deletions packages/mui-material/src/Stack/Stack.js
Original file line number Diff line number Diff line change
@@ -1,144 +1,15 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import {
createUnarySpacing,
getValue,
handleBreakpoints,
mergeBreakpointsInOrder,
unstable_extendSxProp as extendSxProp,
unstable_resolveBreakpointValues as resolveBreakpointValues,
} from '@mui/system';
import { deepmerge } from '@mui/utils';
import { createStack } from '@mui/system';
import styled from '../styles/styled';
import useThemeProps from '../styles/useThemeProps';

/**
* Return an array with the separator React element interspersed between
* each React node of the input children.
*
* > joinChildren([1,2,3], 0)
* [1,0,2,0,3]
*/
function joinChildren(children, separator) {
const childrenArray = React.Children.toArray(children).filter(Boolean);

return childrenArray.reduce((output, child, index) => {
output.push(child);

if (index < childrenArray.length - 1) {
output.push(React.cloneElement(separator, { key: `separator-${index}` }));
}

return output;
}, []);
}

const getSideFromDirection = (direction) => {
return {
row: 'Left',
'row-reverse': 'Right',
column: 'Top',
'column-reverse': 'Bottom',
}[direction];
};

export const style = ({ ownerState, theme }) => {
let styles = {
display: 'flex',
flexDirection: 'column',
...handleBreakpoints(
{ theme },
resolveBreakpointValues({
values: ownerState.direction,
breakpoints: theme.breakpoints.values,
}),
(propValue) => ({
flexDirection: propValue,
}),
),
};

if (ownerState.spacing) {
const transformer = createUnarySpacing(theme);

const base = Object.keys(theme.breakpoints.values).reduce((acc, breakpoint) => {
if (
(typeof ownerState.spacing === 'object' && ownerState.spacing[breakpoint] != null) ||
(typeof ownerState.direction === 'object' && ownerState.direction[breakpoint] != null)
) {
acc[breakpoint] = true;
}
return acc;
}, {});

const directionValues = resolveBreakpointValues({
values: ownerState.direction,
base,
});

const spacingValues = resolveBreakpointValues({
values: ownerState.spacing,
base,
});

if (typeof directionValues === 'object') {
Object.keys(directionValues).forEach((breakpoint, index, breakpoints) => {
const directionValue = directionValues[breakpoint];
if (!directionValue) {
const previousDirectionValue =
index > 0 ? directionValues[breakpoints[index - 1]] : 'column';
directionValues[breakpoint] = previousDirectionValue;
}
});
}

const styleFromPropValue = (propValue, breakpoint) => {
return {
'& > :not(style) + :not(style)': {
margin: 0,
[`margin${getSideFromDirection(
breakpoint ? directionValues[breakpoint] : ownerState.direction,
)}`]: getValue(transformer, propValue),
},
};
};
styles = deepmerge(styles, handleBreakpoints({ theme }, spacingValues, styleFromPropValue));
}

styles = mergeBreakpointsInOrder(theme.breakpoints, styles);

return styles;
};

const StackRoot = styled('div', {
name: 'MuiStack',
slot: 'Root',
overridesResolver: (props, styles) => {
return [styles.root];
},
})(style);

const Stack = React.forwardRef(function Stack(inProps, ref) {
const themeProps = useThemeProps({ props: inProps, name: 'MuiStack' });
const props = extendSxProp(themeProps);
const {
component = 'div',
direction = 'column',
spacing = 0,
divider,
children,
...other
} = props;
const ownerState = {
direction,
spacing,
};

return (
<StackRoot as={component} ownerState={ownerState} ref={ref} {...other}>
{divider ? joinChildren(children, divider) : children}
</StackRoot>
);
const Stack = createStack({
createStyledComponent: styled('div', {
name: 'MuiStack',
slot: 'Root',
overridesResolver: (props, styles) => styles.root,
}),
useThemeProps: (inProps) => useThemeProps({ props: inProps, name: 'MuiStack' }),
});

Stack.propTypes /* remove-proptypes */ = {
Expand Down
Loading

0 comments on commit ec7cdb2

Please sign in to comment.