React Adminで画像の説明文をオーバレイで表示させる

管理画面をサクッと作れるReact Adminで、画像の説明を画像に重ねて表示させたいケースがあったので、備忘録的にメモしていきます。

結論↓

import React from 'react';
import { Box, Typography } from '@mui/material';
import { ImageField, ImageFieldProps } from 'react-admin';

const imageStyles = {
  width: '100%',
  height: '100%',
  objectFit: 'contain',
};

const overlayStyles = {
  position: 'absolute',
  bottom: 0,
  left: 0,
  width: '100%',
  color: 'white',
  backgroundColor: 'rgba(0, 0, 0, 0.5)',
  padding: '10px',
  boxSizing: 'border-box',
  display: 'flex',
  alignItems: 'center',
};

type CustomImageFieldProps = {
  overlayText?: string;
} & ImageFieldProps;

const CustomImageField: React.FC<CustomImageFieldProps> = (props) => (
  <Box sx={{ position: 'relative', width: '100%', height: 200, marginBottom: 2 }}>
    <ImageField
      {...props}
      sx={{ '& .RaImageField-image': imageStyles }}
    />
    {props.overlayText && (
      <Box sx={overlayStyles}>
        <Typography variant='subtitle1'>{props.overlayText}</Typography>
      </Box>
    )}
  </Box>
);

export default CustomImageField;

解説

今回はデフォルトのImage Fieldをカスタムして作るでImage Fieldをインポートしています。

import { ImageField, ImageFieldProps } from 'react-admin';

    <ImageField
      {...props}
      sx={{ '& .RaImageField-image': imageStyles }}
    />

共通のスタイルを設定します。

公式では、スタイルをオーバライドするときはクラス名を指定して、スタイルを渡すことで適用できるとあるので、& .RaImageField-imageに対してスタイルを適用させます。 なお、Image Fileldは配列ごと画像のリソースを渡すこともできるのですが、その場合は& .RaImageField-listを指定します。

コンポーネントは通常のclassNameプロパティを受け入れます。プロパティのおかげで、内部コンポーネントの多くのスタイルをオーバーライドすることもできます。

marmelab.com

const imageStyles = {
  width: '100%',
  height: '100%',
  objectFit: 'contain',
};

    <ImageField
      {...props}
      sx={{ '& .RaImageField-image': imageStyles }} // ここでimageStylesを渡す
    />

propsで受け取れるようにしたoverlayTextのプロパティをMUIのTypographyで表示させます。 スタイルは、親に設定したposition: relativeを基準とするために、子要素にabsoluteを当ててテキストを配置します。背景色は透明度0.5のブラックを指定してその中に白テキストで表示するようにしました。

const overlayStyles = {
  position: 'absolute',
  bottom: 0,
  left: 0,
  width: '100%',
  color: 'white',
  backgroundColor: 'rgba(0, 0, 0, 0.5)',
  padding: '10px',
  boxSizing: 'border-box',
  display: 'flex',
  alignItems: 'center',
};



    {props.overlayText && (
      <Box sx={overlayStyles}>
        <Typography variant='subtitle1'>{props.overlayText}</Typography>
      </Box>

まとめ

Image Fieldをカスタマイズする形でテキストを画像に重ねて表示する実装でした。

React Adminではデフォルトのコンポーネントが多種多様で、使い勝手はいいですが、それをベースにカスタムすることでさらに柔軟性の高いコンポーネントが作れます。

参考リンク

marmelab.com