mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
fix(site): keep mobile model picker effort row and last model visible (#27336)
This commit is contained in:
+12
-4
@@ -83,13 +83,21 @@
|
||||
calc(100vh - var(--mobile-dropdown-above-composer-bottom, 9rem) - 1rem)
|
||||
) !important;
|
||||
overflow: hidden !important;
|
||||
display: flex !important;
|
||||
flex-direction: column !important;
|
||||
}
|
||||
/* min-height: 0 on both flex children lets the list shrink below its
|
||||
content and scroll inside the capped column instead of overflowing. */
|
||||
.mobile-full-width-dropdown-above-composer > [cmdk-root],
|
||||
.mobile-full-width-dropdown-above-composer > [cmdk-root] > [cmdk-list] {
|
||||
flex: 1 1 0% !important;
|
||||
min-height: 0 !important;
|
||||
}
|
||||
.mobile-full-width-dropdown-above-composer > [cmdk-root] > [cmdk-list] {
|
||||
max-height: none !important;
|
||||
}
|
||||
.mobile-full-width-dropdown-above-composer
|
||||
.mobile-full-width-dropdown-scroll-area {
|
||||
max-height: calc(
|
||||
var(--mobile-dropdown-above-composer-max-height, 18rem) -
|
||||
0.5rem
|
||||
) !important;
|
||||
overflow-y: auto !important;
|
||||
overscroll-behavior: contain;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { expect, fn, screen, userEvent, waitFor, within } from "storybook/test";
|
||||
import { ModelSelector, type ModelSelectorOption } from "./ModelSelector";
|
||||
import { MockModelSelectorOption } from "./modelSelectorFixtures";
|
||||
@@ -450,3 +450,54 @@ export const EffortRowClampedToMax: Story = {
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
// The pinned effort row must stay inside the mobile dropdown's capped
|
||||
// height above the composer while the model list scrolls.
|
||||
export const MobileEffortRow: Story = {
|
||||
args: {
|
||||
options: [
|
||||
...Array.from({ length: 30 }, (_, index) => ({
|
||||
...MockModelSelectorOption,
|
||||
id: `openai/model-${index}`,
|
||||
model: `model-${index}`,
|
||||
displayName: `Model ${index}`,
|
||||
})),
|
||||
effortModel,
|
||||
],
|
||||
value: "openai/gpt-5",
|
||||
reasoningEffort: "medium",
|
||||
onReasoningEffortChange: fn(),
|
||||
enableMobileFullWidthDropdown: true,
|
||||
},
|
||||
parameters: {
|
||||
// The interaction runner defaults to a desktop width where the
|
||||
// mobile dropdown CSS never applies, so pin a mobile viewport.
|
||||
viewport: { defaultViewport: "mobile1" },
|
||||
// Capture the visual snapshot at a mobile width so the pinned
|
||||
// effort row and scrollable list render in the CI visual gate.
|
||||
lostpixel: { breakpoints: [320] },
|
||||
},
|
||||
decorators: [
|
||||
(Story) => {
|
||||
useEffect(() => {
|
||||
// Tight enough that the model list plus the pinned effort row
|
||||
// overflow the dropdown, forcing the layout under test.
|
||||
const root = document.documentElement.style;
|
||||
root.setProperty(
|
||||
"--mobile-dropdown-above-composer-max-height",
|
||||
"260px",
|
||||
);
|
||||
return () => {
|
||||
root.removeProperty("--mobile-dropdown-above-composer-max-height");
|
||||
};
|
||||
}, []);
|
||||
return <Story />;
|
||||
},
|
||||
],
|
||||
play: async ({ canvasElement }) => {
|
||||
// Open the picker so the snapshot captures the dropdown, the pinned
|
||||
// effort row, and the scrollable list.
|
||||
await userEvent.click(within(canvasElement).getByRole("combobox"));
|
||||
await within(document.body).findByRole("listbox");
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user