Marigold
v18.0.0-beta.4
Marigold
v18.0.0-beta.4

Application

MarigoldProvider
RouterProvider

Layout

AppShellbeta
Aside
Aspect
Center
Columns
Container
Grid
Inline
Inset
Pagebeta
Panelbeta
Scrollable
Split
Stack
Tiles

Actions

Buttonupdated
ButtonGroupbeta
Link
LinkButton
ToggleButtonbeta

Form

Autocomplete
Calendar
Checkbox
ComboBox
DateField
DatePicker
DateRangePickerbeta
FileField
Form
NumberField
Radio
RangeCalendaralpha
SearchField
SegmentedControlbeta
Select
SelectListupdated
Slider
Switchupdated
TagFieldbeta
TextArea
TextField
TimeField

Collection

Cardupdated
Table
Tag
ActionBaralpha

Navigation

Accordion
Breadcrumbs
Pagination
Sidebarbeta
Tabs
TopNavigationbeta

Overlay

ActionMenualpha
ContextualHelp
Dialog
Drawer
Menuupdated
Toastbeta
Tooltip

Content

Badge
Descriptionalpha
Divider
EmptyStatebeta
ErrorStatebeta
Headline
Keyboardbeta
List
Loader
SectionMessage
SVG
Text
TextValuealpha
Titlealpha

Formatters

DateFormat
NumericFormat

Hooks and Utils

cn
cva
extendTheme
parseFormData
useAsyncListData
useLandmark
useListData
useTheme
VisuallyHidden
Components

TextValue

Inline label primitive for selection items.

The <TextValue> component is a small inline label designed for selection items such as <Select.Option>, <Menu.Item>, <ListBox.Item>, and <ComboBox.Item>. By marking the label explicitly, screen readers announce the right text and keyboard typeahead lands on the right item without any extra wiring.

Anatomy

TextValueSelection item

A <TextValue> is a single inline label with no parts of its own. It sits inside a selection item and marks the text that names the option.

Appearance

<TextValue> carries no styling of its own. Its appearance comes entirely from the surrounding selection item, which keeps the look consistent across menus, selects, and lists. Pair it with <Description> when the item also needs a help line.

Styling is inferred automatically from the surrounding context. See Slot-Driven Composition for how this works.

Usage

<TextValue> exists to mark the label inside a selection item when the item's content is more than a plain string. As soon as an option contains an avatar, an icon, a badge, or any non-text node, there is no longer a single unambiguous text node the option can use as its accessible name. <TextValue> marks that text explicitly, so screen readers announce the right name and keyboard typeahead matches the visible label.

Reach for <TextValue> when:

  • the option's children include images, icons, or layout components like <Inline> or <Stack>,
  • the option pairs a label with a <Description> help line, or
  • you want the label to drive typeahead independently from supporting copy.

Do

Keep <TextValue> content to a short label that names the option, like 'Admin', 'Archived', or 'Newest first'. Screen readers announce it and keyboard typeahead matches against it.

Don't

Don't reach for <TextValue> when:

  • an option's children are a single string, the selection item already uses that as the accessible name, or
  • you need paragraph text or arbitrary inline strings, use <Text> instead.

With a description

Place a <Description> next to the <TextValue> inside a selection item to add a one-line help line below the label. The label drives the option's accessible name and typeahead. The description sits below it.

Region
import { Description, Select, TextValue } from '@marigold/components';export default () => (  <Select label="Region" defaultValue="eu" width={64}>    <Select.Option id="eu">      <TextValue>Europe</TextValue>      <Description>Frankfurt, Dublin, Stockholm</Description>    </Select.Option>    <Select.Option id="us">      <TextValue>North America</TextValue>      <Description>Virginia, Oregon</Description>    </Select.Option>    <Select.Option id="ap">      <TextValue>Asia Pacific</TextValue>      <Description>Tokyo, Singapore, Sydney</Description>    </Select.Option>  </Select>);

With a complex layout

When option content includes images, icons, or layout components like <Inline>, keep <TextValue> around the label text only and let the layout wrap around it. Set the option's textValue prop so typeahead has a plain string to match even when the label sits behind layout.

Pass renderValue to <Select> to control what the trigger shows once an option is selected. Without it the trigger renders the option's full layout, which rarely looks right inside a single-line button.

Choose a venue
import type { Venue } from '@/lib/data/venues';import { venues } from '@/lib/data/venues';import {  Inline,  NumericFormat,  Select,  Stack,  Text,  TextValue,} from '@marigold/components';export default () => (  <Select    label="Choose a venue"    placeholder="Select a venue"    defaultValue="6"    width={96}    items={venues}    renderValue={([venue]: Venue[]) => (      <Inline space={2} alignY="center">        <img          src={venue.image}          alt=""          className="size-5 rounded-sm object-cover"        />        <Text>{venue.name}</Text>      </Inline>    )}  >    {(venue: Venue) => (      <Select.Option id={venue.id}>        <Inline space={4} alignY="center" noWrap>          <img            src={venue.image}            alt=""            className="size-16 rounded-md object-cover"          />          <Stack space="tight">            <TextValue>{venue.name}</TextValue>            <Text size="xs" variant="muted">              {venue.city}, {venue.country} · Capacity {venue.capacity} ·{' '}              {venue.indoor ? 'Indoor' : 'Outdoor'}            </Text>            <Inline space={2} alignY="center">              <Text size="xs" weight="medium">                <NumericFormat                  style="currency"                  currency="USD"                  value={venue.price.from}                  maximumFractionDigits={0}                />                {' – '}                <NumericFormat                  style="currency"                  currency="USD"                  value={venue.price.to}                  maximumFractionDigits={0}                />              </Text>              <Text size="xs" variant="muted">                ★ {venue.rating.toFixed(1)}              </Text>            </Inline>          </Stack>        </Inline>      </Select.Option>    )}  </Select>);

Driving typeahead

Filtering inside a <ComboBox> follows the option's label, not its supporting copy. <TextValue> marks that label, so typing a fragment of a description won't match. Only the label is searched.

import { ComboBox, Description, TextValue } from '@marigold/components';export default () => (  <ComboBox label="Framework" placeholder="Search frameworks" width={72}>    <ComboBox.Option id="react" textValue="React">      <TextValue>React</TextValue>      <Description>Component-based UI library</Description>    </ComboBox.Option>    <ComboBox.Option id="vue" textValue="Vue">      <TextValue>Vue</TextValue>      <Description>Progressive web framework</Description>    </ComboBox.Option>    <ComboBox.Option id="svelte" textValue="Svelte">      <TextValue>Svelte</TextValue>      <Description>Compiles to vanilla JavaScript</Description>    </ComboBox.Option>    <ComboBox.Option id="solid" textValue="Solid">      <TextValue>Solid</TextValue>      <Description>Fine-grained reactivity</Description>    </ComboBox.Option>  </ComboBox>);

Set `textValue` on each ComboBox option

A <ComboBox> shows the selected value inside a text input, which can only display a string. When the option's children are more than plain text, set the textValue prop on the option to the label string. Without it, the input falls back to stringifying the children and renders [object Object]. The textValue prop also drives keyboard typeahead.

Custom styling

<TextValue> carries no styling of its own. It picks up its look from the surrounding selection item, which keeps menus, selects, and lists feeling consistent. That works for most cases, but it also means the label can't be made larger, bolder, or visually distinct from the rest of the option content.

When an option grows into a richer layout where the title should be the loudest element, set the textValue prop on the option instead. It accepts a plain string that becomes the option's accessible name and the source for keyboard typeahead, while leaving the children free to render any layout and typography. Pair it with renderValue on the parent to bring the name back into the trigger once selected.

Choose a venue
import type { Venue } from '@/lib/data/venues';import { venueTypes, venues } from '@/lib/data/venues';import {  Badge,  Inline,  Inset,  NumericFormat,  Select,  Stack,  Text,} from '@marigold/components';export default () => (  <Select    label="Choose a venue"    placeholder="Browse venues"    defaultValue="6"    width="full"    items={venues}    renderValue={([venue]: Venue[]) => (      <Inline space={2} alignY="center" noWrap>        <img          src={venue.image}          alt=""          className="size-5 rounded-sm object-cover"        />        <Inline space={1} alignY="center" noWrap>          <Text>{venue.name}</Text>          <Text variant="muted">            ({venue.city}, {venue.country})          </Text>        </Inline>      </Inline>    )}  >    {(venue: Venue) => (      <Select.Option id={venue.id} textValue={venue.name}>        <Inset p="square-regular">          <Inline space={4} alignY="top" noWrap>            <img              src={venue.image}              alt=""              className="aspect-video w-40 shrink-0 rounded-md object-cover"            />            <Stack space={2}>              <Stack space={1}>                <Inline space={2} alignY="center">                  <Badge variant="info">{venueTypes[venue.type]}</Badge>                  <Text size="xs" variant="muted">                    {venue.city}, {venue.country}                  </Text>                </Inline>                <Text size="xl" weight="bold" lineHeight="tight">                  {venue.name}                </Text>              </Stack>              <Text size="sm" variant="muted">                {venue.description}              </Text>              <Inline space={3} alignY="center" alignX="between">                <Inline space={3} alignY="center">                  <Text size="xs" variant="muted">                    Capacity {venue.capacity}                  </Text>                  <Text size="xs" variant="muted">                    {venue.indoor ? 'Indoor' : 'Outdoor'}                  </Text>                  <Text size="xs" variant="muted">                    ★ {venue.rating.toFixed(1)}                  </Text>                </Inline>                <Text size="sm" weight="semibold">                  <NumericFormat                    style="currency"                    currency="USD"                    value={venue.price.from}                    maximumFractionDigits={0}                  />                  {' – '}                  <NumericFormat                    style="currency"                    currency="USD"                    value={venue.price.to}                    maximumFractionDigits={0}                  />                </Text>              </Inline>            </Stack>          </Inline>        </Inset>      </Select.Option>    )}  </Select>);

Props

Did you know? You can explore, test, and customize props live in Marigold's storybook. Watch the effects they have in real-time!
View TextValue stories

TextValue

Prop

Type

Accessibility props (54)

Prop

Type

DOM event handlers (164)

Prop

Type

Alternative components

  • Text: Use for paragraph text and body copy.
  • Description: The help-line partner inside selection items.
Last update: 2 months ago

Text

Component for displaying text paragraphs

Title

Heading primitive that participates in container slot context.

On this page

AnatomyAppearanceUsageWith a descriptionWith a complex layoutDriving typeaheadCustom stylingPropsTextValueAlternative components