From 44c465a25b3a67e250fa762e331f7de46bcb7f6f Mon Sep 17 00:00:00 2001 From: Ivy Olamit Date: Fri, 13 Feb 2026 13:09:52 -0800 Subject: [PATCH 1/4] [LEMS-3889/adjust-scrollable-viewport] docs(changeset): Added a reusable narrowViewportDecorator that constrains the story width to 400px, forcing content overflow so scroll buttons appear and applied the decorator to all "with scroll" radio widget stories. --- .changeset/six-crabs-chew.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/six-crabs-chew.md diff --git a/.changeset/six-crabs-chew.md b/.changeset/six-crabs-chew.md new file mode 100644 index 0000000000..fa6f554a32 --- /dev/null +++ b/.changeset/six-crabs-chew.md @@ -0,0 +1,5 @@ +--- +"@khanacademy/perseus": patch +--- + +Added a reusable narrowViewportDecorator that constrains the story width to 400px, forcing content overflow so scroll buttons appear and applied the decorator to all "with scroll" radio widget stories. From d0396880a0a73adc0bd119daf272f98166dfe3f6 Mon Sep 17 00:00:00 2001 From: Ivy Olamit Date: Fri, 13 Feb 2026 13:11:39 -0800 Subject: [PATCH 2/4] [LEMS-3889/adjust-scrollable-viewport] [Radio] Added a reusable narrowViewportDecorator that constrains forcing content overflow so scroll buttons appear --- .../src/widgets/__testutils__/story-decorators.tsx | 10 ++++++++++ .../__docs__/multiple-choice-demo.new.stories.tsx | 5 +++++ ...ultiple-choice-initial-state-regression.stories.tsx | 4 ++++ 3 files changed, 19 insertions(+) diff --git a/packages/perseus/src/widgets/__testutils__/story-decorators.tsx b/packages/perseus/src/widgets/__testutils__/story-decorators.tsx index ede8bf2e4d..b1511934e8 100644 --- a/packages/perseus/src/widgets/__testutils__/story-decorators.tsx +++ b/packages/perseus/src/widgets/__testutils__/story-decorators.tsx @@ -1,5 +1,7 @@ import * as React from "react"; +import type {Decorator} from "@storybook/react-vite"; + export const mobileDecorator = (Story) => (
@@ -82,3 +84,11 @@ export const articleFloatRightDecorator = (Story) => (
{articleContent3}
); + +// Decorator to constrain the viewport width so that overflow content +// triggers scroll buttons in the radio widget. +export const narrowViewportDecorator: Decorator = (Story) => ( +
+ +
+); diff --git a/packages/perseus/src/widgets/radio/__docs__/multiple-choice-demo.new.stories.tsx b/packages/perseus/src/widgets/radio/__docs__/multiple-choice-demo.new.stories.tsx index 956693e88d..fb244c0f55 100644 --- a/packages/perseus/src/widgets/radio/__docs__/multiple-choice-demo.new.stories.tsx +++ b/packages/perseus/src/widgets/radio/__docs__/multiple-choice-demo.new.stories.tsx @@ -3,6 +3,7 @@ import * as React from "react"; import {getFeatureFlags} from "../../../testing/feature-flags-util"; import {ServerItemRendererWithDebugUI} from "../../../testing/server-item-renderer-with-debug-ui"; +import {narrowViewportDecorator} from "../../__testutils__/story-decorators"; import {groupedRadioRationaleQuestion} from "../../graded-group/graded-group.testdata"; import { question, @@ -122,6 +123,7 @@ export const SelectWithImagesAndScroll = { question: SingleSelectOverflowImageContent, }), }, + decorators: [narrowViewportDecorator], }; export const SingleSelectWithScroll = { @@ -130,6 +132,7 @@ export const SingleSelectWithScroll = { question: SingleSelectOverflowContent, }), }, + decorators: [narrowViewportDecorator], }; export const MultiSelectSimple = { @@ -154,6 +157,7 @@ export const MultiSelectWithScroll = { question: multiChoiceQuestionSimpleOverflowContent, }), }, + decorators: [narrowViewportDecorator], }; export const GradedGroupSetWithScroll = { @@ -162,6 +166,7 @@ export const GradedGroupSetWithScroll = { question: overflowContentInGradedGroupSet, }), }, + decorators: [narrowViewportDecorator], }; export const GradedGroup = { diff --git a/packages/perseus/src/widgets/radio/__docs__/multiple-choice-initial-state-regression.stories.tsx b/packages/perseus/src/widgets/radio/__docs__/multiple-choice-initial-state-regression.stories.tsx index d99cdc8336..4cf6294c72 100644 --- a/packages/perseus/src/widgets/radio/__docs__/multiple-choice-initial-state-regression.stories.tsx +++ b/packages/perseus/src/widgets/radio/__docs__/multiple-choice-initial-state-regression.stories.tsx @@ -12,6 +12,7 @@ import {ApiOptions} from "../../../perseus-api"; import {ServerItemRenderer} from "../../../server-item-renderer"; import {getFeatureFlags} from "../../../testing/feature-flags-util"; import {testDependenciesV2} from "../../../testing/test-dependencies"; +import {narrowViewportDecorator} from "../../__testutils__/story-decorators"; import { choicesWithGraphie, choicesWithImages, @@ -155,6 +156,7 @@ export const SingleSelectWithImagesAndScroll: Story = { }), }), }, + decorators: [narrowViewportDecorator], }; export const SingleSelectWithLongMathjax: Story = { @@ -329,6 +331,7 @@ export const MultiSelectWithImagesAndScroll: Story = { }), }), }, + decorators: [narrowViewportDecorator], }; export const MultiSelectWithLongText: Story = { @@ -363,6 +366,7 @@ export const GradedGroupSetWithScroll: Story = { question: overflowContentInGradedGroupSet, }), }, + decorators: [narrowViewportDecorator], }; function RadioQuestionRenderer(props: { From 60a71496f1babade63ef5b8416382550920d5245 Mon Sep 17 00:00:00 2001 From: Ivy Olamit Date: Fri, 13 Feb 2026 16:11:35 -0800 Subject: [PATCH 3/4] Update packages/perseus/src/widgets/__testutils__/story-decorators.tsx Co-authored-by: Anakaren --- packages/perseus/src/widgets/__testutils__/story-decorators.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/perseus/src/widgets/__testutils__/story-decorators.tsx b/packages/perseus/src/widgets/__testutils__/story-decorators.tsx index b1511934e8..9791ca27ba 100644 --- a/packages/perseus/src/widgets/__testutils__/story-decorators.tsx +++ b/packages/perseus/src/widgets/__testutils__/story-decorators.tsx @@ -85,7 +85,7 @@ export const articleFloatRightDecorator = (Story) => ( ); -// Decorator to constrain the viewport width so that overflow content +// Force overflow so the radio widget’s scroll controls render in these stories. // triggers scroll buttons in the radio widget. export const narrowViewportDecorator: Decorator = (Story) => (
From cf27f08bee8e8a24ca127933887ff8d9875b83df Mon Sep 17 00:00:00 2001 From: Ivy Olamit Date: Fri, 13 Feb 2026 16:13:29 -0800 Subject: [PATCH 4/4] remove unnecessary comment --- packages/perseus/src/widgets/__testutils__/story-decorators.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/perseus/src/widgets/__testutils__/story-decorators.tsx b/packages/perseus/src/widgets/__testutils__/story-decorators.tsx index 9791ca27ba..7b2439ccf5 100644 --- a/packages/perseus/src/widgets/__testutils__/story-decorators.tsx +++ b/packages/perseus/src/widgets/__testutils__/story-decorators.tsx @@ -86,7 +86,6 @@ export const articleFloatRightDecorator = (Story) => ( ); // Force overflow so the radio widget’s scroll controls render in these stories. -// triggers scroll buttons in the radio widget. export const narrowViewportDecorator: Decorator = (Story) => (