-
Notifications
You must be signed in to change notification settings - Fork 457
/
Copy pathSfSelect.tsx
90 lines (86 loc) · 2.84 KB
/
SfSelect.tsx
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
'use client';
import { KeyboardEvent, useState } from 'react';
import classNames from 'classnames';
import { SfSelectSize, SfIconExpandMore, composeHandlers, useFocusVisible } from '@storefront-ui/react';
import type { SfSelectProps } from './types';
export default function SfSelect(props: SfSelectProps) {
const {
size = SfSelectSize.base,
children,
invalid,
wrapperClassName,
slotChevron,
required,
disabled,
className,
placeholder,
onBlur,
onChange,
onClick,
onKeyDown,
...attributes
} = props;
const { isFocusVisible } = useFocusVisible();
const [chevronRotated, setChevronRotated] = useState(false);
const rotateUp = () => setChevronRotated(true);
const rotateDown = () => setChevronRotated(false);
const keydownHandler = (event: KeyboardEvent<HTMLSelectElement>) => {
if (event.code === 'Space') rotateUp();
};
return (
<span
className={classNames(
'relative flex flex-col rounded-md',
{
'focus-within:outline focus-within:outline-offset': isFocusVisible,
},
wrapperClassName,
)}
data-testid="select"
>
<select
required={required}
disabled={disabled}
className={classNames(
'appearance-none disabled:cursor-not-allowed cursor-pointer pl-4 pr-3.5 text-neutral-900 focus:ring-primary-700 focus:ring-2 outline-none bg-transparent rounded-md ring-1 ring-inset ring-neutral-300 hover:ring-primary-700 active:ring-2 active:ring-primary-700 disabled:bg-disabled-100 disabled:text-disabled-900 disabled:ring-disabled-200',
{
'py-1.5': size === SfSelectSize.sm,
'py-2': size === SfSelectSize.base,
'py-3 text-base': size === SfSelectSize.lg,
'!ring-negative-700 ring-2': invalid && !disabled,
},
className,
)}
data-testid="select-input"
onBlur={composeHandlers(rotateDown, onBlur)}
onChange={composeHandlers(rotateDown, onChange)}
onClick={composeHandlers(rotateUp, onClick)}
onKeyDown={composeHandlers(keydownHandler, onKeyDown)}
{...attributes}
>
{placeholder && (
<option
hidden
value=""
className={classNames('bg-neutral-300 text-sm', {
'text-base': size === SfSelectSize.lg,
})}
data-testid="select-placeholder"
>
{placeholder}
</option>
)}
{children}
</select>
{slotChevron || (
<SfIconExpandMore
className={classNames(
'box-border absolute -translate-y-1 pointer-events-none top-1/3 right-4 transition easy-in-out duration-0.5',
disabled ? 'text-disabled-500' : 'text-neutral-500',
{ 'rotate-180': chevronRotated },
)}
/>
)}
</span>
);
}