Правильная композиция стилей композиции с реагировать на выбор V2

Мы хотим настроить базовый компонент Select с общим стилем для всего приложения. К сожалению, на данный момент есть необходимость в небольшой настройке, эти стили будут игнорироваться, если специально не подготовлены для этого в базовом компоненте. Это то, что я придумал, но это, на мой взгляд, довольно уродливо и подвержено ошибкам. Поэтому мне интересно, есть ли лучший способ, который я мог бы пропустить?

Этот подход был бы особенно болезненным, если бы потребовался какой-то нечастый компонент, который использует базовый, но имеет свой собственный стиль улучшения, который необходимо настроить от родителя.

export interface ISelectControlProps<OptionType = {}>
  extends Props<OptionType> {
  width?: number
  minWidth?: number
}

const composeStyles = (outerStyles: StylesConfig = {}) => ({
  ...outerStyles,
  control: (base, state) => {
    const {
      selectProps: { width, minWidth },
    } = state
    const controlStyles = {
      ...base,
      border: `1px solid ${Colors.greyMiddle}`,
      margin: Spacing.MarginAroundFormComponents,
      width: width !== undefined ? `${width}rem` : '100%',
      minWidth: minWidth !== undefined ? `${minWidth}rem` : '8rem',
    }
    return outerStyles.control
      ? outerStyles.control(controlStyles, state)
      : controlStyles
  },
  menu: (base, state) => {
    const {
      selectProps: { width },
    } = state
    const menuStyles = {
      ...base,
      zIndex: 20,
      color: Colors.black,
      width: width !== undefined ? `${width}rem` : '100%',
    }
    return outerStyles.menu ? outerStyles.menu(menuStyles, state) : menuStyles
  },
})

export class SelectControl<OptionType> extends React.Component<
  ISelectControlProps<OptionType>
> {
  render() {
    return <Select {...this.props} styles={composeStyles(this.props.styles)} />
  }
}

Обратите внимание, что из самого компонента я беру любые стили, которые были переданы из родительского, и использую их для композиции с нашими базовыми стилями.

Обновить

Я подготовил пример кода и коробки. Это работает, но в случае BaseSelect это просто кажется довольно уродливым, и было много головной боли, чтобы понять, как собрать его там. Обратите внимание, что цвета преднамеренно безобразны, чтобы показать случай:)

https://codesandbox.io/s/zk6jpnm613

0 ответов

Другие вопросы по тегам