Good Code
The good version includes a visible keyboard focus treatment and a disabled style that changes both pointer behavior and visual affordance.
Lesson 03
Review interactive utilities as a full state set, not just the hover style that looks good with a mouse.
export function SubmitButton({ isSaving }: { isSaving: boolean }) {
// The button covers hover, keyboard focus, and disabled states together.
return (
<button
type="submit"
disabled={isSaving}
className="inline-flex h-10 items-center rounded-md bg-emerald-600 px-4 text-sm font-medium text-white transition hover:bg-emerald-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-emerald-300 disabled:cursor-not-allowed disabled:bg-slate-300 disabled:text-slate-600"
>
{isSaving ? "Saving" : "Save"}
</button>
);
}export function SubmitButton({ isSaving }) {
// outline-none removes keyboard focus without a replacement.
return (
<button
disabled={isSaving}
className="rounded-md bg-emerald-600 px-4 py-2 text-white hover:bg-emerald-500 outline-none"
>
Save
</button>
);
}The good version includes a visible keyboard focus treatment and a disabled style that changes both pointer behavior and visual affordance.
The bad version only styles hover and removes the outline without replacing it. Disabled users see the same call to action even when the button cannot be used.