Как использовать адаптивный реквизит в стиле стилевой системы

Могу ли я использовать 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>
Другие вопросы по тегам