Skip to content

Commit 355c045

Browse files
OpenStaxClaudeclaudeCopilot
authored andcommitted
Phase 2.4: Dropdown System Migration
Migrates dropdown components from styled-components to global CSS files. Changes: - Created Dropdown.css with all dropdown styles - Refactored Dropdown.tsx to use plain React with CSS classes - Updated index.tsx to import Dropdown.css globally - Maintained backward compatibility with styled() wrappers Components migrated: - DropdownToggle - Cursor styling - DropdownMenu - Positioning, shadow, border styles - DropdownFocusWrapper - Overflow control - DropdownList - Menu item styles and focus states - DotMenu (already partially migrated, verified) Key features preserved: - fadeIn animation (100ms ease-out) - Complex :focus-within selectors for tab-transparent variant - Component selector compatibility via styled() wrappers - Keyboard navigation and tab trapping - Controlled/uncontrolled state handling Follows migration patterns from PLAIN_CSS_MIGRATION_LEARNINGS.md: - Uses classnames package for className composition - React.forwardRef for components with refs - CSS variables set before ...style spread - Global CSS imported from src/app/index.tsx Related to: CORE-1698 🤖 Generated with [Claude Code](https://claude.com/claude-code) Delete package-lock.json Lint stuff Update yarn.lock Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> Co-Authored-By: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
1 parent e7dcd94 commit 355c045

3 files changed

Lines changed: 225 additions & 139 deletions

File tree

src/app/components/Dropdown.css

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
/* Dropdown component styles */
2+
3+
/* Keyframe animation for dropdown fade-in */
4+
@keyframes dropdown-fade-in {
5+
0% {
6+
opacity: 0;
7+
}
8+
100% {
9+
opacity: 1;
10+
}
11+
}
12+
13+
/* DropdownToggle styles */
14+
.dropdown-toggle {
15+
cursor: pointer;
16+
}
17+
18+
/* TabHiddenDropDown menu styles - applies to children that are not the toggle */
19+
.dropdown-menu {
20+
animation: 100ms dropdown-fade-in ease-out;
21+
position: absolute;
22+
box-shadow: 0 0.5rem 0.5rem 0 rgba(0, 0, 0, 0.1);
23+
border: 1px solid var(--dropdown-form-border, #d5d5d5); /* theme.color.neutral.formBorder */
24+
top: calc(100% + 0.4rem);
25+
left: 0;
26+
}
27+
28+
/* DropdownFocusWrapper styles */
29+
.dropdown-focus-wrapper {
30+
overflow: visible;
31+
}
32+
33+
/* DropdownList styles */
34+
.dropdown-list {
35+
list-style: none;
36+
margin: 0;
37+
padding: 0.6rem 0;
38+
background: var(--dropdown-form-background, #f5f5f5); /* theme.color.neutral.formBackground */
39+
z-index: 1;
40+
}
41+
42+
.dropdown-list li {
43+
padding: 0.2rem;
44+
}
45+
46+
.dropdown-list li button,
47+
.dropdown-list li a {
48+
white-space: nowrap;
49+
text-decoration: none;
50+
display: flex;
51+
align-items: center;
52+
text-align: left;
53+
cursor: pointer;
54+
outline: none;
55+
border: none;
56+
padding-left: 0.8rem;
57+
margin: 0;
58+
height: 3rem;
59+
background: none;
60+
min-width: 7rem;
61+
/* textStyle from Typography - using CSS variables */
62+
font-family: var(--text-font-family, Helvetica, Arial, sans-serif);
63+
font-weight: var(--text-font-weight, normal);
64+
color: var(--dropdown-text-color, #424242); /* theme.color.text.default */
65+
font-size: 1.4rem;
66+
line-height: 2rem;
67+
}
68+
69+
.dropdown-list li button:focus,
70+
.dropdown-list li a:focus {
71+
background: var(--dropdown-form-border, #d5d5d5); /* theme.color.neutral.formBorder */
72+
outline: 0.2rem auto Highlight;
73+
outline: 0.2rem auto -webkit-focus-ring-color;
74+
}
75+
76+
/* Visually hidden utility classes */
77+
.dropdown-visually-hidden {
78+
height: 0;
79+
width: 0;
80+
overflow: hidden;
81+
clip: rect(1px, 1px, 1px, 1px);
82+
}
83+
84+
.dropdown-visually-shown {
85+
height: unset;
86+
width: unset;
87+
clip: unset;
88+
overflow: visible;
89+
}
90+
91+
/* TabTransparentDropdown focus-within behavior */
92+
/* Hide the second toggle by default */
93+
.dropdown-transparent .dropdown-toggle-second {
94+
height: 0;
95+
width: 0;
96+
overflow: hidden;
97+
clip: rect(1px, 1px, 1px, 1px);
98+
}
99+
100+
/* Show the second toggle when focus is within the wrapper */
101+
.dropdown-transparent .dropdown-focus-wrapper.focus-within + .dropdown-toggle-second,
102+
.dropdown-transparent .dropdown-focus-wrapper:focus-within + .dropdown-toggle-second {
103+
height: unset;
104+
width: unset;
105+
clip: unset;
106+
overflow: visible;
107+
}
108+
109+
/* Show the first toggle by default */
110+
.dropdown-transparent .dropdown-focus-wrapper > .dropdown-toggle {
111+
height: unset;
112+
width: unset;
113+
clip: unset;
114+
overflow: visible;
115+
}
116+
117+
/* Hide the first toggle when focus is within the wrapper */
118+
.dropdown-transparent .dropdown-focus-wrapper.focus-within > .dropdown-toggle,
119+
.dropdown-transparent .dropdown-focus-wrapper:focus-within > .dropdown-toggle {
120+
height: 0;
121+
width: 0;
122+
overflow: hidden;
123+
clip: rect(1px, 1px, 1px, 1px);
124+
}
125+
126+
/* Menu positioning and animation for TabTransparentDropdown */
127+
.dropdown-transparent .dropdown-focus-wrapper > .dropdown-menu {
128+
animation: 100ms dropdown-fade-in ease-out;
129+
position: absolute;
130+
box-shadow: 0 0.5rem 0.5rem 0 rgba(0, 0, 0, 0.1);
131+
border: 1px solid var(--dropdown-form-border, #d5d5d5); /* theme.color.neutral.formBorder */
132+
top: calc(100% + 0.4rem);
133+
left: 0;
134+
}
135+
136+
/* Hide the menu by default */
137+
.dropdown-transparent .dropdown-focus-wrapper > .dropdown-menu {
138+
height: 0;
139+
width: 0;
140+
overflow: hidden;
141+
clip: rect(1px, 1px, 1px, 1px);
142+
}
143+
144+
/* Show the menu when focus is within the wrapper */
145+
.dropdown-transparent .dropdown-focus-wrapper.focus-within > .dropdown-menu,
146+
.dropdown-transparent .dropdown-focus-wrapper:focus-within > .dropdown-menu {
147+
height: unset;
148+
width: unset;
149+
clip: unset;
150+
overflow: visible;
151+
}

0 commit comments

Comments
 (0)