Как я могу переопределить глубокие элементы ExpansionPanelSummary с помощью styled-компонентов? - PullRequest
1 голос
/ 30 марта 2019

Используя документы / примеры для переопределения стилей UI материалов с помощью styled-компонентов, мне удалось стилизовать корневой и "более глубокие элементы" в ExpansionPanel и ExpansionPanelDetails.

Однако, когда я использую ту же технику для возврата переопределенной ExpansionPanelSummary из функции, переданной в styled(), ExpansionPanelSummary перемещается в DOM, и весь ExpansionPanel больше не отображается правильно.

Рассматриваемая методика применительно к ExpansionPanel (это работает, как и ожидалось, для контейнера ExpansionPanel):

import MUIExpansionPanel from '@material-ui/core/ExpansionPanel';

export const ExpansionPanel = styled(props => (
  <MUIExpansionPanel
    classes={{expanded: 'expanded'}}
    {...props}
  />
))`
  && {
    ...root style overrides
  }
  &&.expanded {
    ...expanded style overrides
  }
`;

Типичный DOM (с сокращенными именами классов) для ExpansionPanel и друзей:

<div class="MuiExpansionPanel...">
  <div class="MuiExpansionPanelSummary..." />
  <div class="MuiCollapse-container...>
    <div class="MuiCollapse-wrapper...>
      <div class="MuiCollapse-wrapperInner...>
        <div class="MuiExpansionPanelDetails..." />
      </div>
    </div>
  </div>
</div>

DOM, когда я применяю вышеописанную технику к ExpansionPanelSummary:

<div class="MuiExpansionPanel...">
  <div class="MuiCollapse-container...>
    <div class="MuiCollapse-wrapper...>
      <div class="MuiCollapse-wrapperInner...>
        <div class="MuiExpansionPanelSummary..." />
        <div class="MuiExpansionPanelDetails..." />
      </div>
    </div>
  </div>
</div>

Для полноты вот минимальное повторение того, что я делаю с ExpansionPanelSummary, которое вызывает переключение DOM:

export const ExpansionPanelSummary = styled(props => (
  <MUIExpansionPanelSummary
    {...props}
  />
))``;

А у меня JSX стандартная ExpansionPanel настройка:

<ExpansionPanel>
  <ExpansionPanelSummary>
    Summary Label
  </ExpansionPanelSummary>
  <ExpansionPanelDetails>
    <div>Some Content</div>
  </ExpansionPanelDetails>
</ExpansionPanel>

1 Ответ

1 голос
/ 30 марта 2019

Эта трудность не зависит от использования стилевых компонентов и просто связана с переносом ExpansionPanelSummary в другой компонент.

Вы можете аналогичным образом воспроизвести это в следующей упаковке ExpansionPanelSummary:

const MyCustomSummary = props => {
  return (
    <ExpansionPanelSummary {...props} expandIcon={<ExpandMoreIcon />}>
      <Typography>{props.text}</Typography>
    </ExpansionPanelSummary>
  );
};

Существует несколько групп компонентов, подобных этой, где родительский компонент Material-UI ищет определенный тип дочернего компонента и обрабатывает его специально. Например, вы можете найти следующий блок в ExpansionPanel

      if (isMuiElement(child, ['ExpansionPanelSummary'])) {
        summary = React.cloneElement(child, {
          disabled,
          expanded,
          onChange: this.handleChange,
        });
        return null;
      }

К счастью, Material-UI имеет простой способ сказать, что ваш пользовательский компонент должен обрабатываться так же, как и конкретный компонент Material-UI, через свойство muiName:

MyCustomSummary.muiName = "ExpansionPanelSummary";

или в вашем случае это будет выглядеть так:

export const ExpansionPanelSummary = styled(props => (
  <MUIExpansionPanelSummary
    {...props}
  />
))``;

ExpansionPanelSummary.muiName = "ExpansionPanelSummary";

Edit Custom ExpansionPanelSummary

...