11import React from 'react'
2- import styled from 'styled-components'
32import { clsx } from 'clsx'
43import type { StyledWrapperProps } from '../internal/components/TextInputWrapper'
54import TextInputWrapper from '../internal/components/TextInputWrapper'
6- import { toggleStyledComponent } from '../internal/utils/toggleStyledComponent'
7- import { useFeatureFlag } from '../FeatureFlags'
85import type { ForwardRefComponent as PolymorphicForwardRefComponent } from '../utils/polymorphic'
96
107import classes from './Select.module.css'
118
129export type SelectProps = Omit <
13- Omit < React . ComponentPropsWithoutRef < 'select' > , 'size' > & Omit < StyledWrapperProps , 'variant' > ,
10+ Omit < React . ComponentProps < 'select' > , 'size' > & Omit < StyledWrapperProps , 'variant' > ,
1411 'multiple' | 'hasLeadingVisual' | 'hasTrailingVisual' | 'as'
1512> & {
1613 placeholder ?: string
1714}
1815
19- const CSS_MODULES_FEATURE_FLAG = 'primer_react_css_modules_ga'
20-
21- const arrowRightOffset = '4px'
22-
23- const StyledSelect = toggleStyledComponent (
24- CSS_MODULES_FEATURE_FLAG ,
25- 'select' ,
26- styled . select `
27- appearance: none;
28- border-radius: inherit;
29- border: 0;
30- color: currentColor;
31- font-size: inherit;
32- outline: none;
33- width: 100%;
34-
35- /* Firefox hacks: */
36- /* 1. Makes Firefox's native dropdown menu's background match the theme.
37-
38- background-color should be 'transparent', but Firefox uses the background-color on
39- <select> to determine the background color used for the dropdown menu.
40-
41- 2. Adds 1px margins to the <select> so the background color doesn't hide the focus outline created with an inset box-shadow.
42- */
43- background-color: inherit;
44- margin-top: 1px;
45- margin-left: 1px;
46- margin-bottom: 1px;
47-
48- /* 2. Prevents visible overlap of partially transparent background colors.
49-
50- 'colors.input.disabledBg' happens to be partially transparent in light mode, so we use a
51- transparent background-color on a disabled <select>. */
52- &:disabled {
53- background-color: transparent;
54- }
55-
56- /* 3. Maintain dark bg color in Firefox on Windows high-contrast mode
57-
58- Firefox makes the <select>'s background color white when setting 'background-color: transparent;' */
59- @media screen and (forced-colors: active) {
60- &:disabled {
61- background-color: -moz-combobox;
62- }
63- }
64- ` ,
65- )
66-
6716const ArrowIndicatorSVG : React . FC < React . PropsWithChildren < { className ?: string } > > = ( { className} ) => {
6817 return (
6918 < svg
@@ -79,83 +28,33 @@ const ArrowIndicatorSVG: React.FC<React.PropsWithChildren<{className?: string}>>
7928 )
8029}
8130
82- const StyledArrowIndicatorSVG = styled ( ArrowIndicatorSVG ) `
83- pointer-events: none;
84- position: absolute;
85- right: ${ arrowRightOffset } ;
86- top: 50%;
87- transform: translateY(-50%);
88- `
89-
9031const ArrowIndicator : React . FC < { className ?: string } > = ( { className} ) => {
91- const enabled = useFeatureFlag ( CSS_MODULES_FEATURE_FLAG )
92- if ( enabled ) {
93- return < ArrowIndicatorSVG className = { clsx ( classes . ArrowIndicator , className ) } />
94- }
95-
96- return < StyledArrowIndicatorSVG />
32+ return < ArrowIndicatorSVG className = { clsx ( classes . ArrowIndicator , className ) } />
9733}
9834
9935const Select = React . forwardRef < HTMLSelectElement , SelectProps > (
100- ( { block, children, contrast, disabled, placeholder, size, required, validationStatus, ...rest } : SelectProps , ref ) => {
101- const enabled = useFeatureFlag ( CSS_MODULES_FEATURE_FLAG )
102- if ( enabled ) {
103- return (
104- < TextInputWrapper
105- block = { block }
106- contrast = { contrast }
107- disabled = { disabled }
108- size = { size }
109- validationStatus = { validationStatus }
110- className = { classes . TextInputWrapper }
111- sx = { rest . sx }
112- >
113- < StyledSelect
114- ref = { ref }
115- required = { required }
116- disabled = { disabled }
117- aria-invalid = { validationStatus === 'error' ? 'true' : 'false' }
118- data-hasplaceholder = { Boolean ( placeholder ) }
119- defaultValue = { placeholder ?? undefined }
120- className = { clsx ( classes . Select , disabled && classes . Disabled ) }
121- { ...rest }
122- >
123- { placeholder && (
124- < option value = "" disabled = { required } hidden = { required } >
125- { placeholder }
126- </ option >
127- ) }
128- { children }
129- </ StyledSelect >
130- < ArrowIndicator className = { classes . ArrowIndicator } />
131- </ TextInputWrapper >
132- )
133- }
134-
36+ (
37+ { block, children, contrast, disabled, placeholder, size, required, validationStatus, sx, ...rest } : SelectProps ,
38+ ref ,
39+ ) => {
13540 return (
13641 < TextInputWrapper
137- sx = { {
138- overflow : 'hidden' ,
139- position : 'relative' ,
140- '@media screen and (forced-colors: active)' : {
141- svg : {
142- fill : disabled ? 'GrayText' : 'FieldText' ,
143- } ,
144- } ,
145- } }
14642 block = { block }
14743 contrast = { contrast }
14844 disabled = { disabled }
14945 size = { size }
15046 validationStatus = { validationStatus }
47+ className = { classes . TextInputWrapper }
48+ sx = { sx }
15149 >
152- < StyledSelect
50+ < select
15351 ref = { ref }
15452 required = { required }
15553 disabled = { disabled }
15654 aria-invalid = { validationStatus === 'error' ? 'true' : 'false' }
15755 data-hasplaceholder = { Boolean ( placeholder ) }
15856 defaultValue = { placeholder ?? undefined }
57+ className = { clsx ( classes . Select , disabled && classes . Disabled ) }
15958 { ...rest }
16059 >
16160 { placeholder && (
@@ -164,8 +63,8 @@ const Select = React.forwardRef<HTMLSelectElement, SelectProps>(
16463 </ option >
16564 ) }
16665 { children }
167- </ StyledSelect >
168- < ArrowIndicator />
66+ </ select >
67+ < ArrowIndicator className = { classes . ArrowIndicator } />
16968 </ TextInputWrapper >
17069 )
17170 } ,
0 commit comments