Skip to content

Commit 3325ad6

Browse files
Copilotfrancineluccajoshblack
authored
Add disableFullscreenOnNarrow prop to SelectPanel for opt-out of fullscreen behavior (#6138)
Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: francinelucca <[email protected]> Co-authored-by: Marie Lucca <[email protected]> Co-authored-by: joshblack <[email protected]> Co-authored-by: Josh Black <[email protected]>
1 parent 5a84cd3 commit 3325ad6

File tree

4 files changed

+115
-1
lines changed

4 files changed

+115
-1
lines changed

.changeset/good-ligers-pull.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@primer/react": minor
3+
---
4+
5+
Add disableFullscreenOnNarrow prop to SelectPanel for opt-out of fullscreen behavior

packages/react/src/SelectPanel/SelectPanel.docs.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,12 @@
183183
"type": "boolean",
184184
"description": "Whether to display the selected items at the top of the list",
185185
"default": "true"
186+
},
187+
{
188+
"name": "disableFullscreenOnNarrow",
189+
"type": "boolean",
190+
"description": "Whether to disable fullscreen behavior on narrow viewports. When `true`, the panel will maintain its anchored position regardless of viewport size. When `false`, the panel will go fullscreen on narrow viewports (if feature flag is enabled).",
191+
"defaultValue": "undefined (uses feature flag default)"
186192
}
187193
],
188194
"subcomponents": []

packages/react/src/SelectPanel/SelectPanel.test.tsx

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,6 +1066,100 @@ for (const useModernActionList of [false, true]) {
10661066
expect(options[2]).toHaveTextContent('item three')
10671067
})
10681068
})
1069+
1070+
describe('disableFullscreenOnNarrow prop', () => {
1071+
const renderSelectPanelWithFlags = (flags: Record<string, boolean>, props: Record<string, unknown> = {}) => {
1072+
return render(
1073+
<FeatureFlags flags={flags}>
1074+
<ThemeProvider>
1075+
<SingleSelectPanel {...props} />
1076+
</ThemeProvider>
1077+
</FeatureFlags>,
1078+
)
1079+
}
1080+
1081+
// Create a single-select version to test ResponsiveCloseButton behavior
1082+
function SingleSelectPanel(passthroughProps: Record<string, unknown>) {
1083+
const [filter, setFilter] = React.useState('')
1084+
const [open, setOpen] = React.useState(false)
1085+
1086+
return (
1087+
<ThemeProvider>
1088+
<SelectPanel
1089+
title="test title"
1090+
subtitle="test subtitle"
1091+
items={items}
1092+
placeholder="Select an item"
1093+
placeholderText="Filter items"
1094+
selected={undefined}
1095+
onSelectedChange={() => {}}
1096+
filterValue={filter}
1097+
onFilterChange={value => {
1098+
setFilter(value)
1099+
}}
1100+
open={open}
1101+
onOpenChange={open => setOpen(open)}
1102+
{...passthroughProps}
1103+
/>
1104+
</ThemeProvider>
1105+
)
1106+
}
1107+
1108+
it('should opt out of fullscreen when disableFullscreenOnNarrow=true even when feature flag is enabled', async () => {
1109+
const user = userEvent.setup()
1110+
1111+
renderSelectPanelWithFlags(
1112+
{
1113+
primer_react_select_panel_with_modern_action_list: useModernActionList,
1114+
primer_react_select_panel_fullscreen_on_narrow: true,
1115+
},
1116+
{disableFullscreenOnNarrow: true},
1117+
)
1118+
1119+
await user.click(screen.getByText('Select an item'))
1120+
1121+
// When disableFullscreenOnNarrow=true, the ResponsiveCloseButton should not be present
1122+
// even when the feature flag is enabled, indicating no fullscreen behavior
1123+
const responsiveCloseButton = screen.queryByRole('button', {name: 'Cancel and close'})
1124+
expect(responsiveCloseButton).not.toBeInTheDocument()
1125+
})
1126+
1127+
it('should use fullscreen behavior when disableFullscreenOnNarrow=false and feature flag is enabled', async () => {
1128+
const user = userEvent.setup()
1129+
1130+
renderSelectPanelWithFlags(
1131+
{
1132+
primer_react_select_panel_with_modern_action_list: useModernActionList,
1133+
primer_react_select_panel_fullscreen_on_narrow: true,
1134+
},
1135+
{disableFullscreenOnNarrow: false},
1136+
)
1137+
1138+
await user.click(screen.getByText('Select an item'))
1139+
1140+
// When feature flag is true and disableFullscreenOnNarrow is false, the ResponsiveCloseButton should be present
1141+
// indicating fullscreen behavior is active
1142+
const responsiveCloseButton = screen.getByRole('button', {name: 'Cancel and close'})
1143+
expect(responsiveCloseButton).toBeInTheDocument()
1144+
})
1145+
1146+
it('should default to feature flag value when disableFullscreenOnNarrow is undefined', async () => {
1147+
const user = userEvent.setup()
1148+
1149+
// Test with feature flag disabled
1150+
renderSelectPanelWithFlags({
1151+
primer_react_select_panel_with_modern_action_list: useModernActionList,
1152+
primer_react_select_panel_fullscreen_on_narrow: false,
1153+
})
1154+
1155+
await user.click(screen.getByText('Select an item'))
1156+
1157+
// When feature flag is false and disableFullscreenOnNarrow is undefined,
1158+
// the ResponsiveCloseButton should not be present
1159+
const responsiveCloseButton = screen.queryByRole('button', {name: 'Cancel and close'})
1160+
expect(responsiveCloseButton).not.toBeInTheDocument()
1161+
})
1162+
})
10691163
})
10701164
})
10711165
}

packages/react/src/SelectPanel/SelectPanel.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,13 @@ interface SelectPanelBaseProps {
101101
*/
102102
footer?: string | React.ReactElement
103103
showSelectedOptionsFirst?: boolean
104+
/**
105+
* Whether to disable fullscreen behavior on narrow viewports.
106+
* When `true`, the panel will maintain its anchored position regardless of viewport size.
107+
* When `false`, the panel will go fullscreen on narrow viewports (if feature flag is enabled).
108+
* @default undefined (uses feature flag default)
109+
*/
110+
disableFullscreenOnNarrow?: boolean
104111
}
105112

106113
// onCancel is optional with variant=anchored, but required with variant=modal
@@ -172,6 +179,7 @@ function Panel({
172179
variant = 'anchored',
173180
secondaryAction,
174181
showSelectedOptionsFirst = true,
182+
disableFullscreenOnNarrow,
175183
...listProps
176184
}: SelectPanelProps): JSX.Element {
177185
const titleId = useId()
@@ -192,7 +200,8 @@ function Panel({
192200
const [prevOpen, setPrevOpen] = useState(open)
193201

194202
const usingModernActionList = useFeatureFlag('primer_react_select_panel_with_modern_action_list')
195-
const usingFullScreenOnNarrow = useFeatureFlag('primer_react_select_panel_fullscreen_on_narrow')
203+
const featureFlagFullScreenOnNarrow = useFeatureFlag('primer_react_select_panel_fullscreen_on_narrow')
204+
const usingFullScreenOnNarrow = disableFullscreenOnNarrow ? false : featureFlagFullScreenOnNarrow
196205
const shouldOrderSelectedFirst =
197206
useFeatureFlag('primer_react_select_panel_order_selected_at_top') && showSelectedOptionsFirst
198207

0 commit comments

Comments
 (0)