стилизованная система | Разрешить функцию стиля темы в компоненте
Я пытаюсь понять, как разрешить функцию стилизованной системы в компоненте по умолчанию. Идея состоит в том, чтобы иметь элемент контейнера, который использует тему из коробки для предоставления основных адаптивных разрывов.
Прямо сейчас то, что я делаю ниже, - это создание системы стилей.
width
функцию с таким объектом:
//theme.js
const CONTAINERS = {
xs: "100%",
sm: "55rem",
md: "74rem",
lg: "100rem",
xl: "131rem",
};
export default {
containers: CONTAINERS,
//other items
}
//Container.js
export default (props) => {
const { containers, grid } = useContext(ThemeContext);
return (
<Container px={grid.margin} width={containers} {...props}>
{props.children}
</Container>
);
};
const Container = styled("div")(
css`
margin-right: auto;
margin-left: auto;
padding-right: 1rem;
padding-left: 1rem;
`,
compose
);
Это ДЕЙСТВИТЕЛЬНО работает, но не так чисто, как хотелось бы. Я бы хотел иметь возможность просто
const Container = styled("div")(
css`
margin-right: auto;
margin-left: auto;
padding-right: 1rem;
padding-left: 1rem;
${//maybe resolve the responsive widths here}
`,
compose //<- a group of styled-system functions supplied in one object
//or resolve responsive widths here
);
export default Container
Это было бы намного чище, так как я мог бы затем объединить и экспортировать компоненты макета в один файл без необходимости выполнять
const Container...
+
const StyledContainer...
формальности.
Я играю с идеей написать функцию, которая зацикливает
containers
объект и возвращает ширину, обернутую в медиа-запросы, но мне интересно, делает ли styled-system это из коробки?
1 ответ
Я не могу найти ничего в документации, чтобы сделать что-то подобное из коробки, поэтому я реализовал это вручную.
//theme.js
const BREAKPOINTS = {
xs: "0em",
sm: "37em",
md: "48em",
lg: "64.625em",
xl: "84em",
};
const CONTAINERS = {
xs: "100%",
sm: "55rem",
md: "74rem",
lg: "100rem",
xl: "131rem",
};
Приведенный ниже сценарий берет объекты выше и помещает значения точек останова в оболочку.
@media
затем вставляет значения контейнеров как
width:
внутри этого. Затем возвращает весь лот как css.
const Container = styled("div")(
css`
margin-right: auto;
margin-left: auto;
padding-right: 1rem;
padding-left: 1rem;
&::after,
&::before {
content: "";
display: block;
min-height: 2rem;
height: 4vw;
max-height: 6rem;
}
`,
compose,
(props) => {
const breakpoints = props.theme.breakpoints;
const containers = props.theme.containers;
const makeMedia = (media) => {
return (...args) => css`
@media ${media} {
${css(...args)}
}
`;
};
const getMedia = Object.keys(breakpoints).reduce((media, breakpoint) => {
const breakpointWidth = breakpoints[breakpoint];
media[breakpoint] = makeMedia(
[breakpoint !== 0 && `(min-width: ${breakpointWidth})`]
.filter(Boolean)
.join(" and ")
);
return media;
}, {});
return css`
${Object.keys(breakpoints).map(
(key) => containers[key] && getMedia[key]`width: ${containers[key]}`
)};
`;
}
);