Tips & Tricks

Claude Code के साथ Designing and Implementing Modal Dialogs

Claude Code का उपयोग करके designing and implementing modal dialogs सीखें। Practical code examples शामिल हैं।

modal・ダイアlogの設計原則

modalはuserのध्यानを特定の操作に集मेंさせるUIpattern है।लेकिन、フォーカスmanagementやkeyボード操作、スクリーンリーダーsupportを怠ると、accessibilityの問題を引き起こし है।Claude Code का उपयोग करके、WAI-ARIA準拠のmodalを正しくimplementationでき है।

HTML dialog要素を使ったimplementation

> HTML標準のdialog要素を使ったmodalcomponentを作って。
> accessibilityとanimationにsupportして。
import { useRef, useEffect } from 'react';

interface DialogProps {
  open: boolean;
  onClose: () => void;
  title: string;
  children: React.ReactNode;
}

function Dialog({ open, onClose, title, children }: DialogProps) {
  const dialogRef = useRef<HTMLDialogElement>(null);

  useEffect(() => {
    const dialog = dialogRef.current;
    if (!dialog) return;

    if (open) {
      dialog.showModal();
    } else {
      dialog.close();
    }
  }, [open]);

  useEffect(() => {
    const dialog = dialogRef.current;
    if (!dialog) return;

    const handleClose = () => onClose();
    dialog.addEventListener('close', handleClose);

    const handleClick = (e: MouseEvent) => {
      if (e.target === dialog) onClose();
    };
    dialog.addEventListener('click', handleClick);

    return () => {
      dialog.removeEventListener('close', handleClose);
      dialog.removeEventListener('click', handleClick);
    };
  }, [onClose]);

  return (
    <dialog
      ref={dialogRef}
      aria-labelledby="dialog-title"
      className="rounded-xl shadow-2xl p-0 backdrop:bg-black/50 backdrop:backdrop-blur-sm
        max-w-lg w-full open:animate-fadeIn"
    >
      <div className="p-6">
        <div className="flex items-center justify-between mb-4">
          <h2 id="dialog-title" className="text-xl font-bold">{title}</h2>
          <button onClick={onClose} aria-label="Close"
            className="rounded-full p-1 hover:bg-gray-100">✕</button>
        </div>
        {children}
      </div>
    </dialog>
  );
}

confirmダイアlog

> 「Deleteしてよろしいですか?」の तरहなconfirmダイアlogをPromiseベースで使える तरहして。
import { createRoot } from 'react-dom/client';

interface ConfirmOptions {
  title: string;
  message: string;
  confirmLabel?: string;
  cancelLabel?: string;
  variant?: 'danger' | 'default';
}

function confirm(options: ConfirmOptions): Promise<boolean> {
  return new Promise((resolve) => {
    const container = document.createElement('div');
    document.body.appendChild(container);
    const root = createRoot(container);

    const handleClose = (result: boolean) => {
      root.unmount();
      container.remove();
      resolve(result);
    };

    root.render(
      <Dialog open={true} onClose={() => handleClose(false)} title={options.title}>
        <p className="text-gray-600 mb-6">{options.message}</p>
        <div className="flex justify-end gap-3">
          <button onClick={() => handleClose(false)}
            className="px-4 py-2 border rounded-lg hover:bg-gray-50">
            {options.cancelLabel ?? 'キャンセル'}
          </button>
          <button onClick={() => handleClose(true)}
            className={`px-4 py-2 rounded-lg text-white ${
              options.variant === 'danger' ? 'bg-red-600 hover:bg-red-700' : 'bg-blue-600 hover:bg-blue-700'
            }`}>
            {options.confirmLabel ?? 'confirm'}
          </button>
        </div>
      </Dialog>
    );
  });
}

// Usage example
async function handleDelete(id: string) {
  const ok = await confirm({
    title: 'Deleteのconfirm',
    message: 'इस項目をDeleteしてよろしいですか?इस操作は取り消せ नहीं है।',
    confirmLabel: 'Deleteする',
    variant: 'danger',
  });
  if (ok) await deleteItem(id);
}

commandパレット

function CommandPalette({ commands, onClose }: { commands: Command[]; onClose: () => void }) {
  const [query, setQuery] = useState('');
  const [activeIndex, setActiveIndex] = useState(0);
  const filtered = commands.filter((c) =>
    c.label.toLowerCase().includes(query.toLowerCase())
  );

  const handleKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === 'ArrowDown') {
      e.preventDefault();
      setActiveIndex((prev) => Math.min(prev + 1, filtered.length - 1));
    } else if (e.key === 'ArrowUp') {
      e.preventDefault();
      setActiveIndex((prev) => Math.max(prev - 1, 0));
    } else if (e.key === 'Enter' && filtered[activeIndex]) {
      filtered[activeIndex].action();
      onClose();
    }
  };

  return (
    <Dialog open={true} onClose={onClose} title="commandパレット">
      <input
        autoFocus
        value={query}
        onChange={(e) => { setQuery(e.target.value); setActiveIndex(0); }}
        onKeyDown={handleKeyDown}
        placeholder="command search..."
        className="w-full px-3 py-2 border rounded-lg mb-3"
        role="combobox"
        aria-expanded={true}
      />
      <ul role="listbox" className="max-h-64 overflow-y-auto">
        {filtered.map((cmd, i) => (
          <li key={cmd.id} role="option" aria-selected={i === activeIndex}
            onClick={() => { cmd.action(); onClose(); }}
            className={`px-3 py-2 rounded cursor-pointer ${i === activeIndex ? 'bg-blue-100' : 'hover:bg-gray-50'}`}>
            {cmd.label}
          </li>
        ))}
      </ul>
    </Dialog>
  );
}

Summary

Claude Code का उपयोग करके、HTML dialog要素をutilizationしたアクセシブルなmodal से、confirmダイアlog、commandパレット तकefficientlybuild किया जा सकता है。トースト通知との使い分けはトースト通知implementationを、accessibilityの基本はaccessibilityガイドをदेखें。

dialog要素の仕様はMDN Web Docs - dialogदेखें。

#Claude Code #modal #ダイアlog #React #accessibility
मुफ़्त

मुफ़्त PDF: 5 मिनट में Claude Code चीटशीट

बस अपना ईमेल दर्ज करें और हम तुरंत A4 एक-पृष्ठ चीटशीट PDF भेज देंगे।

हम आपकी व्यक्तिगत जानकारी की सुरक्षा करते हैं और स्पैम नहीं भेजते।

Masa

लेखक के बारे में

Masa

Claude Code का गहराई से उपयोग करने वाले इंजीनियर। claudecode-lab.com चलाते हैं, जो 10 भाषाओं में 2,000 से अधिक पेजों वाला टेक मीडिया है।