ChoicePicker
A small icon+label choice grid — e.g. the "Kamera" / "Galerie" pair inside a photo-source dialog. Not food-specific: a generic N-choice picker, reusable for any small set of mutually-exclusive icon+label options.
Playground
Picked: (none yet)
Options stagger in on appear. Hover lifts an option, clicking one scales it down briefly before select fires — the consumer's own dialog still owns closing itself.
vue
<script setup>
import { ChoicePicker } from 'yemek'
function choosePhotoSource(key) {
photoPickerOpen.value = false
if (key === 'camera') cameraFileInput.value?.click()
else galleryFileInput.value?.click()
}
</script>
<template>
<ChoicePicker
:options="[
{ key: 'camera', label: 'Kamera' },
{ key: 'gallery', label: 'Galerie' }
]"
@select="choosePhotoSource"
>
<template #icon="{ key }">
<CameraIcon v-if="key === 'camera'" />
<GalleryIcon v-else />
</template>
</ChoicePicker>
</template>Props
| Prop | Type | Default | Description |
|---|---|---|---|
options | { key: string; label: string }[] | — | Already-localized option labels. Any number of options — the grid auto-fits (repeat(auto-fit, minmax(7rem, 1fr))). |
Slots
| Slot | Scope | Description |
|---|---|---|
icon | { option, key } | Renders the icon for each option — the consumer decides what icon fits which key (camera/gallery/barcode/...). |
Events
| Event | Payload | Fired when |
|---|---|---|
select | string (the picked option's key) | An option is clicked. |
Behavior notes
- No dialog/picker logic lives in the component — it only renders the grid and emits which key was picked. The consumer's own dialog (or whatever container wraps this) still owns open/close.
- Options stagger in on appear (a per-option animation delay), and each option lifts slightly on hover and scales down briefly on click — replacing a fully static grid.
prefers-reduced-motion: reducedisables the entrance stagger and hover-lift transforms.- Option card background is derived relative to whatever surface it's actually placed on (
color-mix(in srgb, var(--yemek-color-text) 6%, var(--yemek-color-surface))), not the separate-insettoken — a host app's-surface/-insetpair can be two unrelated shades, so a fixed-insetbackground can visibly mismatch the container it's dropped into.