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देखें。
Related Posts
Claude Code से Productivity 3 गुना बढ़ाने की 10 Tips
Claude Code से ज़्यादा पाने की 10 practical tips जानें। Prompt strategies से workflow shortcuts तक, ये techniques आज से ही आपकी efficiency boost करेंगी।
Claude Code के साथ Canvas/WebGL Optimization
Claude Code का उपयोग करके Canvas/WebGL optimization के बारे में जानें। Practical tips और code examples शामिल हैं।
Claude Code के साथ Markdown Implementation
Claude Code का उपयोग करके markdown implementation सीखें। Practical tips और code examples शामिल हैं।