diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 9abcf78e92..6068fecda0 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -110,6 +110,8 @@ jobs: run: pnpm exec pixel-storybook env: PIXEL_KEY: ${{ secrets.PIXEL_KEY }} + # On pull_request, github.sha is a synthetic merge commit, not the PR head. + PIXEL_COMMIT: ${{ github.event.pull_request.head.sha || github.sha }} # Auto-approve on mainline to avoid blocking CI after squash merges. PIXEL_AUTO_REVIEW: ${{ github.ref == 'refs/heads/main' }} diff --git a/.storybook/preview.ts b/.storybook/preview.ts index ad5833c39f..ef464fb77a 100644 --- a/.storybook/preview.ts +++ b/.storybook/preview.ts @@ -1,5 +1,6 @@ /// +import { isPixel } from "@coder/pixel-storybook/storyapi"; import codiconCssUrl from "@vscode/codicons/dist/codicon.css?url"; import { createElement } from "react"; @@ -29,6 +30,11 @@ if (typeof window !== "undefined") { }); } +// Lets us skip motion animation during Pixel captures. +if (typeof document !== "undefined" && isPixel()) { + document.documentElement.setAttribute("data-pixel", "true"); +} + // Inject codicon stylesheet immediately (before any components render) // Must be a element with id "vscode-codicon-stylesheet" for vscode-elements if ( diff --git a/packages/ui/src/components/Icon/Icon.css b/packages/ui/src/components/Icon/Icon.css index 42a3429401..9967622c11 100644 --- a/packages/ui/src/components/Icon/Icon.css +++ b/packages/ui/src/components/Icon/Icon.css @@ -13,3 +13,8 @@ animation: none; } } + +/* data-pixel is set in .storybook/preview.ts via isPixel(). */ +:root[data-pixel] .ui-icon--spin { + animation: none; +} diff --git a/packages/ui/src/components/Menu/Menu.css b/packages/ui/src/components/Menu/Menu.css index c4a10c0e0a..ec56a68507 100644 --- a/packages/ui/src/components/Menu/Menu.css +++ b/packages/ui/src/components/Menu/Menu.css @@ -140,6 +140,14 @@ } } +/* data-pixel is set in .storybook/preview.ts via isPixel(). */ +@media (prefers-reduced-motion: no-preference) { + :where(:root[data-pixel]) .ui-menu[data-state="open"], + :where(:root[data-pixel]) .ui-menu[data-state="closed"] { + animation: none; + } +} + @media (forced-colors: active) { .ui-menu__item[data-highlighted], .ui-menu__item[data-state="open"] { diff --git a/packages/ui/src/components/ProgressBar/ProgressBar.css b/packages/ui/src/components/ProgressBar/ProgressBar.css index dc31caec85..5dcdd4453b 100644 --- a/packages/ui/src/components/ProgressBar/ProgressBar.css +++ b/packages/ui/src/components/ProgressBar/ProgressBar.css @@ -52,3 +52,8 @@ background: Highlight; } } + +/* data-pixel is set in .storybook/preview.ts via isPixel(). */ +:root[data-pixel] .ui-progress-bar--indeterminate .ui-progress-bar__indicator { + animation: none; +} diff --git a/packages/ui/src/components/Spinner/Spinner.css b/packages/ui/src/components/Spinner/Spinner.css index 023c91a016..eb32eb4ba4 100644 --- a/packages/ui/src/components/Spinner/Spinner.css +++ b/packages/ui/src/components/Spinner/Spinner.css @@ -50,3 +50,8 @@ border-inline-end-color: Highlight; } } + +/* data-pixel is set in .storybook/preview.ts via isPixel(). */ +:root[data-pixel] .ui-spinner { + animation: none; +} diff --git a/packages/ui/src/vscode-parity.stories.tsx b/packages/ui/src/vscode-parity.stories.tsx index d37c2067f4..a9a7e49a93 100644 --- a/packages/ui/src/vscode-parity.stories.tsx +++ b/packages/ui/src/vscode-parity.stories.tsx @@ -24,7 +24,7 @@ import { ProgressBar } from "./components/ProgressBar/ProgressBar"; import { SearchInput } from "./components/SearchInput/SearchInput"; import { Spinner } from "./components/Spinner/Spinner"; import { StatusPill } from "./components/StatusPill/StatusPill"; -import { openMenu, PIXEL_ALL_THEMES } from "./storybook"; +import { PIXEL_ALL_THEMES } from "./storybook"; import type { Meta, StoryObj } from "@storybook/react-vite"; @@ -177,8 +177,7 @@ const Parity = (): React.JSX.Element => ( ); -/* The reference menu renders inline; ours is a real portalled DropdownMenu, - so the play function opens it under its trigger. */ +/* defaultOpen + an invisible trigger mirror the reference's `show`. */ const MenuParity = (): React.JSX.Element => (
( fontSize: "13px", }} > - + - + Start workspace @@ -228,7 +227,4 @@ export const SideBySide: Story = {}; export const Menu: Story = { render: () => , - play: async ({ canvasElement }) => { - await openMenu(canvasElement, "Menu"); - }, };