View on GitHub

ページサイズの動的調整

Home

ページサイズの動的調整

定数の定義

src/frontend/src/constants/styles.ts

/**
 * スタイル関連の定数
 */
export const STYLES = {
  ......
  // 映画リスト関連
  ......
  LIST_MOVIE_PER_PAGE_DEFAULT: 5,
  // ↓追加
  LIST_MOVIE_CARD_WIDTH: 128,
  LIST_MOVIE_CARD_GAP: 8,
  // ↑追加
  ......
} as const;

コンポーネントの作成

映画リストコンポーネント

src/frontend/src/app/components/list/ListMovie.tsx

"use client";

import { useEffect, useState, useCallback, useRef } from "react"; // <- useRefを追加
......
/**
 * 映画リストコンポーネント
 */
const ListMovie = (props: Props) => {
  const [movies, setMovies] = useState<Movie[]>(props.movies);
  const [perPage, setPerPage] = useState<number>(STYLES.LIST_MOVIE_PER_PAGE_DEFAULT);
  const [currentMovies, setCurrentMovies] = useState<Movie[]>([]);
  const [currentPage, setCurrentPage] = useState(0);

  const observerRef = useRef<ResizeObserver | null>(null); // <- 追加
  ......
  /**
   * ページ変更ハンドラ
   * @param page - 移動先のページ番号
   */
  const handlePageChange = useCallback(
    ......
  );

  // ↓追加
  const containerRef = useCallback((el: HTMLDivElement | null) => {
    if (observerRef.current) {
      observerRef.current.disconnect();
      observerRef.current = null;
    }
    if (!el) return;
    const observer = new ResizeObserver(([entry]) => {
      const width = entry.contentRect.width;
      const count = Math.max(
        1,
        Math.floor(
          (width + STYLES.LIST_MOVIE_CARD_GAP) /
            (STYLES.LIST_MOVIE_CARD_WIDTH + STYLES.LIST_MOVIE_CARD_GAP)
        )
      );
      setPerPage(count);
    });
    observer.observe(el);
    observerRef.current = observer;
  }, []);
  // ↑追加

  // 空の状態の表示
  if (movies.length === 0) {
    return <></>;
  }

  return (
    <>
      <div className={`${STYLES.LIST_MOVIE_LABEL_PHRASE}`}>{props.phrase}</div>
      <div className={`${STYLES.LIST_MOVIE}`}>
        ...(略)...
        <div className={`${STYLES.LIST_MOVIE_INSIDE}`} ref={containerRef}>  {/* <- refを追加 */}
          ...(略)...
        </div>
      </div>
    </>
  );
};

export default ListMovie;

ブラウザで下記 URL にアクセスしてください。

サインインすると、映画リストが表示されます。また、ウィンドウサイズを変更すると、ページ内の映画件数が動的に調整されます。