(frontend) add icon support to select primitive component

Enhance select component by adding icon display capability for better
visual representation of options.
This commit is contained in:
lebaudantoine
2025-08-01 17:28:20 +02:00
committed by aleb_the_flash
parent e2c3b745ca
commit 872ce1ecc6

View File

@@ -1,6 +1,6 @@
import { type ReactNode } from 'react' import { type ReactNode } from 'react'
import { styled } from '@/styled-system/jsx' import { styled } from '@/styled-system/jsx'
import { RiArrowDropDownLine } from '@remixicon/react' import { RemixiconComponentType, RiArrowDropDownLine } from '@remixicon/react'
import { import {
Button, Button,
ListBox, ListBox,
@@ -12,12 +12,14 @@ import {
import { Box } from './Box' import { Box } from './Box'
import { StyledPopover } from './Popover' import { StyledPopover } from './Popover'
import { menuRecipe } from '@/primitives/menuRecipe.ts' import { menuRecipe } from '@/primitives/menuRecipe.ts'
import { css } from '@/styled-system/css'
const StyledButton = styled(Button, { const StyledButton = styled(Button, {
base: { base: {
width: 'full', width: 'full',
display: 'flex', display: 'flex',
justifyContent: 'space-between', justifyContent: 'space-between',
alignItems: 'center',
paddingY: 0.125, paddingY: 0.125,
paddingX: 0.25, paddingX: 0.25,
border: '1px solid', border: '1px solid',
@@ -53,22 +55,40 @@ const StyledSelectValue = styled(SelectValue, {
}, },
}) })
const StyledIcon = styled('div', {
base: {
marginRight: '0.35rem',
flexShrink: 0,
},
})
export const Select = <T extends string | number>({ export const Select = <T extends string | number>({
label, label,
iconComponent,
items, items,
errors, errors,
...props ...props
}: Omit<SelectProps<object>, 'items' | 'label' | 'errors'> & { }: Omit<SelectProps<object>, 'items' | 'label' | 'errors'> & {
iconComponent?: RemixiconComponentType
label: ReactNode label: ReactNode
items: Array<{ value: T; label: ReactNode }> items: Array<{ value: T; label: ReactNode }>
errors?: ReactNode errors?: ReactNode
}) => { }) => {
const IconComponent = iconComponent
return ( return (
<RACSelect {...props}> <RACSelect {...props}>
{label} {label}
<StyledButton> <StyledButton>
{!!IconComponent && (
<StyledIcon>
<IconComponent size={18} />
</StyledIcon>
)}
<StyledSelectValue /> <StyledSelectValue />
<RiArrowDropDownLine aria-hidden="true" /> <RiArrowDropDownLine
aria-hidden="true"
className={css({ flexShrink: 0 })}
/>
</StyledButton> </StyledButton>
<StyledPopover> <StyledPopover>
<Box size="sm" type="popover" variant="control"> <Box size="sm" type="popover" variant="control">