Survey Fields
ImageChoice, Likert, and YesNo fields for surveys, questionnaires, and feedback forms
Full example
The complete sandbox example, read directly from the form-develop-app / form-develop-app-shadcn
source at build time. The shadcn side (survey-demo) covers ImageChoice and Likert; YesNo lives
in a separate auth-fields demo not covered here.
'use client'
import { Box, Heading, VStack } from '@chakra-ui/react'
import { Form } from '@letar/forms'
import { useState } from 'react'
import { DemoPageLayout } from '../_components'
export default function SurveyFieldsDemoPage() {
const [submittedData, setSubmittedData] = useState<Record<string, unknown> | null>(null)
return (
<DemoPageLayout title="Survey Fields" description="ImageChoice, Likert, YesNo — поля для опросников и анкет">
<VStack gap={8} align="stretch">
{/* ImageChoice */}
<Box>
<Heading size="md" mb={3}>
ImageChoice — выбор из картинок
</Heading>
<Form
debug
initialValue={{ style: '' }}
onSubmit={(data) => setSubmittedData(data as Record<string, unknown>)}
>
<Form.Field.ImageChoice
name="style"
label="Выберите стиль интерьера"
options={[
{
value: 'modern',
label: 'Современный',
image: 'https://picsum.photos/seed/modern/300/200',
description: 'Минимализм и чистые линии',
},
{
value: 'classic',
label: 'Классический',
image: 'https://picsum.photos/seed/classic/300/200',
description: 'Элегантность и традиции',
},
{
value: 'loft',
label: 'Лофт',
image: 'https://picsum.photos/seed/loft/300/200',
description: 'Индустриальный шик',
},
]}
columns={3}
/>
<Form.Button.Submit>Выбрать</Form.Button.Submit>
</Form>
</Box>
{/* Likert */}
<Box>
<Heading size="md" mb={3}>
Likert — шкала согласия
</Heading>
<Form
debug
initialValue={{ experience: undefined }}
onSubmit={(data) => setSubmittedData(data as Record<string, unknown>)}
>
<Form.Field.Likert
name="experience"
label="Как вы оцениваете опыт работы с нашим продуктом?"
anchors={['Совсем не доволен', 'Не доволен', 'Нейтрально', 'Доволен', 'Очень доволен']}
showNumbers
/>
<Form.Button.Submit>Отправить</Form.Button.Submit>
</Form>
</Box>
{/* YesNo — buttons */}
<Box>
<Heading size="md" mb={3}>
YesNo — бинарный выбор
</Heading>
<Form
debug
initialValue={{ agree: undefined, recommend: undefined, subscribe: undefined }}
onSubmit={(data) => setSubmittedData(data as Record<string, unknown>)}
>
<Form.Field.YesNo
name="agree"
label="Вы согласны с условиями использования?"
yesLabel="Да, согласен"
noLabel="Нет, отказываюсь"
variant="buttons"
/>
<Form.Field.YesNo name="recommend" label="Порекомендуете нас друзьям?" variant="thumbs" />
<Form.Field.YesNo name="subscribe" label="Подписаться на рассылку?" variant="emoji" />
<Form.Button.Submit>Отправить</Form.Button.Submit>
</Form>
</Box>
{submittedData && (
<Box p={4} bg="bg.subtle" borderRadius="md">
<Heading size="sm" mb={2}>
Отправленные данные:
</Heading>
<pre style={{ fontSize: '12px', overflow: 'auto' }}>{JSON.stringify(submittedData, null, 2)}</pre>
</Box>
)}
</VStack>
</DemoPageLayout>
)
}'use client'
import { FieldImageChoice, FieldLikert, FieldMatrixChoice } from '@letar/forms-shadcn'
import { useState } from 'react'
import { DemoForm, DemoPageLayout, SubmittedDataPreview } from '../_components'
const imageChoiceOptions = [
{ value: 'modern', label: 'Современный', image: 'https://placehold.co/200x120?text=Modern' },
{
value: 'classic',
label: 'Классический',
image: 'https://placehold.co/200x120?text=Classic',
description: 'Строгие линии',
},
]
const matrixRows = [
{ value: 'speed', label: 'Скорость доставки' },
{ value: 'quality', label: 'Качество товара' },
]
const matrixColumns = [
{ value: '1', label: 'Плохо' },
{ value: '3', label: 'Нормально' },
{ value: '5', label: 'Отлично' },
]
interface SurveyValues {
productStyle: string
npsScore: number | undefined
satisfaction: Record<string, string | string[]>
}
const defaultValues: SurveyValues = {
productStyle: '',
npsScore: undefined,
satisfaction: {},
}
export default function SurveyDemoPage() {
const [submitted, setSubmitted] = useState<SurveyValues | null>(null)
return (
<DemoPageLayout
title="Поля опросов"
description="ImageChoice, Likert (NPS-шкала), MatrixChoice"
>
<DemoForm<SurveyValues> defaultValues={defaultValues} onSubmit={setSubmitted}>
<FieldImageChoice name="productStyle" label="Стиль товара" options={imageChoiceOptions} columns={2} />
<FieldLikert
name="npsScore"
label="Насколько вы довольны сервисом?"
anchors={['Совсем не доволен', 'Не доволен', 'Нейтрально', 'Доволен', 'Полностью доволен']}
showNumbers
/>
<FieldMatrixChoice
name="satisfaction"
label="Оцените аспекты заказа"
rows={matrixRows}
columns={matrixColumns}
/>
<button
type="submit"
className="bg-primary text-primary-foreground rounded-md px-4 py-2 text-sm font-medium"
>
Отправить
</button>
</DemoForm>
<SubmittedDataPreview data={submitted} />
</DemoPageLayout>
)
}Vue-пример для этого поля появится позже.
Angular-пример для этого поля появится позже.
ImageChoice
Visual selection from image cards. Ideal for choosing styles, products, or categories.
<Form.Field.ImageChoice
name="style"
label="Choose a style"
options={[
{ value: 'modern', label: 'Modern', image: '/img/modern.jpg' },
{ value: 'classic', label: 'Classic', image: '/img/classic.jpg' },
]}
columns={3}
multiple={false}
/>Value: string (single) or string[] (when multiple={true})
| Prop | Type | Default | Description |
|---|---|---|---|
options | ImageChoiceOption[] | required | Options with images |
columns | number | 3 | Grid columns (responsive: 1→2→N) |
multiple | boolean | false | Multi-select mode |
Likert
Agreement/satisfaction scale with labeled points. Standard for NPS and survey forms.
<Form.Field.Likert
name="satisfaction"
label="How satisfied are you?"
anchors={['Very Unsatisfied', 'Unsatisfied', 'Neutral', 'Satisfied', 'Very Satisfied']}
showNumbers={true}
/>Value: number (1-based index of selected point)
| Prop | Type | Default | Description |
|---|---|---|---|
anchors | string[] | required | Labels for each point |
showNumbers | boolean | false | Show point numbers |
On mobile, the horizontal scale switches to a vertical list.
YesNo
Binary choice with large clickable blocks. Good for consents, confirmations, and simple questions.
<Form.Field.YesNo
name="agree"
label="Do you agree?"
yesLabel="Yes, I agree"
noLabel="No, I decline"
variant="buttons"
/>Value: boolean
| Prop | Type | Default | Description |
|---|---|---|---|
yesLabel | string | 'Да' | Yes button text |
noLabel | string | 'Нет' | No button text |
variant | 'buttons' | 'thumbs' | 'emoji' | 'buttons' | Visual style |
Variants: buttons (text only), thumbs (with thumbs up/down), emoji (with happy/sad face).
Live Example
Try the interactive example on forms-example.letar.best.