From a44115e7202fecb9d4c2aed5a0c88790361716cf Mon Sep 17 00:00:00 2001
From: Marie Lucca <40550942+francinelucca@users.noreply.github.com>
Date: Mon, 6 Jan 2025 12:09:01 -0500
Subject: [PATCH] Revert "chore(Select): Remove CSS modules feature flag from
 Select (#5464)"

This reverts commit d43f27f7f7b63ec6dfe8b6efe62c3d9fd6e7386b.
---
 .changeset/violet-tables-eat.md      |   5 --
 packages/react/src/Select/Select.tsx | 125 ++++++++++++++++++++++++---
 2 files changed, 113 insertions(+), 17 deletions(-)
 delete mode 100644 .changeset/violet-tables-eat.md

diff --git a/.changeset/violet-tables-eat.md b/.changeset/violet-tables-eat.md
deleted file mode 100644
index ac644ed6b67..00000000000
--- a/.changeset/violet-tables-eat.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"@primer/react": minor
----
-
-Remove CSS modules feature flag from Select
diff --git a/packages/react/src/Select/Select.tsx b/packages/react/src/Select/Select.tsx
index 75d49c79be2..98faa357844 100644
--- a/packages/react/src/Select/Select.tsx
+++ b/packages/react/src/Select/Select.tsx
@@ -1,18 +1,69 @@
 import React from 'react'
+import styled from 'styled-components'
 import {clsx} from 'clsx'
 import type {StyledWrapperProps} from '../internal/components/TextInputWrapper'
 import TextInputWrapper from '../internal/components/TextInputWrapper'
+import {toggleStyledComponent} from '../internal/utils/toggleStyledComponent'
+import {useFeatureFlag} from '../FeatureFlags'
 import type {ForwardRefComponent as PolymorphicForwardRefComponent} from '../utils/polymorphic'
 
 import classes from './Select.module.css'
 
 export type SelectProps = Omit<
-  Omit<React.ComponentProps<'select'>, 'size'> & Omit<StyledWrapperProps, 'variant'>,
+  Omit<React.ComponentPropsWithoutRef<'select'>, 'size'> & Omit<StyledWrapperProps, 'variant'>,
   'multiple' | 'hasLeadingVisual' | 'hasTrailingVisual' | 'as'
 > & {
   placeholder?: string
 }
 
+const CSS_MODULES_FEATURE_FLAG = 'primer_react_css_modules_ga'
+
+const arrowRightOffset = '4px'
+
+const StyledSelect = toggleStyledComponent(
+  CSS_MODULES_FEATURE_FLAG,
+  'select',
+  styled.select`
+    appearance: none;
+    border-radius: inherit;
+    border: 0;
+    color: currentColor;
+    font-size: inherit;
+    outline: none;
+    width: 100%;
+
+    /* Firefox hacks: */
+    /* 1. Makes Firefox's native dropdown menu's background match the theme.
+
+        background-color should be 'transparent', but Firefox uses the background-color on
+        <select> to determine the background color used for the dropdown menu.
+
+     2. Adds 1px margins to the <select> so the background color doesn't hide the focus outline created with an inset box-shadow.
+  */
+    background-color: inherit;
+    margin-top: 1px;
+    margin-left: 1px;
+    margin-bottom: 1px;
+
+    /* 2. Prevents visible overlap of partially transparent background colors.
+
+     'colors.input.disabledBg' happens to be partially transparent in light mode, so we use a
+     transparent background-color on a disabled <select>. */
+    &:disabled {
+      background-color: transparent;
+    }
+
+    /* 3. Maintain dark bg color in Firefox on Windows high-contrast mode
+
+     Firefox makes the <select>'s background color white when setting 'background-color: transparent;' */
+    @media screen and (forced-colors: active) {
+      &:disabled {
+        background-color: -moz-combobox;
+      }
+    }
+  `,
+)
+
 const ArrowIndicatorSVG: React.FC<React.PropsWithChildren<{className?: string}>> = ({className}) => {
   return (
     <svg
@@ -28,33 +79,83 @@ const ArrowIndicatorSVG: React.FC<React.PropsWithChildren<{className?: string}>>
   )
 }
 
+const StyledArrowIndicatorSVG = styled(ArrowIndicatorSVG)`
+  pointer-events: none;
+  position: absolute;
+  right: ${arrowRightOffset};
+  top: 50%;
+  transform: translateY(-50%);
+`
+
 const ArrowIndicator: React.FC<{className?: string}> = ({className}) => {
-  return <ArrowIndicatorSVG className={clsx(classes.ArrowIndicator, className)} />
+  const enabled = useFeatureFlag(CSS_MODULES_FEATURE_FLAG)
+  if (enabled) {
+    return <ArrowIndicatorSVG className={clsx(classes.ArrowIndicator, className)} />
+  }
+
+  return <StyledArrowIndicatorSVG />
 }
 
 const Select = React.forwardRef<HTMLSelectElement, SelectProps>(
-  (
-    {block, children, contrast, disabled, placeholder, size, required, validationStatus, sx, ...rest}: SelectProps,
-    ref,
-  ) => {
+  ({block, children, contrast, disabled, placeholder, size, required, validationStatus, ...rest}: SelectProps, ref) => {
+    const enabled = useFeatureFlag(CSS_MODULES_FEATURE_FLAG)
+    if (enabled) {
+      return (
+        <TextInputWrapper
+          block={block}
+          contrast={contrast}
+          disabled={disabled}
+          size={size}
+          validationStatus={validationStatus}
+          className={classes.TextInputWrapper}
+          sx={rest.sx}
+        >
+          <StyledSelect
+            ref={ref}
+            required={required}
+            disabled={disabled}
+            aria-invalid={validationStatus === 'error' ? 'true' : 'false'}
+            data-hasplaceholder={Boolean(placeholder)}
+            defaultValue={placeholder ?? undefined}
+            className={clsx(classes.Select, disabled && classes.Disabled)}
+            {...rest}
+          >
+            {placeholder && (
+              <option value="" disabled={required} hidden={required}>
+                {placeholder}
+              </option>
+            )}
+            {children}
+          </StyledSelect>
+          <ArrowIndicator className={classes.ArrowIndicator} />
+        </TextInputWrapper>
+      )
+    }
+
     return (
       <TextInputWrapper
+        sx={{
+          overflow: 'hidden',
+          position: 'relative',
+          '@media screen and (forced-colors: active)': {
+            svg: {
+              fill: disabled ? 'GrayText' : 'FieldText',
+            },
+          },
+        }}
         block={block}
         contrast={contrast}
         disabled={disabled}
         size={size}
         validationStatus={validationStatus}
-        className={classes.TextInputWrapper}
-        sx={sx}
       >
-        <select
+        <StyledSelect
           ref={ref}
           required={required}
           disabled={disabled}
           aria-invalid={validationStatus === 'error' ? 'true' : 'false'}
           data-hasplaceholder={Boolean(placeholder)}
           defaultValue={placeholder ?? undefined}
-          className={clsx(classes.Select, disabled && classes.Disabled)}
           {...rest}
         >
           {placeholder && (
@@ -63,8 +164,8 @@ const Select = React.forwardRef<HTMLSelectElement, SelectProps>(
             </option>
           )}
           {children}
-        </select>
-        <ArrowIndicator className={classes.ArrowIndicator} />
+        </StyledSelect>
+        <ArrowIndicator />
       </TextInputWrapper>
     )
   },