radix-ui / themes

Radix Themes is an open-source component library optimized for fast development, easy maintenance, and accessibility. Maintained by @workos.
https://radix-ui.com/themes
MIT License
5.58k stars 201 forks source link

Proposal: Add a Select.Slot component add an icon to the Select.Root component #128

Open alaindeurveilher opened 1 year ago

alaindeurveilher commented 1 year ago

It would nice to be able to homogeneously format a form containing a mix of TextField an Select components kind of the same way to be able to add indicative icons to them.

The feature already exists for TextField.Root, with the usage of TextField.Slot inside of it. It would be nice to a similar approach for the Select.Root component, sometihing like a Select.Slot component to add a extra icon or whatever addon one might like to add.

That would make users use homogenous and beautiful forms mixing both input fields and selects all of them with addon icons.

Thank you.

vladmoroz commented 10 months ago

Could you provide an example design where this is needed?

abhinavagqoala commented 9 months ago

Hi, it would be nice to add the above mentioned slot in select. Use case: When we want icons representing the select say a calendar icon before selected value that shows the select is related to dates. When we want to add icons in option with labels.

alaindeurveilher commented 9 months ago

Hello, here is an example where a slot to add icon in the select would make the form more homogeneous:

missing-icon-slot-for-select-component

And the corresponding code:

'use client';

import { Button, Card, Flex, Heading, Select, TextField } from '@radix-ui/themes';
import { AiOutlineIdcard } from 'react-icons/ai';
import { FaRegEnvelope } from 'react-icons/fa';

export default function SelectPage() {
  return (
    <Card size="3">
      <form>
        <Flex direction="column" gap="4">
          <Heading size="3">Example of a form with input and select</Heading>
          <TextField.Root variant="soft" size="3">
            <TextField.Slot>
              <AiOutlineIdcard />
            </TextField.Slot>
            <TextField.Input name="name" placeholder="Some text field" />
          </TextField.Root>
          <TextField.Root variant="soft" size="3">
            <TextField.Slot>
              <FaRegEnvelope />
            </TextField.Slot>
            <TextField.Input name="email" placeholder="Other text field" />
          </TextField.Root>

          <Select.Root name="select" size="3">
            <Select.Trigger placeholder="Select field without icon" variant="soft" />
            <Select.Content>
              <Select.Item value="1">option 1</Select.Item>
              <Select.Item value="2">option 2</Select.Item>
              <Select.Item value="3">option 3</Select.Item>
            </Select.Content>
          </Select.Root>

          <Button type="submit">Submit</Button>
          <Button type="button" variant="outline" color="gray">Cancel</Button>
        </Flex>
      </form>
    </Card>
  );
}
vladmoroz commented 7 months ago

We allow passing children to Select.Trigger in the 3.0 release; you should be able to nest an icon manually.

shift4id commented 3 months ago

This behavior isn't enough unless the Select has a value. @vladmoroz

Screenshot 2024-07-14 at 23 51 57 Screenshot 2024-07-14 at 23 52 20
vladmoroz commented 3 months ago

@shift4id good point. Technically you can pass a node instead of a string to the placeholder:

<Select.Trigger
  placeholder={
    <Flex align="center" gap="2">
      <MagnifyingGlassIcon />
      Find...
    </Flex>
  }
/>

We'll just need to update the types to reflect that placeholder accepts React.ReactNode and not just strings though