Standardize create-flow option steps on one question-and-options layout and Selection sizes.
Method cards, chips, and the right rail now share the two-column shell; last options clear the footer fade, See all stays under the stack, and the left heading no longer jumps when the list expands. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
2fc7fbf818
commit
24a9615c0c
26 files changed
+354
-245
No files matched your search
@@ -126,6 +126,18 @@ describe("CardStack Component", () => {
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test("single-stack See all / Show less is centered, not end-aligned", () => {
|
||||
render(
|
||||
<CardStack cards={SAMPLE_CARDS} hasMore={true} layout="singleStack" />,
|
||||
);
|
||||
|
||||
const toggle = screen.getByRole("button", {
|
||||
name: "See all communication approaches",
|
||||
});
|
||||
expect(toggle.className).toMatch(/\bself-center\b/);
|
||||
expect(toggle.className).not.toMatch(/\bself-end\b/);
|
||||
});
|
||||
|
||||
test("calls onCardSelect when a card is clicked", () => {
|
||||
const onCardSelect = vi.fn();
|
||||
render(<CardStack cards={SAMPLE_CARDS} onCardSelect={onCardSelect} />);
|
||||
|
||||
@@ -54,6 +54,33 @@ describe("Selection Component", () => {
|
||||
|
||||
const card = screen.getByRole("button");
|
||||
expect(card).toHaveClass("flex-row");
|
||||
expect(card).toHaveAttribute("data-selection-size", "l");
|
||||
});
|
||||
|
||||
it("maps size s to a chip with accessible selected state", () => {
|
||||
render(
|
||||
<Selection
|
||||
label="Open membership"
|
||||
supportText="Anyone can join"
|
||||
size="s"
|
||||
selected
|
||||
/>,
|
||||
);
|
||||
|
||||
const chip = screen.getByRole("button", {
|
||||
name: "Open membership: Anyone can join",
|
||||
});
|
||||
expect(chip).toHaveAttribute("aria-pressed", "true");
|
||||
expect(chip).toHaveTextContent("Open membership");
|
||||
expect(screen.queryByText("Anyone can join")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("uses size m for compact tiles and exposes aria-pressed", () => {
|
||||
render(<Selection {...defaultProps} size="m" selected />);
|
||||
|
||||
const card = screen.getByRole("button");
|
||||
expect(card).toHaveAttribute("data-selection-size", "m");
|
||||
expect(card).toHaveAttribute("aria-pressed", "true");
|
||||
});
|
||||
|
||||
it("does not render a helper icon by default", () => {
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
CREATE_FLOW_MD_CENTERED_SHELL_CLASS,
|
||||
CREATE_FLOW_PAGE_GUTTER_CLASS,
|
||||
CREATE_FLOW_FIXED_TOP_BANNER_OFFSET_CLASS,
|
||||
CREATE_FLOW_SCROLL_END_PAD_CLASS,
|
||||
CREATE_FLOW_VIEWPORT_FRAME_CLASS,
|
||||
getCreateFlowContentMaxClass,
|
||||
} from "../../app/(app)/create/components/createFlowLayoutTokens";
|
||||
@@ -39,7 +40,11 @@ describe("createFlowLayoutTokens", () => {
|
||||
expect(CREATE_FLOW_VIEWPORT_FRAME_CLASS).toContain("max-h-dvh");
|
||||
});
|
||||
|
||||
it("centers lockup+card and card-stack steps in the nav–footer band from md", () => {
|
||||
it("pads option scrollports past the footer scrim", () => {
|
||||
expect(CREATE_FLOW_SCROLL_END_PAD_CLASS).toBe("pb-12");
|
||||
});
|
||||
|
||||
it("centers review lockup+card steps in the nav–footer band from md", () => {
|
||||
expect(CREATE_FLOW_MD_CENTERED_MAIN_CLASS).toBe(
|
||||
"items-start justify-center overflow-y-auto",
|
||||
);
|
||||
@@ -55,7 +60,7 @@ describe("createFlowLayoutTokens", () => {
|
||||
);
|
||||
expect(
|
||||
getCreateFlowContentMaxClass({ step: "communication-methods" }),
|
||||
).toBe(CREATE_FLOW_WIDE_MAX_CLASS);
|
||||
).toBe(CREATE_FLOW_TWO_COLUMN_MAX_WIDTH_CLASS);
|
||||
expect(getCreateFlowContentMaxClass({ step: "final-review" })).toBe(
|
||||
CREATE_FLOW_TWO_COLUMN_MAX_WIDTH_CLASS,
|
||||
);
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { CREATE_FLOW_SCREEN_REGISTRY } from "../../app/(app)/create/utils/createFlowScreenRegistry";
|
||||
import {
|
||||
CREATE_FLOW_SCREEN_REGISTRY,
|
||||
createFlowStepUsesCardLayout,
|
||||
} from "../../app/(app)/create/utils/createFlowScreenRegistry";
|
||||
import { VALID_STEPS } from "../../app/(app)/create/utils/flowSteps";
|
||||
|
||||
describe("create flow registry vs valid steps (CR-92 §3)", () => {
|
||||
@@ -10,4 +13,11 @@ describe("create flow registry vs valid steps (CR-92 §3)", () => {
|
||||
}
|
||||
expect(keys.size).toBe(VALID_STEPS.length);
|
||||
});
|
||||
|
||||
it("keeps Figma card-kind ids on the method-card steps", () => {
|
||||
expect(createFlowStepUsesCardLayout("communication-methods")).toBe(true);
|
||||
expect(createFlowStepUsesCardLayout("membership-methods")).toBe(true);
|
||||
expect(createFlowStepUsesCardLayout("conflict-management")).toBe(true);
|
||||
expect(createFlowStepUsesCardLayout("decision-approaches")).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -234,10 +234,19 @@ describe("flowSteps", () => {
|
||||
expect(isDirectTemplateReviewEntry(null)).toBe(false);
|
||||
});
|
||||
|
||||
it("uses split-column scroll for select, right-rail, and stakeholders", () => {
|
||||
it("uses split-column scroll for select, method-card, right-rail, and stakeholders", () => {
|
||||
expect(createFlowStepUsesSelectSplitScroll("community-structure")).toBe(
|
||||
true,
|
||||
);
|
||||
expect(createFlowStepUsesSelectSplitScroll("communication-methods")).toBe(
|
||||
true,
|
||||
);
|
||||
expect(createFlowStepUsesSelectSplitScroll("membership-methods")).toBe(
|
||||
true,
|
||||
);
|
||||
expect(createFlowStepUsesSelectSplitScroll("conflict-management")).toBe(
|
||||
true,
|
||||
);
|
||||
expect(createFlowStepUsesSelectSplitScroll("confirm-stakeholders")).toBe(
|
||||
true,
|
||||
);
|
||||
|
||||
Reference in new issue
Block a user