ディバイダー - Vibe Coding Showcase

ディバイダー

コンテンツを視覚的に区切る線要素。セクション間の境界を明確にし、情報の階層構造を表現。

デザインプレビュー

基本的なディバイダー

コンテンツの区切りに使用します

次のセクション

サイズバリエーション

Small

Medium

Large

バリアント

Solid

Dashed

Dotted

カラーバリエーション

テキスト付きディバイダー

または
セクション 1
終了

垂直ディバイダー

左側
右側
破線

装飾的なディバイダー

セクションディバイダー

新しいセクション

ここから新しい内容が始まります

機能紹介

ディバイダーの特徴

多様なスタイル

実線、破線、点線、装飾的なデザインから選択可能

柔軟な配置

水平・垂直方向、テキスト付き、位置調整に対応

セマンティック

意味のある区切りを提供し、アクセシビリティに配慮

AI活用ガイド

アニメーションディバイダー

プロンプト例:

スクロールに連動するアニメーションディバイダーを作成してください。波形、パーティクル、グラデーション効果、視差効果、インタラクティブな要素を含め、ページの雰囲気を演出する装飾的な区切り線を実装してください。

コンテキストディバイダー

プロンプト例:

周囲のコンテンツに応じて自動的にスタイルを調整するスマートディバイダーを開発してください。セクションの重要度、コンテンツの種類、ユーザーの読書進捗に基づいて、太さ・色・スタイルを動的に変更してください。

ストーリーディバイダー

プロンプト例:

ナラティブコンテンツ用の特別なディバイダーシステムを実装してください。章の区切り、時間経過の表現、場面転換のエフェクト、読者の注意を引く装飾要素を含め、読書体験を向上させてください。

実装コード

ファイルサイズ: 6.3KB TypeScript

コンポーネント実装

import React from 'react';
import type { BaseDividerProps } from '../types';

interface DividerProps extends BaseDividerProps {
  className?: string;
  children?: React.ReactNode;
}

export const Divider: React.FC<DividerProps> = ({
  orientation = 'horizontal',
  variant = 'solid',
  size = 'md',
  color = 'gray',
  align = 'center',
  className = '',
  children,
}) => {
  // サイズに基づくスタイル
  const getSizeClasses = () => {
    const sizes = {
      sm: orientation === 'horizontal' ? 'h-px' : 'w-px',
      md: orientation === 'horizontal' ? 'h-0.5' : 'w-0.5',
      lg: orientation === 'horizontal' ? 'h-1' : 'w-1',
    };
    return sizes[size as keyof typeof sizes] || sizes.md;
  };

  // カラーに基づくスタイル
  const getColorClasses = () => {
    const colors = {
      gray: 'bg-gray-300 border-gray-300',
      blue: 'bg-blue-500 border-blue-500',
      green: 'bg-green-500 border-green-500',
      red: 'bg-red-500 border-red-500',
      purple: 'bg-purple-500 border-purple-500',
    };
    return colors[color as keyof typeof colors] || colors.gray;
  };

  // バリアントに基づくスタイル
  const getVariantClasses = () => {
    if (variant === 'dashed') {
      return orientation === 'horizontal'
        ? 'border-t-2 border-dashed bg-transparent'
        : 'border-l-2 border-dashed bg-transparent';
    } else if (variant === 'dotted') {
      return orientation === 'horizontal'
        ? 'border-t-2 border-dotted bg-transparent'
        : 'border-l-2 border-dotted bg-transparent';
    }
    return '';
  };

  // テキスト位置の調整
  const getAlignClasses = () => {
    const alignments = {
      start: 'justify-start',
      center: 'justify-center',
      end: 'justify-end',
    };
    return alignments[align as keyof typeof alignments] || alignments.center;
  };

  const dividerClasses = `
    ${getSizeClasses()}
    ${getColorClasses()}
    ${getVariantClasses()}
    ${orientation === 'vertical' ? 'h-full' : 'w-full'}
  `.trim();

  // テキスト付きディバイダー
  if (children) {
    return (
      <div
        className={`
          flex items-center
          ${orientation === 'horizontal' ? 'flex-row' : 'flex-col'}
          ${getAlignClasses()}
          ${className}
        `}
      >
        <div
          className={`
            ${dividerClasses}
            ${orientation === 'horizontal' ? 'flex-1' : 'flex-1'}
          `}
        />
        <span
          className={`
            px-4 py-1 text-sm text-gray-600
            ${orientation === 'horizontal' ? 'mx-4' : 'my-4'}
          `}
        >
          {children}
        </span>
        <div
          className={`
            ${dividerClasses}
            ${orientation === 'horizontal' ? 'flex-1' : 'flex-1'}
          `}
        />
      </div>
    );
  }

  // シンプルなディバイダー
  return <div className={`${dividerClasses} ${className}`} />;
};

// 装飾的なディバイダー
export const DecorativeDivider: React.FC<{
  type?: 'dots' | 'wave' | 'gradient';
  className?: string;
}> = ({ type = 'dots', className = '' }) => {
  if (type === 'dots') {
    return (
      <div className={`flex items-center justify-center py-4 ${className}`}>
        <div className="flex space-x-2">
          <div className="w-2 h-2 bg-gray-400 rounded-full"></div>
          <div className="w-2 h-2 bg-gray-400 rounded-full"></div>
          <div className="w-2 h-2 bg-gray-400 rounded-full"></div>
        </div>
      </div>
    );
  }

  if (type === 'wave') {
    return (
      <div className={`w-full py-4 ${className}`}>
        <svg
          className="w-full h-6"
          viewBox="0 0 1200 24"
          fill="none"
          xmlns="http://www.w3.org/2000/svg"
        >
          <path
            d="M0 12C150 12 150 0 300 0C450 0 450 12 600 12C750 12 750 0 900 0C1050 0 1050 12 1200 12"
            stroke="#D1D5DB"
            strokeWidth="2"
          />
        </svg>
      </div>
    );
  }

  if (type === 'gradient') {
    return (
      <div className={`w-full h-1 bg-gradient-to-r from-transparent via-gray-300 to-transparent ${className}`} />
    );
  }

  return null;
};

// セクションディバイダー
export const SectionDivider: React.FC<{
  title: string;
  subtitle?: string;
  icon?: React.ReactNode;
  className?: string;
}> = ({ title, subtitle, icon, className = '' }) => {
  return (
    <div className={`relative py-8 ${className}`}>
      <div className="absolute inset-0 flex items-center">
        <div className="w-full border-t border-gray-300"></div>
      </div>
      <div className="relative flex justify-center">
        <div className="bg-white px-6 flex items-center">
          {icon && <span className="mr-3">{icon}</span>}
          <div className="text-center">
            <h3 className="text-lg font-semibold text-gray-900">{title}</h3>
            {subtitle && <p className="text-sm text-gray-600">{subtitle}</p>}
          </div>
        </div>
      </div>
    </div>
  );
};

// ディバイダーのデモコンポーネント
export const DividerDemo: React.FC = () => {
  return (
    <div className="space-y-12">
      {/* 基本的なディバイダー */}
      <div className="space-y-4">
        <h3 className="text-lg font-semibold">基本的なディバイダー</h3>
        <div className="space-y-4">
          <Divider />
          <div className="p-4 bg-gray-50 rounded">
            <p className="mb-4">コンテンツの区切りに使用します</p>
            <Divider />
            <p className="mt-4">次のセクション</p>
          </div>
        </div>
      </div>

      {/* サイズバリエーション */}
      <div className="space-y-4">
        <h3 className="text-lg font-semibold">サイズバリエーション</h3>
        <div className="space-y-4">
          <div>
            <p className="text-sm text-gray-600 mb-2">Small</p>
            <Divider size="sm" />
          </div>
          <div>
            <p className="text-sm text-gray-600 mb-2">Medium</p>
            <Divider size="md" />
          </div>
          <div>
            <p className="text-sm text-gray-600 mb-2">Large</p>
            <Divider size="lg" />
          </div>
        </div>
      </div>

      {/* バリアント */}
      <div className="space-y-4">
        <h3 className="text-lg font-semibold">バリアント</h3>
        <div className="space-y-4">
          <div>
            <p className="text-sm text-gray-600 mb-2">Solid</p>
            <Divider variant="solid" />
          </div>
          <div>
            <p className="text-sm text-gray-600 mb-2">Dashed</p>
            <Divider variant="dashed" />
          </div>
          <div>
            <p className="text-sm text-gray-600 mb-2">Dotted</p>
            <Divider variant="dotted" />
          </div>
        </div>
      </div>

      {/* カラー */}
      <div className="space-y-4">
        <h3 className="text-lg font-semibold">カラーバリエーション</h3>
        <div className="space-y-4">
          <Divider color="gray" />
          <Divider color="blue" />
          <Divider color="green" />
          <Divider color="red" />
          <Divider color="purple" />
        </div>
      </div>

      {/* テキスト付き */}
      <div className="space-y-4">
        <h3 className="text-lg font-semibold">テキスト付きディバイダー</h3>
        <div className="space-y-4">
          <Divider>または</Divider>
          <Divider align="start">セクション 1</Divider>
          <Divider align="center">中央配置</Divider>
          <Divider align="end">右寄せ</Divider>
        </div>
      </div>

      {/* 垂直ディバイダー */}
      <div className="space-y-4">
        <h3 className="text-lg font-semibold">垂直ディバイダー</h3>
        <div className="flex items-center h-20 gap-4">
          <span>左側</span>
          <Divider orientation="vertical" />
          <span>右側</span>
          <Divider orientation="vertical" variant="dashed" />
          <span>破線</span>
        </div>
      </div>

      {/* 装飾的なディバイダー */}
      <div className="space-y-4">
        <h3 className="text-lg font-semibold">装飾的なディバイダー</h3>
        <DecorativeDivider type="dots" />
        <DecorativeDivider type="wave" />
        <DecorativeDivider type="gradient" />
      </div>

      {/* セクションディバイダー */}
      <div className="space-y-4">
        <h3 className="text-lg font-semibold">セクションディバイダー</h3>
        <SectionDivider
          title="新しいセクション"
          subtitle="ここから新しい内容が始まります"
        />
        <SectionDivider
          title="機能紹介"
          icon={
            <svg className="w-5 h-5 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 10V3L4 14h7v7l9-11h-7z" />
            </svg>
          }
        />
      </div>
    </div>
  );
};

export default Divider;

使用例

// 基本的な使用例
import { Divider, DecorativeDivider, SectionDivider } from './divider';

function App() {
  return (
    <div>
      {/* 基本的なディバイダー */}
      <Divider />
      
      {/* サイズとカラー */}
      <Divider size="lg" color="blue" />
      
      {/* バリアント */}
      <Divider variant="dashed" />
      <Divider variant="dotted" />
      
      {/* テキスト付き */}
      <Divider>または</Divider>
      <Divider align="start">セクション 1</Divider>
      <Divider align="end">終了</Divider>
      
      {/* 垂直ディバイダー */}
      <div className="flex items-center h-20">
        <span>左側</span>
        <Divider orientation="vertical" />
        <span>右側</span>
      </div>
      
      {/* 装飾的なディバイダー */}
      <DecorativeDivider type="dots" />
      <DecorativeDivider type="wave" />
      <DecorativeDivider type="gradient" />
      
      {/* セクションディバイダー */}
      <SectionDivider
        title="新しいセクション"
        subtitle="ここから新しい内容が始まります"
      />
      
      {/* アイコン付きセクション */}
      <SectionDivider
        title="機能紹介"
        icon={<StarIcon />}
      />
      
      {/* カスタムスタイル */}
      <Divider 
        className="my-8" 
        size="md"
        color="purple"
      />
    </div>
  );
}