Skip to content

Commit aca5999

Browse files
z-index fixes for dropdowns in connect-react (#19326)
* z-index fixes for dropdowns * linting fixes * PR feedback * version and changelog * Update ControlSelect.tsx * Update ControlSelect.tsx
1 parent d59f000 commit aca5999

File tree

7 files changed

+129
-66
lines changed

7 files changed

+129
-66
lines changed

packages/connect-react/CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,21 @@
22

33
# Changelog
44

5+
## [2.2.0] - 2025-11-29
6+
7+
### Added
8+
9+
- Added React 19 support to peer dependencies
10+
11+
### Fixed
12+
13+
- Fixed dropdown menus being clipped or hidden behind other elements when rendered inside containers with overflow constraints (e.g., workflow builders, modals)
14+
- All select components now portal their menus to the document body with proper z-index handling
15+
16+
### Changed
17+
18+
- Upgraded `react-select` from 5.8.2 to 5.9.0 for React 19 compatibility
19+
520
## [2.1.2] - 2025-11-14
621

722
### Fixed

packages/connect-react/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@pipedream/connect-react",
3-
"version": "2.1.2",
3+
"version": "2.2.0",
44
"description": "Pipedream Connect library for React",
55
"files": [
66
"dist"
@@ -34,7 +34,7 @@
3434
"@tanstack/react-query": "^5.59.16",
3535
"lodash.isequal": "^4.5.0",
3636
"react-markdown": "^9.0.1",
37-
"react-select": "^5.8.2"
37+
"react-select": "^5.9.0"
3838
},
3939
"devDependencies": {
4040
"@emotion/react": "^11.13.5",
@@ -44,7 +44,7 @@
4444
"vite-plugin-dts": "^4.3.0"
4545
},
4646
"peerDependencies": {
47-
"react": "^16.8.0 || ^17.0.0 || ^18.0.0",
48-
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
47+
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
48+
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
4949
}
5050
}

packages/connect-react/src/components/ControlApp.tsx

Lines changed: 54 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -146,44 +146,62 @@ export function ControlApp({ app }: ControlAppProps) {
146146
app,
147147
...formFieldCtx,
148148
})}>
149-
{isLoadingAccounts ?
150-
`Loading ${app.name} accounts...`
151-
: accounts.length ?
152-
<Select
153-
instanceId={id}
154-
value={selectValue}
155-
options={selectOptions}
156-
{...selectProps}
157-
required={true}
158-
placeholder={`Select ${app.name} account...`}
159-
isLoading={isLoadingAccounts}
160-
isClearable={true}
161-
isSearchable={true}
162-
getOptionLabel={(a) => a.name ?? ""}
163-
getOptionValue={(a) => a.id}
164-
onChange={(a) => {
165-
if (a) {
166-
if (a.id === "_new") {
167-
// start connect account and then select it, etc.
168-
// TODO unset / put in loading state
169-
startConnectAccount();
149+
{isLoadingAccounts
150+
? `Loading ${app.name} accounts...`
151+
: accounts.length
152+
? (
153+
<Select
154+
instanceId={id}
155+
value={selectValue}
156+
options={selectOptions}
157+
{...selectProps}
158+
// These must come AFTER selectProps spread to avoid being overridden
159+
classNamePrefix="react-select"
160+
required={true}
161+
placeholder={`Select ${app.name} account...`}
162+
isLoading={isLoadingAccounts}
163+
isClearable={true}
164+
isSearchable={true}
165+
getOptionLabel={(a) => a.name ?? ""}
166+
getOptionValue={(a) => a.id}
167+
menuPortalTarget={
168+
typeof document !== "undefined"
169+
? document.body
170+
: null
171+
}
172+
menuPosition="fixed"
173+
styles={{
174+
...selectProps.styles,
175+
menuPortal: (base) => ({
176+
...base,
177+
zIndex: 99999,
178+
}),
179+
}}
180+
onChange={(a) => {
181+
if (a) {
182+
if (a.id === "_new") {
183+
// start connect account and then select it, etc.
184+
// TODO unset / put in loading state
185+
startConnectAccount();
186+
} else {
187+
onChange({
188+
authProvisionId: a.id,
189+
});
190+
}
170191
} else {
171-
onChange({
172-
authProvisionId: a.id,
173-
});
192+
onChange(undefined);
174193
}
175-
} else {
176-
onChange(undefined);
177-
}
178-
}}
179-
/>
180-
:
181-
<button type="button" {...getProps("connectButton", baseStylesConnectButton, {
182-
app,
183-
...formFieldCtx,
184-
})} onClick={() => startConnectAccount()}>
185-
Connect {app.name}
186-
</button>
194+
}}
195+
/>
196+
)
197+
: (
198+
<button type="button" {...getProps("connectButton", baseStylesConnectButton, {
199+
app,
200+
...formFieldCtx,
201+
})} onClick={() => startConnectAccount()}>
202+
Connect {app.name}
203+
</button>
204+
)
187205
}
188206
</div>
189207
);

packages/connect-react/src/components/ControlSelect.tsx

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,8 +256,25 @@ export function ControlSelect<T extends PropOptionValue>({
256256
onChange={handleChange}
257257
{...props}
258258
{...selectProps}
259-
components={finalComponents}
260259
{...additionalProps}
260+
// These must come AFTER spreads to avoid being overridden
261+
classNamePrefix="react-select"
262+
menuPortalTarget={
263+
typeof document !== "undefined"
264+
? document.body
265+
: null
266+
}
267+
menuPosition="fixed"
268+
styles={{
269+
// eslint-disable-next-line react/prop-types
270+
...props.styles,
271+
...selectProps?.styles,
272+
menuPortal: (base) => ({
273+
...base,
274+
zIndex: 99999,
275+
}),
276+
}}
277+
components={finalComponents}
261278
/>
262279
);
263280
}

packages/connect-react/src/components/SelectApp.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,18 @@ export function SelectApp({
172172
}}
173173
onMenuScrollToBottom={handleMenuScrollToBottom}
174174
isLoading={isLoading}
175+
menuPortalTarget={
176+
typeof document !== "undefined"
177+
? document.body
178+
: null
179+
}
180+
menuPosition="fixed"
181+
styles={{
182+
menuPortal: (base) => ({
183+
...base,
184+
zIndex: 99999,
185+
}),
186+
}}
175187
/>
176188
);
177189
}

packages/connect-react/src/components/SelectComponent.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,18 @@ export function SelectComponent({
9898
onMenuScrollToBottom={handleMenuScrollToBottom}
9999
isLoading={isLoading}
100100
components={customComponents}
101+
menuPortalTarget={
102+
typeof document !== "undefined"
103+
? document.body
104+
: null
105+
}
106+
menuPosition="fixed"
107+
styles={{
108+
menuPortal: (base) => ({
109+
...base,
110+
zIndex: 99999,
111+
}),
112+
}}
101113
/>
102114
);
103115
}

pnpm-lock.yaml

Lines changed: 14 additions & 25 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)