-
Notifications
You must be signed in to change notification settings - Fork 453
Expand file tree
/
Copy pathOrgSelect.tsx
More file actions
111 lines (106 loc) · 2.96 KB
/
OrgSelect.tsx
File metadata and controls
111 lines (106 loc) · 2.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import { useRef } from 'react';
import { Box, Icon, Image, Text } from '@/ui/customizables';
import { Select, SelectButton, SelectOptionList } from '@/ui/elements/Select';
import { Check } from '@/ui/icons';
import { common } from '@/ui/styledSystem';
export type OrgOption = {
value: string;
label: string;
logoUrl: string;
};
type OrgSelectProps = {
options: OrgOption[];
value: string | null;
onChange: (value: string) => void;
};
export function OrgSelect({ options, value, onChange }: OrgSelectProps) {
const buttonRef = useRef<HTMLButtonElement>(null);
const selected = options.find(option => option.value === value);
return (
<Select
options={options}
value={value}
onChange={option => onChange(option.value)}
referenceElement={buttonRef}
renderOption={(option, _index, isSelected) => (
<Box
as='span'
sx={theme => ({
width: '100%',
display: 'grid',
gridTemplateColumns: `${theme.sizes.$5} 1fr ${theme.sizes.$3}`,
columnGap: theme.space.$2,
paddingInlineStart: theme.space.$1,
paddingInlineEnd: theme.space.$1x5,
paddingBlock: theme.space.$1,
alignItems: 'center',
borderRadius: theme.radii.$md,
'&:hover, &[data-focused="true"]': {
background: common.mutedBackground(theme),
},
})}
>
<Image
src={option.logoUrl}
alt={option.label}
sx={theme => ({
width: theme.sizes.$5,
height: theme.sizes.$5,
objectFit: 'contain',
flexShrink: 0,
})}
/>
<Text
sx={{ flex: 1, textAlign: 'start', minWidth: 0, maxInlineSize: '200px' }}
truncate
as='span'
variant='subtitle'
>
{option.label}
</Text>
{isSelected && (
<Icon
icon={Check}
size='sm'
sx={theme => ({ color: theme.colors.$primary500 })}
/>
)}
</Box>
)}
>
<SelectButton
ref={buttonRef}
sx={theme => ({
inlineSize: 'min(100%, 16rem)',
paddingInline: theme.space.$3,
marginInline: 'auto',
})}
>
<Image
src={selected?.logoUrl || ''}
alt={selected?.label || ''}
sx={theme => ({
width: theme.sizes.$5,
height: theme.sizes.$5,
borderRadius: theme.radii.$md,
objectFit: 'contain',
flexShrink: 0,
})}
/>
<Text
colorScheme='body'
as='span'
truncate
sx={{
flex: 1,
minWidth: 0,
textAlign: 'start',
}}
>
{selected?.label || 'Select an option'}
</Text>
</SelectButton>
<SelectOptionList />
</Select>
);
}