Как использовать адаптивный реквизит в стиле стилевой системы
Могу ли я использовать styled-system
добиться чего-то подобного?
<MyComponent
backgroundImage={{
default: "https://placekitten.com/380/80",
sm: "https://placekitten.com/340/80"
}}
/>
или это (потому что я знаю, что это можно сделать и с другими "стилевыми реквизитами", такими как ширина, но я предпочитаю использовать объект с ключами):
<MyComponent
backgroundImage={[
"https://placekitten.com/300/80",
"https://placekitten.com/500/80"
]}
/>
Я думаю, что приведенные выше примеры кода информативны и соответствуют шаблону библиотеки, но для ясности я сопоставляю значения (источники изображений) с точками останова (по умолчанию и следующие).
Например, это работает из коробки:
<Box
width={[
default: 1,
sm: 1/3,
]}
/>
Результат будет примерно таким:
.QWojd {
width: 100%;
}
@media screen and (min-width: 24em) {
.QWojd {
width: 33.33333333333333%;
}
}
Я изучал исходный код, и эта часть заставляет меня думать, что он должен работать и с backgroundImage:
К сожалению, это не работает, и результатом является строковый объект (или значения конкатенированного массива) в выводе CSS.
Я не могу представить, как variant
функция будет полезна здесь, как и предполагали люди. Я пробовал использоватьsystem
функции, но я просто не могу понять документацию. ВResponsiveValue
type дает мне подсказку, но мне хочется ползать в темноте, когда я пытаюсь понять внутренности.
В конечном счете, я хотел бы использовать "объект точек останова" (или массив) с любой настраиваемой опорой, которая мне нравится, например:
<Box
myProp={[
default: 'foo',
sm: 'bar',
]}
/>
Примечание. Я узнал (из опыта), что вы можете просто использовать версию "массива точек останова" (без установки точек останова в теме и передачи ее поставщику), и это сопоставит значение с первыми двумя точками останова по умолчанию (не уверен откуда они берутся), но если вы хотите использовать объект с ключами, вам нужно использовать ThemeProvider
с объектом темы с вашими собственными точками останова.
Примечание 2: я могу понять документацию по стилизованной системе до этого момента: https://styled-system.com/custom-props. Когда я приезжаю сюда, я чувствую, что это то, что я ищу, но я не могу понять пример, объяснение меня еще больше смущает, и я не могу найти никаких примеров в Интернете.
Примечание 3: Spectrum Chat имеет системный канал со стилем, и автор библиотеки находится там, но, к сожалению, мне не удалось отправить туда никаких сообщений (постоянная сетевая ошибка)
2 ответа
Итак, согласно документации (https://styled-system.com/custom-props/), чтобы создать настраиваемую опору (или, в данном случае, заменить существующую), вы должны использоватьsystem
полезность. Поскольку я не являюсь пользователем этой библиотеки (styled-system
), Я не уверен на 100%, что это правильный подход, но я протестировал ваш пример кода и, похоже, он работает так, как вы хотели.
Объявление компонента (оно также работает с такими объектами, как вы хотели) с массивом:
<ResponsiveImageBox
color="white"
backgroundImage={[
"https://placekitten.com/300/80",
"https://placekitten.com/500/80"
]}
>
Box 8
</ResponsiveImageBox>
с объектами:
<ResponsiveImageBox
color="white"
backgroundImage={{
default: "https://placekitten.com/300/80",
sm: "https://placekitten.com/500/80"
}}
>
Box 8
</ResponsiveImageBox>
А это код компонента:
export const ResponsiveImageBox = styled(Box)(
({ myCustomProp }) => {
return css`
${system({
backgroundImage: {
property: "backgroundImage",
transform: value => `url(${value})`
}
})}
`
});
Как вы можете видеть в примерах 4, 5 и 8 ( https://stackblitz.com/edit/styled-system-mccqje?file=Examples.tsx), я также сделал это дляborder-radius
атрибут с простым переименованием опоры и просто указанием того, какой атрибут css я хотел изменить (property
), поэтому добавлять transform
поскольку значение останется прежним.
export const ExtendedBox2 = styled(Box)<ExtendedBoxProps>`
background-position: center;
${system({
myCustomProp: {
property: "border-radius"
}
})}
`;
Взгляните и убедитесь, что это то, что вы искали!:)
Я знаю, что вы уже отметили его как решенное, и подход Эдуардо определенно работает. Однако другой способ сделать это «из коробки» - использовать псевдонимы, чтобы вы могли использовать объекты вместо массивов (источник: https://styled-system.com/responsive-styles/):
// theme.js
const breakpoints = ['40em', '52em', '64em', '80em']
// aliases
breakpoints.sm = breakpoints[0]
breakpoints.md = breakpoints[1]
breakpoints.lg = breakpoints[2]
breakpoints.xl = breakpoints[3]
export default {
breakpoints,
}
// ResponsiveImageBox.js
<ResponsiveImageBox
color="white"
backgroundImage={{
md: "https://placekitten.com/300/80",
sm: "https://placekitten.com/500/80"
}}
>
Box 8
</ResponsiveImageBox>