-
Notifications
You must be signed in to change notification settings - Fork 0
feat(workspace): Storybook tokens for rehearsal components #897
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
seonghobae
wants to merge
48
commits into
develop
Choose a base branch
from
feat/workspace-storybook-tokens
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
48 commits
Select commit
Hold shift + click to select a range
a61093b
feat(workspace): add Storybook coverage and tokens for rehearsal comp…
seonghobae dec4e17
fix(storybook): provide required progress story args
seonghobae 958c6b7
fix(storybook): provide required role switcher args
seonghobae 87ed620
test(workspace): reject inert rehearsal callout actions
seonghobae dfea7b7
fix(workspace): disable unwired rehearsal callout actions
seonghobae 6f56d9d
test(workspace): require localized confidence tooltip
seonghobae f54dd21
fix(workspace): localize confidence badge tooltip
seonghobae e68d37d
docs(workspace): explain overlap warning component
seonghobae 05ec060
docs(workspace): explain rehearsal callout behavior
seonghobae e79f1b9
docs(workspace): explain roadmap helpers
seonghobae 6a6c085
docs(ranges): explain range summary component
seonghobae edf525f
test(design): expose missing confidence badge size variants
seonghobae 33c64c9
feat(design): support Figma confidence badge sizes
seonghobae 248eafc
feat(tokens): encode Figma confidence badge heights
seonghobae 785c84e
docs(storybook): inventory both confidence badge sizes
seonghobae f7f0c9e
docs(design): bind confidence size variants to Figma
seonghobae 65e6236
docs(changelog): record Figma confidence size parity
seonghobae 7db55a8
fix(design): keep confidence badge width semantics stable
seonghobae 1f4cb0a
fix(quality): document confidence badge size contract
seonghobae f579995
feat(storybook): cover OverlapWarningList and enable the first practi…
seonghobae 86be298
fix(storybook): apply current review feedback
seonghobae abf28f3
test(workspace): keep chord label placeholders literal
seonghobae d05f9d8
fix(workspace): interpolate chord edit labels once
seonghobae 6f5cf97
test(design): lock confidence badge to live Figma semantic tokens
seonghobae 7b38eaa
fix(design): align confidence tokens with live Figma semantics
seonghobae bc409e6
test(design): resolve Figma token source from workspace root
seonghobae bf87847
test(design): pin Figma confidence typography
seonghobae 24026fd
fix(design): align confidence badge typography
seonghobae 691061a
test(workspace): cover repeated overlap warnings
seonghobae d31a6ce
fix(workspace): keep repeated overlap warnings distinct
seonghobae 58a4341
Merge remote-tracking branch 'origin/develop' into feat/workspace-sto…
seonghobae 1de3d90
merge(develop): keep playable-range copy with Storybook tokens
seonghobae 0309be8
fix(design): restore component contract governance
seonghobae 9da6487
test(workspace): require readable light clash tokens
seonghobae 9484322
fix(workspace): support light clash surfaces
seonghobae d678f37
fix(ranges): use readable clash surface
seonghobae e040c2d
fix(tokens): add light clash palette
seonghobae b172221
test(storybook): cover light clash surface
seonghobae 6238356
docs(a11y): trace overlap contrast repair
seonghobae 4f4c200
docs(design): bind light warning and live Figma drift
seonghobae c39e51f
docs(changelog): record clash contrast repair
seonghobae 30d7e69
docs(design): record restored warning authority
seonghobae 0b81117
docs(a11y): record restored Figma warning states
seonghobae 027bd34
docs(design): bind current Figma warning authority
seonghobae 1c58613
probe: write-scope retry
seonghobae 163c2e7
chore: remove write-access probe from Storybook tokens branch
seonghobae 192f188
docs(design): bind live overlap-warning authority
seonghobae d436820
docs(a11y): align warning provenance and security notes
seonghobae File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
39 changes: 39 additions & 0 deletions
39
apps/desktop/src/features/workspace/ConfidenceBadge.stories.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| import type { Meta, StoryObj } from "@storybook/react-vite"; | ||
| import { ConfidenceBadge } from "./ConfidenceBadge"; | ||
|
|
||
| /** Storybook metadata for the Figma 19-239 confidence-badge level and size matrix. */ | ||
| const meta = { | ||
| title: "Workspace/ConfidenceBadge", | ||
| component: ConfidenceBadge, | ||
| parameters: { | ||
| layout: "centered", | ||
| docs: { | ||
| description: { | ||
| component: | ||
| "Figma 19-239 Confidence Badge. Mirrors Level=Low/Medium/High and Size=Compact/Default with workspace tokens; existing call sites remain Compact by default.", | ||
| }, | ||
| }, | ||
| }, | ||
| argTypes: { | ||
| size: { | ||
| control: "select", | ||
| options: ["compact", "default"], | ||
| }, | ||
| }, | ||
| } satisfies Meta<typeof ConfidenceBadge>; | ||
|
|
||
| export default meta; | ||
| type Story = StoryObj<typeof meta>; | ||
|
|
||
| /** Low-confidence compact badge, matching the backward-compatible Figma compact state. */ | ||
| export const Low: Story = { args: { level: "low" } }; | ||
| /** Low-confidence default-size badge from the Figma level/size matrix. */ | ||
| export const LowDefault: Story = { args: { level: "low", size: "default" } }; | ||
| /** Medium-confidence compact badge from the Figma level/size matrix. */ | ||
| export const Medium: Story = { args: { level: "medium" } }; | ||
| /** Medium-confidence default-size badge from the Figma level/size matrix. */ | ||
| export const MediumDefault: Story = { args: { level: "medium", size: "default" } }; | ||
| /** High-confidence compact badge from the Figma level/size matrix. */ | ||
| export const High: Story = { args: { level: "high" } }; | ||
| /** High-confidence default-size badge from the Figma level/size matrix. */ | ||
| export const HighDefault: Story = { args: { level: "high", size: "default" } }; | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
95 changes: 95 additions & 0 deletions
95
apps/desktop/src/features/workspace/ConfidenceBadge.test.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,95 @@ | ||
| import { readFileSync } from "node:fs"; | ||
| import { resolve } from "node:path"; | ||
| import { render, screen } from "@testing-library/react"; | ||
| import { describe, expect, it, vi } from "vitest"; | ||
| import { ConfidenceBadge } from "./ConfidenceBadge"; | ||
|
|
||
| vi.mock("../../i18n", () => ({ | ||
| createTranslator: () => (key: string) => | ||
| ({ | ||
| confidenceLevelLow: "확신이 낮음", | ||
| confidenceLevelMedium: "귀로 한 번 더 확인", | ||
| confidenceLevelHigh: "믿고 가져가도 됨" | ||
| })[key] ?? key, | ||
| detectPreferredLocale: () => "ko" | ||
| })); | ||
|
|
||
| describe("ConfidenceBadge", () => { | ||
| it("keeps the pointer tooltip on the localized confidence contract", () => { | ||
| render(<ConfidenceBadge level="high" />); | ||
|
|
||
| const badge = screen.getByText("믿고 가져가도 됨"); | ||
| expect(badge).toHaveAttribute("title", "믿고 가져가도 됨"); | ||
| expect(badge).not.toHaveAttribute("title", "Confidence: high"); | ||
| }); | ||
|
|
||
| it("mirrors the Figma compact and default size variants without changing existing call sites", () => { | ||
| const { rerender } = render(<ConfidenceBadge level="low" />); | ||
|
|
||
| expect(screen.getByText("확신이 낮음")).toHaveClass( | ||
| "h-[var(--bandscope-confidence-compact-height)]" | ||
| ); | ||
|
|
||
| rerender(<ConfidenceBadge level="low" size="default" />); | ||
|
|
||
| expect(screen.getByText("확신이 낮음")).toHaveClass( | ||
| "h-[var(--bandscope-confidence-default-height)]" | ||
| ); | ||
| }); | ||
|
|
||
| it("matches the live Figma Caption/Status typography contract", () => { | ||
| render(<ConfidenceBadge level="low" />); | ||
|
|
||
| expect(screen.getByText("확신이 낮음")).toHaveClass( | ||
| "text-[11px]", | ||
| "font-medium", | ||
| "leading-[16px]", | ||
| "tracking-normal" | ||
| ); | ||
| }); | ||
|
|
||
| it("keeps confidence colors mapped to the live Figma 19:239 semantic status variables", () => { | ||
| const tokenSource = readFileSync( | ||
| resolve(process.cwd(), "src/styles/workspace-tokens.css"), | ||
| "utf8" | ||
| ).replace(/\s+/g, " "); | ||
|
|
||
| expect(tokenSource).toContain("--bandscope-status-danger: #fda4af;"); | ||
| expect(tokenSource).toContain("--bandscope-status-danger-bg: #fda4af14;"); | ||
| expect(tokenSource).toContain("--bandscope-status-danger-border: #fda4af4d;"); | ||
| expect(tokenSource).toContain("--bandscope-status-warning: #fcd34d;"); | ||
| expect(tokenSource).toContain("--bandscope-status-warning-bg: #fcd34d12;"); | ||
| expect(tokenSource).toContain("--bandscope-status-warning-border: #fcd34d33;"); | ||
| expect(tokenSource).toContain("--bandscope-status-success: #6ee7b7;"); | ||
| expect(tokenSource).toContain("--bandscope-status-success-bg: #6ee7b712;"); | ||
| expect(tokenSource).toContain("--bandscope-status-success-border: #6ee7b733;"); | ||
|
|
||
| expect(tokenSource).toContain( | ||
| "--bandscope-confidence-low-fg: var(--bandscope-status-danger);" | ||
| ); | ||
| expect(tokenSource).toContain( | ||
| "--bandscope-confidence-low-bg: var(--bandscope-status-danger-bg);" | ||
| ); | ||
| expect(tokenSource).toContain( | ||
| "--bandscope-confidence-low-border: var(--bandscope-status-danger-border);" | ||
| ); | ||
| expect(tokenSource).toContain( | ||
| "--bandscope-confidence-medium-fg: var(--bandscope-status-warning);" | ||
| ); | ||
| expect(tokenSource).toContain( | ||
| "--bandscope-confidence-medium-bg: var(--bandscope-status-warning-bg);" | ||
| ); | ||
| expect(tokenSource).toContain( | ||
| "--bandscope-confidence-medium-border: var(--bandscope-status-warning-border);" | ||
| ); | ||
| expect(tokenSource).toContain( | ||
| "--bandscope-confidence-high-fg: var(--bandscope-status-success);" | ||
| ); | ||
| expect(tokenSource).toContain( | ||
| "--bandscope-confidence-high-bg: var(--bandscope-status-success-bg);" | ||
| ); | ||
| expect(tokenSource).toContain( | ||
| "--bandscope-confidence-high-border: var(--bandscope-status-success-border);" | ||
| ); | ||
| }); | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
43 changes: 43 additions & 0 deletions
43
apps/desktop/src/features/workspace/OverlapWarningList.stories.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| import type { Meta, StoryObj } from "@storybook/react-vite"; | ||
| import { OverlapWarningList } from "./OverlapWarningList"; | ||
|
|
||
| const meta = { | ||
| title: "Workspace/OverlapWarningList", | ||
| component: OverlapWarningList, | ||
| parameters: { | ||
| layout: "padded", | ||
| docs: { | ||
| description: { | ||
| component: | ||
| "Shared clash list extracted from Section Roadmap and Ranges. Select the dark or light surface contract so the same next-player warning remains readable in both contexts.", | ||
| }, | ||
| }, | ||
| }, | ||
| } satisfies Meta<typeof OverlapWarningList>; | ||
|
|
||
| export default meta; | ||
| type Story = StoryObj<typeof meta>; | ||
|
|
||
| export const SharedClashes: Story = { | ||
| args: { | ||
| warnings: ["Bass and vocal share C3", "Keys cover the guitar hook"], | ||
| }, | ||
| }; | ||
|
|
||
| export const LightCard: Story = { | ||
| args: { | ||
| warnings: ["Bass and vocal share C3", "Keys cover the guitar hook"], | ||
| surface: "light", | ||
| }, | ||
| render: (args) => ( | ||
| <div style={{ background: "#fff", padding: "12px", maxWidth: "360px" }}> | ||
| <OverlapWarningList {...args} /> | ||
| </div> | ||
| ), | ||
| }; | ||
|
|
||
| export const NoClashes: Story = { | ||
| args: { | ||
| warnings: [], | ||
| }, | ||
| }; |
42 changes: 42 additions & 0 deletions
42
apps/desktop/src/features/workspace/OverlapWarningList.test.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| import { render, screen } from "@testing-library/react"; | ||
| import { describe, expect, it, vi } from "vitest"; | ||
| import { OverlapWarningList } from "./OverlapWarningList"; | ||
|
|
||
| describe("OverlapWarningList", () => { | ||
| it("renders nothing when there are no clashes", () => { | ||
| const { container } = render(<OverlapWarningList warnings={[]} />); | ||
| expect(container).toBeEmptyDOMElement(); | ||
| }); | ||
|
|
||
| it("lists each clash so the next player action is visible", () => { | ||
| render(<OverlapWarningList warnings={["Bass and vocal share C3", "Keys cover the guitar hook"]} />); | ||
| expect(screen.getByRole("list", { name: "Clash warning" })).toBeTruthy(); | ||
| expect(screen.getByText("Bass and vocal share C3")).toBeTruthy(); | ||
| expect(screen.getByText("Keys cover the guitar hook")).toBeTruthy(); | ||
| }); | ||
|
|
||
| it("uses dedicated readable tokens when rendered on a light card", () => { | ||
| render(<OverlapWarningList warnings={["Bass and vocal share C3"]} surface="light" />); | ||
|
|
||
| const warning = screen.getByText("Bass and vocal share C3").closest("li"); | ||
| expect(warning).not.toBeNull(); | ||
| expect(warning?.className).toContain("border-[color:var(--bandscope-overlap-light-border)]"); | ||
| expect(warning?.className).toContain("bg-[var(--bandscope-overlap-light-bg)]"); | ||
| expect(warning?.className).toContain("text-[color:var(--bandscope-overlap-light-fg)]"); | ||
| }); | ||
|
|
||
| it("keeps repeated clash evidence distinct without duplicate React keys", () => { | ||
| const consoleError = vi.spyOn(console, "error").mockImplementation(() => undefined); | ||
|
|
||
| try { | ||
| render(<OverlapWarningList warnings={["Bass and vocal share C3", "Bass and vocal share C3"]} />); | ||
|
|
||
| expect(screen.getAllByText("Bass and vocal share C3")).toHaveLength(2); | ||
| expect( | ||
| consoleError.mock.calls.some((call) => call.map(String).join(" ").includes("same key")), | ||
| ).toBe(false); | ||
| } finally { | ||
| consoleError.mockRestore(); | ||
| } | ||
| }); | ||
| }); |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.