import { expect, within } from "storybook/test"; import type { Meta, StoryObj } from "@storybook/react-vite"; import type { ReactNode } from "react"; import { SafeAreaScope } from "../../core/SafeAreaEdgesContext"; import { Box } from "../containers/Box"; import { Text } from "../primitives/Text"; import { View } from "../primitives/View"; import { Story } from "../story-components/Story"; import { ScreenScrollView } from "./ScreenScrollView"; export default { title: "alouette/Layout/ScreenScrollView", component: ScreenScrollView, parameters: { componentSubtitle: "A screen-filling ScrollView: bg-screen frame, growing content, safe-area insets as content padding", docs: { description: { component: `### Features - \`bg-screen min-h-full\` frame and a \`grow\` content container, both extendable through \`className\` / \`contentContainerClassName\` (merged with tailwind-merge) - Safe-area insets applied to the **content**, so the background bleeds under the system bars while the content clears them - Edges default to everything an ancestor \`SafeAreaScope\` has not declared consumed; \`edges\` overrides them per screen - Insets are native-only: \`useSafeAreaInsets\` is stubbed to zeros on web ### Usage ~~~tsx Content {/* under a navigation header that already applies the top inset */} … {/* or explicitly, ignoring the scope */} … ~~~`, }, }, }, } satisfies Meta; interface RowsProps { count: number; } function Rows({ count }: RowsProps): ReactNode { return ( <> {Array.from({ length: count }, (_, index) => ( {`Item ${index + 1}`} ))} ); } export const PreviewStory: StoryObj = { name: "ScreenScrollView Preview", parameters: { chromatic: { disableSnapshot: true } }, render: () => ( ), }; export const VariantsStory: StoryObj = { name: "ScreenScrollView", render: () => ( ), }; export const Tests: StoryObj = { name: "ScreenScrollView Tests", render: () => ( ), play: async ({ canvasElement }) => { const canvas = within(canvasElement); const backgroundOf = (label: string): string => getComputedStyle(canvas.getByLabelText(label)).backgroundColor; const frame = canvas.getByLabelText("default screen"); const contentContainer = frame.firstElementChild; if (!contentContainer) { throw new Error("ScreenScrollView rendered no content container"); } await expect(getComputedStyle(contentContainer).flexGrow).toBe("1"); await expect(backgroundOf("default screen")).toBe( backgroundOf("screen reference"), ); await expect(backgroundOf("custom background screen")).toBe( backgroundOf("surface reference"), ); }, };