Skip to content
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.