LoginSignup
1
0

【MUI】Accordionコンポーネントの開閉状態を取得する

Posted at

概要

Accordion コンポーネントを使用している UI で、その開閉状態に関わらず全体の height を 100vh に合わせる必要がありました。
Accodion の開閉状態を取得する方法で少し調べる必要があったので書き記しておきます。

状況

下図のように水色の枠の部分 (TextBox コンポーネント) は Accodion を使用していて、開閉が可能になっています。

各コンポーネントの高さの指定を厳密にするために、100vhから自身以外のコンポーネントの高さを引いた値を設定しています。
Accodion の開閉状態に合わせてピンク色の枠の部分 (Body コンポーネント) の高さを変える必要がありました。
useState で状態を取得しようと思いましたが、どこから取れるのかが不明でした。

解決

ChatGPTに質問してみたところ AccordionSummary の onClick で状態を反転させる方法を提示してくれましたが、こちらは期待する効果が得られませんでした。
公式ドキュメントをよくよく見ていくとどうやら Accodion の onChange イベントが expanded というプロパティを持っていることが判明し、以下の実装になりました。

Pane.tsx
// 親である Pane コンポーネントで state を定義する
const [isAccordionOpen, setIsAccordionOpen] = useState(false)

// 水色枠 (TextBox) には props として isAccordionOpen, setIsAccordionOpen を渡す
// ピンク色枠 (Body) には props として isAccordionOpen を渡す

TextBox コンポーネントでは Accodion の onChange イベント内で expanded の値で state を更新します。
ちなみにややこしいのですが Accordion の開閉時それぞれの height は以下のように設定します。

  • 閉じた状態 : AccordionSummaryminHeight
  • 開いた状態 : AccordionDetailsheight
TextBox.tsx
...

return (
    <Accordion
      disableGutters
      onChange={(_event: React.SyntheticEvent, expanded: boolean) =>
        setIsAccordionOpen(expanded)
      }
    >
      <AccordionSummary
        expandIcon={<ExpandMoreIcon fontSize="small" />}
        aria-controls="panel1a-content"
        sx={{ minHeight: 'var(--column-close-input-height)' }}
      ></AccordionSummary>
      <AccordionDetails>
        <Box sx={inputStyle}>
          <FormControl
            variant="outlined"
            sx={{
              width: '100%',
              display: 'flex',
              flexDirection: 'column-reverse',
            }}
          >
            <OutlinedInput
              id="text-input"
              value={messageValue}
              multiline
              fullWidth
              rows={7}
              onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
                setMessageValue(event.target.value)
              }}
              endAdornment={
                <InputAdornment position="end">
                  <IconButton onClick={sending} disabled={messageValue === ''}>
                    <SendIcon fontSize="small" />
                  </IconButton>
                </InputAdornment>
              }
            />
          </FormControl>
        </Box>
      </AccordionDetails>
    </Accordion>
  )

Body コンポーネントでは isAcorrdionOpen の値に応じて、よしなに height を書き換える。

Body.tsx
  const bodyHeight = isAcorrdionOpen
    ? 'calc(100vh - var(--column-header-height) - var(--column-open-input-height))'
    : 'calc(100vh - var(--column-header-height) - var(--column-close-input-height))'

参考資料

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0