Skip to content

ChoiceList

A vertical, full-width, text-first single-select list — e.g. onboarding's "Abnehmen / Halten / Aufbauen" goal picker. A sibling to ChoicePicker, not a variant of it: ChoicePicker is a fixed icon+label grid (its icon slot isn't optional, and its repeat(auto-fit, minmax(7rem, 1fr)) layout doesn't produce a full-width vertical stack for a few text-only options) — a genuinely different shape, not just "ChoicePicker without icons". Not goal-specific — a generic N-choice vertical list.

Playground

Selected: maintain

vue
<script setup>
import { ChoiceList } from 'yemek'

const goal = ref('maintain')

function selectGoal(key) {
  goal.value = key
  const preset = { cut: 1800, maintain: 2400, bulk: 2800 }[key]
  targetCalories.value = preset
}
</script>

<template>
  <ChoiceList
    :options="[
      { key: 'cut', label: 'Abnehmen', description: 'Kaloriendefizit für Fettabbau' },
      { key: 'maintain', label: 'Halten', description: 'Gewicht stabil halten' },
      { key: 'bulk', label: 'Aufbauen', description: 'Kalorienüberschuss für Muskelaufbau' }
    ]"
    :selected-key="goal"
    @select="selectGoal"
  />
</template>

Props

PropTypeDefaultDescription
options{ key: string; label: string; description?: string }[]Already-localized option labels. Any number of options — full-width vertical stack, not a grid.
selectedKeystringundefinedThe currently active option's key, if any.

Events

EventPayloadFired when
selectstring (the picked option's key)An option is clicked.

Behavior notes

  • No selection-state logic lives here — the consumer owns which key is "selected" and re-passes it as selectedKey; this only renders and emits.
  • Options stagger in on appear (a per-option animation delay), same convention as ChoicePicker's grid entrance, just applied to a vertical list instead.
  • prefers-reduced-motion: reduce disables the entrance stagger.
  • Option background is derived relative to whatever surface it's actually placed on (color-mix(in srgb, var(--yemek-color-text) 5%, var(--yemek-color-surface))), not the separate -inset token — same lesson as Textarea/ChoicePicker.