🥐
React Wrap Balancer でタイトルを読みやすく
はじめに
- React Wrap Blancer はさまざまなビューポートサイズでタイトルを読みやすくするシンプルな React コンポーネントです。
- タイトルを複数行で表示する場合、折返し位置を改善し、バランスのとれた見た目にします。
- 以下は、サイト[1]に公開されているデモで、左が改善前で、改善後です。
以下に作業コードおいてみます。
作業環境の構築
作業するプロジェクトを新規に作成していきます。
長いので、折りたたんでおきます。
作業環境の構築
$ pnpm create next-app@latest next-react-wrap-balancer-sample --typescript --eslint --import-alias "@/*" --src-dir --use-pnpm --tailwind --app
$ cd next-react-wrap-balancer-sample
以下の通り不要な設定を削除し、プロジェクトの初期環境を構築します。
src/app/globals.css
@tailwind base;
@tailwind components;
@tailwind utilities;
src/app/page.tsx
export default function Home() {
return (
<main className="text-lg">
テストページ
</main>
)
}
src/app/layout.tsx
import "./globals.css";
export const metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="ja">
<body className="">{children}</body>
</html>
);
}
tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./src/components/**/*.{js,ts,jsx,tsx,mdx}",
"./src/app/**/*.{js,ts,jsx,tsx,mdx}",
],
plugins: [],
};
tailwind.config.js
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
+ "baseUrl": ".",
"paths": {
"@/*": ["./src/*"],
+ "@app/*": ["./src/app/*"],
+ "@components/*": ["./src/components/*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}
コミットします。
$ pnpm build
$ git add .
$ git commit -m "新規にプロジェクトを作成し, 作業環境を構築"
パッケージのインストール
パッケージをインストールします。
$ pnpm add react-wrap-balancer
使用方法
<Blander>
タグで囲むことで、バランスの調整ができます。以下で、バランスしている、バランスしていない、2つの例を記述しています。
あまり意味はないですが、export const runtime = "edge"
を設定し edge で動作させています。
src/app/page.tsx
import Balancer from "react-wrap-balancer";
export const runtime = "edge"
export default function Home() {
return (
<main>
<div className="mb-5 p-5">
<h1 className="text-xl font-bold">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis
malesuada nisl ut vehicula tincidunt.
</h1>
<p>
Lorem Ipsum is simply dummy text of the printing and typesetting
industry. Lorem Ipsum has been the industry{"'"}s standard dummy text
ever since the 1500s, when an unknown printer took a galley of type
and scrambled it to make a type specimen book. It has survived not
only five centuries, but also the leap into electronic typesetting,
remaining essentially unchanged. It was popularised in the 1960s with
the release of Letraset sheets containing Lorem Ipsum passages, and
more recently with desktop publishing software like Aldus PageMaker
including versions of Lorem Ipsum.
</p>
</div>
<div className="p-5">
<h1 className="text-xl font-bold">
<Balancer>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis
malesuada nisl ut vehicula tincidunt.
</Balancer>
</h1>
<p>
<Balancer>
Lorem Ipsum is simply dummy text of the printing and typesetting
industry. Lorem Ipsum has been the industry{"'"}s standard dummy
text ever since the 1500s, when an unknown printer took a galley of
type and scrambled it to make a type specimen book. It has survived
not only five centuries, but also the leap into electronic
typesetting, remaining essentially unchanged. It was popularised in
the 1960s with the release of Letraset sheets containing Lorem Ipsum
passages, and more recently with desktop publishing software like
Aldus PageMaker including versions of Lorem Ipsum.
</Balancer>
</p>
</div>
</main>
);
}
ビルドします。
$ pnpm build
> next-react-wrap-balancer-sample@0.1.0 build /Users/hayato94087/Private/next-react-wrap-balancer-sample
> next build
- info Creating an optimized production build
- info Compiled successfully
- info Linting and checking validity of types
- info Collecting page data
- info Generating static pages (3/3)
- info Finalizing page optimization
Route (app) Size First Load JS
┌ ℇ / 1.02 kB 78.5 kB
└ ○ /favicon.ico 0 B 0 B
+ First Load JS shared by all 77.5 kB
├ chunks/597-ce4dfb0d334fe8ea.js 25.1 kB
├ chunks/7c8ed547-986ce5d4b54bc93e.js 50.5 kB
├ chunks/main-app-a19710ebb78d0d42.js 214 B
└ chunks/webpack-7af87f48bef51ca8.js 1.64 kB
Route (pages) Size First Load JS
─ ○ /404 182 B 75.5 kB
+ First Load JS shared by all 75.3 kB
├ chunks/framework-5cb727a20916d7ea.js 45 kB
├ chunks/main-7341becf2689f336.js 28.4 kB
├ chunks/pages/_app-33987be98293b80d.js 193 B
└ chunks/webpack-7af87f48bef51ca8.js 1.64 kB
ℇ (Streaming) server-side renders with streaming (uses React 18 SSR streaming or Server Components)
○ (Static) automatically rendered as static HTML (uses no initial props)
実行結果
実行させます。
$ pnpm start
時間かかりますが、しばらくすると画像が動きます。
コミットします。
コミット処理
$ pnpm build
$ git add .
$ git commit -m "react-wrap-balancerを導入"
パフォーマンス
パフォーマンスについてです。<Balancer>
はバランスのとれたテキストに変換処理をしているため、オーバーヘッドが発生します[1:1]。調整対象となるテキストや`<Balancer>のコンポーネントの数が増えると、オーバーヘッドが増えることが予想されます。
パフォーマンスの計測については公式のサイト[1:2]に記載されています。
まとめ
- React Wrap Blancer はさまざまなビューポートサイズでタイトルを読みやすくするシンプルな React コンポーネントです。
- タイトルを複数行で表示する場合、折返し位置を改善し、バランスのとれた見た目にします。
- 実装を通して動作を確認できました。
以下に作業コードおいてみます。
参考
Discussion