All Taste components
Onboarding
Pick your interests
The personalising step: a small illustration, a grid of interest chips to tap on and off, and continue.
small illustration · 10 multi-select chips · selected with tick · count hint · continue
4 of 4
What are you into?
Pick three or more and we will tune your feed.
4 selected
// Mobile-first screen for a React web app; the same markup maps to React Native via NativeWind (View, Text, Pressable, react-native-svg).
import { cn } from "@/lib/utils";
const interests = ["Design","Cooking","Travel","Music","Fitness","Books","Photography","Film","Tech","Art"];
function Illustration({ className }: { className?: string }) {
return (
<svg viewBox="0 0 160 92" aria-hidden="true" className={cn("h-14 w-24", className)}>
<circle cx="54" cy="52" r="30" className="fill-brand-200" />
<rect x="72" y="16" width="44" height="44" rx="10" transform="rotate(12 94 38)" className="fill-brand-600" />
<path d="M100 84l22-36 22 36z" strokeWidth="6" strokeLinejoin="round" className="fill-brand-400 stroke-brand-400" />
<path d="M26 10l2.4 5.6 5.6 2.4-5.6 2.4-2.4 5.6-2.4-5.6-5.6-2.4 5.6-2.4z" className="fill-brand-400" />
</svg>
);
}
export default function PickInterests({ selected = [], min = 3, onToggle, onContinue, onSkip }: {
selected?: string[];
min?: number;
onToggle?: (name: string) => void;
onContinue?: () => void;
onSkip?: () => void;
}) {
return (
<main className="mx-auto flex min-h-dvh max-w-md flex-col bg-bg px-6 pb-8 font-sans text-fg">
<header className="-mr-3.5 flex h-12 items-center justify-between">
<span className="text-[13px] font-medium tabular-nums text-fg-subtle">4 of 4</span>
<button type="button" onClick={onSkip} className="h-11 rounded px-3.5 text-sm font-medium text-fg-muted hover:bg-surface-2">
Skip
</button>
</header>
<Illustration className="mb-3.5" />
<h1 className="text-[26px] font-semibold leading-8 tracking-tight">What are you into?</h1>
<p className="mt-2.5 text-[15px] leading-[22px] text-fg-muted">Pick three or more and we will tune your feed.</p>
<div className="mt-5 flex flex-wrap gap-2">
{interests.map((name) => {
const on = selected.includes(name);
return (
<button
key={name}
type="button"
aria-pressed={on}
onClick={() => onToggle?.(name)}
className={cn(
"relative inline-flex h-9 items-center gap-1.5 rounded-full border px-3.5 text-sm font-medium transition-colors before:absolute before:inset-x-0 before:-inset-y-1",
on ? "border-primary bg-primary text-primary-fg" : "border-border-strong bg-bg text-fg hover:border-primary",
)}
>
{on && (
<svg viewBox="0 0 24 24" aria-hidden="true" className="-ml-0.5 size-[15px]" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
<path d="M20 6 9 17l-5-5" />
</svg>
)}
{name}
</button>
);
})}
</div>
<div className="mt-auto pt-6">
<p className="mb-3 text-center text-[13px] text-fg-subtle">
{selected.length < min ? "Pick " + (min - selected.length) + " more" : selected.length + " selected"}
</p>
<button
type="button"
onClick={onContinue}
disabled={selected.length < min}
className="h-[52px] w-full rounded-lg bg-primary text-[15px] font-semibold text-primary-fg hover:bg-primary-hover disabled:pointer-events-none disabled:opacity-50"
>
Continue
</button>
</div>
</main>
);
}
The code uses the Taste Tailwind preset. Make yours on the Taste page with Export my system.