ワンクリックで
agentic-skill-ux-patterns
Use when implementing forms, inputs, modals, loading states, or user feedback patterns.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Use when implementing forms, inputs, modals, loading states, or user feedback patterns.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Use when producing product artifacts - epics, user stories, acceptance criteria, or analytics specs.
Use when defining product direction, vision document sections, or roadmap. Triggers on strategic product planning, vision creation, or vision document quality review.
Use when designing UI, choosing colors, typography, spacing, creating visual hierarchy, or making design decisions. Based on Refactoring UI by Wathan & Schoger.
Use when someone needs a plain-language explanation of how an existing feature or edge case behaves in the codebase. Triggers - non-technical stakeholder asks how something works, need code-informed functional explanation, need to understand rules or edge cases without implementation planning.
Use when a developer wants to go from rough idea to working code autonomously. Triggers - imperfect prompt, solo dev wants full pipeline, "just build it", idea to implementation without manual steps.
Use when creating a new agentic workflow skill. Triggers - need new multi-step orchestrated process, want to add workflow to agentic framework, building spec-driven pipeline.
| name | agentic:skill:ux-patterns |
| description | Use when implementing forms, inputs, modals, loading states, or user feedback patterns. |
| Component | Good | Bad |
|---|---|---|
| Credit card input | Auto-format with spaces, inputmode="numeric" | Raw input, type="number" |
| OTP fields | Separate digits + paste support + auto-submit | Single field or no paste |
| Submit button | Always enabled, validate on submit | Disabled until "valid" |
| Loading >2s | Progressive messages or skeleton | Static "Loading..." spinner |
| Modal close | X + outside click + Escape key | X button only |
| Feedback | Inline near action | Toast notification |
| Options 2-5 | Radio buttons/cards visible | Dropdown |
| Options 10+ | Searchable combobox | Long dropdown |
Credit cards, phone, IBAN: Auto-format with visual separators.
// Store raw, display formatted
const [raw, setRaw] = useState('')
const formatted = raw.replace(/(\d{4})/g, '$1 ').trim()
<input
inputMode="numeric" // NOT type="number"
value={formatted}
placeholder="4242 4242 4242 4242"
onChange={e => setRaw(e.target.value.replace(/\D/g, ''))}
/>
Must have: Separate digit fields + paste support + auto-submit on last digit.
const handlePaste = (e: ClipboardEvent) => {
const digits = e.clipboardData.getData('text').replace(/\D/g, '')
digits.split('').forEach((d, i) => fields[i]?.setValue(d))
if (digits.length === maxLength) submitOtp(digits)
}
const handleChange = (index: number, value: string) => {
// Auto-advance to next field
if (value && index < maxLength - 1) fields[index + 1].focus()
// Auto-submit when complete
if (getAllDigits().length === maxLength) submitOtp(getAllDigits())
}
Desktop: Add visible "Paste" button (browser permission prompt is acceptable).
Support all three methods:
<dialog
onClick={e => e.target === e.currentTarget && close()} // outside click
onKeyDown={e => e.key === 'Escape' && close()} // escape key
>
<button onClick={close}>×</button> // X button
{children}
</dialog>
Exception: Disable outside-click for destructive/critical confirmations.
Keep enabled. Validate on submit, show inline errors.
// Bad: disabled={!isValid}
// Good: always enabled, validate on click
<button type="submit">Submit</button>
{errors.map(e => <span className="error">{e}</span>)}
Only disable: During submission (with loading indicator).
| Duration | Pattern |
|---|---|
| <300ms | Nothing |
| 300ms-2s | Spinner or skeleton |
| >2s | Progressive messages |
// Progressive messages for long operations
const messages = ['Connecting...', 'Processing...', 'Almost done...']
const [msgIndex, setMsgIndex] = useState(0)
useEffect(() => {
const timer = setInterval(() => setMsgIndex(i => Math.min(i + 1, messages.length - 1)), 2000)
return () => clearInterval(timer)
}, [])
Skeleton loading: Match actual content layout (not generic spinner).
Prefer inline for contextual actions. Place feedback near user focus.
// Bad: toast("Copied!")
// Good: inline confirmation
<button onClick={copy}>
{copied ? '✓ Copied' : 'Copy'}
</button>
Toasts: Only for background operations user didn't initiate.
| Options | Use |
|---|---|
| 2-5 | Radio buttons, cards, segmented control |
| 6-9 | Dropdown acceptable |
| 10+ | Searchable combobox required |