【Next.js】「ページトップへスクロール」のコンポーネント【AIでコードのカスタマイズ可】
eyecatch

2024-06-24

2024-07-02

【Next.js】「ページトップへスクロール」のコンポーネント【AIでコードのカスタマイズ可】

UIコンポーネント配布

環境

  • Next.js(App Router) 14.2.4
  • React 18.3.1
  • TypeScript 5.5.2
  • @emotion/react 11.11.4

イメージ

コード

  • PageTop.tsx
/** @jsxImportSource @emotion/react */
"use client";
import { css, SerializedStyles } from "@emotion/react";
import { ReactNode, useCallback } from "react";

export type CSSProps = SerializedStyles;

type UpChevronIconProps = {
  className?: string;
  cssOverride?: CSSProps;
  color?: string;
  weight?: number;
  size?: number;
};

export function UpChevronIcon({
  className,
  cssOverride,
  color = "#444444",
  weight = 2,
  size = 1,
}: UpChevronIconProps) {
  const borderSize = `${weight / 10}em`;

  return (
    <span
      css={[
        cssOverride,
        css`
          display: inline-block;
          vertical-align: middle;
          color: ${color};
          width: ${size}em;
          height: ${size}em;
          line-height: ${size}em;
          border-width: ${borderSize};
          border-color: ${color};
          border-style: solid;
          border-left: 0;
          border-bottom: 0;
          box-sizing: border-box;
          transform: translateY(25%) rotate(-45deg);
        `,
      ]}
      className={"" + (className ? ` ${className}` : "")}
    />
  );
}

export type PageTopProps = {
  color?: string;
  bgColor?: string;
  iconWeight?: number;
  iconSize?: number;
  cssOverride?: CSSProps;
  children?: ReactNode;
  clickArea?: "container" | "contents";
};

export function PageTop({
  color = "#FFFFFF",
  bgColor = "#444444",
  iconWeight = 2,
  iconSize = 1,
  cssOverride,
  children,
  clickArea = "container",
}: PageTopProps) {
  // スクロールトップするハンドラー
  const handleScrollToTop = useCallback(() => {
    window.scrollTo({ top: 0, behavior: "smooth" });
  }, []);

  return (
    <div
      onClick={clickArea === "container" ? handleScrollToTop : undefined}
      css={css`
        ${cssOverride};
        width: 100%;
        background-color: ${bgColor};
        ${clickArea === "container"
          ? css`
              cursor: pointer;
            `
          : css``}
      `}
    >
      <button
        onClick={clickArea === "contents" ? handleScrollToTop : undefined}
        css={css`
          background-color: ${bgColor};
          border: none;
          display: flex;
          justify-content: center;
          align-items: center;
          margin: 0 auto;
          padding: 1rem 0;
          cursor: pointer;
          ${children
            ? css`
                column-gap: 0.75rem;
              `
            : css``}
        `}
      >
        <UpChevronIcon color={color} weight={iconWeight} size={iconSize} />
        {children && (
          <div
            css={css`
              color: ${color};
            `}
          >
            {children}
          </div>
        )}
      </button>
    </div>
  );
}

サンプルコード(使用例)


  • page.tsx (※ <body>タグなどページ全体の横余白(マージンやパディング)がゼロになっている前提)
import { PageTop } from "@/components/PageTop";

export default function Page() {
  return (
    <main>
      <h2>「ページトップ」へスクロールするコンポーネントを作成してみよう!</h2>
      <div
        style={{
          height: "150vh",
          border: "4px solid #666666",
          padding: "8px",
          marginLeft: "16px",
          marginRight: "16px",
          marginBottom: "64px",
        }}
      >
        これはスクロールを試すための余白用のテキストです。
        これはスクロールを試すための余白用のテキストです。
        これはスクロールを試すための余白用のテキストです。
      </div>
      <div
        style={{
          marginBottom: "32px",
        }}
      >
        <section>
          <h3>アイコンのみバージョン</h3>
          <p>かつ クリックできる範囲は「コンポーネント全体」</p>
          <PageTop
            clickArea="container"
            color="#FFFFFF"
            bgColor="#444444"
            iconWeight={2.5}
            iconSize={1}
          />
        </section>
        <section>
          <h3>アイコンとテキストありバージョン</h3>
          <p>かつ クリックできる範囲は「コンテンツ」</p>
          <PageTop
            clickArea="contents"
            color="#FFFFFF"
            bgColor="#444444"
            iconWeight={2}
            iconSize={0.75}
          >
            <span>ページのトップへ</span>
          </PageTop>
        </section>
      </div>
    </main>
  );
}

以上です。 最後まで読んでいただきありがとうございました!

AIでコードをカスタマイズ

リリースノートはこちら
(プロンプト作成エディタ v1.0.1)

今回の記事に掲載されているコードを、以下のフォームでカスタマイズできます。
(例: コードの言語やフレームワーク、ライブラリを変更したい場合など)

各内容を入力すると、自動的に「AIによるコード生成を行うためのプロンプト」を作成します。
作成されたプロンプトはボタンを押してコピーし、ChatGPTなどお使いの生成AIに貼り付けてご利用ください。

※必ずしも、プロンプトで生成されるコードが期待通りに生成されるとは限りません。予めご了承ください。

変更したい言語・フレームワーク・ライブラリ等の、「名称」「バージョン」を入力してください。

変更前
変更後

プロジェクトのコーディングルールに合わせたい場合などにご利用できます。

※より生成の精度を最適化するため、プロンプトは予告なくアップデートされる場合があります。

UIコンポーネント配布 の関連記事

関連記事はありません

コメント(0件)

この記事にはまだコメントがありません。

自己紹介

logo

かわいち

Webエンジニアです! 普段から効率良く開発できるように心がけています。 また、趣味でもプログラミングをしており、モノづくりが好きです。 このブログでは、プログラミングに役立つコトを日々発信しています!