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"),
);
},
};