fix(app): suppress review sidebar hydration motion (#36847)
This commit is contained in:
parent
59fe350972
commit
21f8184c58
6 changed files with 74 additions and 2 deletions
|
|
@ -9,7 +9,7 @@ import { createStore } from "solid-js/store"
|
|||
import { Persist, persisted } from "@/utils/persist"
|
||||
|
||||
export function createReviewPanelV2State() {
|
||||
const [store, setStore] = persisted(
|
||||
const [store, setStore, , ready] = persisted(
|
||||
Persist.global("review-panel-v2"),
|
||||
createStore({
|
||||
sidebarOpened: true,
|
||||
|
|
@ -24,6 +24,7 @@ export function createReviewPanelV2State() {
|
|||
return {
|
||||
sidebarOpened: () => store.sidebarOpened,
|
||||
sidebarWidth: () => store.sidebarWidth,
|
||||
sidebarTransition: ready,
|
||||
filter,
|
||||
setFilter,
|
||||
expandMode: () => store.expandMode,
|
||||
|
|
|
|||
|
|
@ -200,6 +200,7 @@ function ReviewPanelV2Sidebar(props: {
|
|||
return (
|
||||
<SessionReviewV2Sidebar
|
||||
open={props.state.sidebarOpened()}
|
||||
transition={props.state.sidebarTransition()}
|
||||
title={props.title}
|
||||
stats={<DiffChanges changes={props.diffs()} />}
|
||||
filter={props.state.filter()}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ const emptyFiles: string[] = []
|
|||
export type SessionFileBrowserState = {
|
||||
sidebarOpened: () => boolean
|
||||
sidebarWidth: () => number
|
||||
sidebarTransition: () => boolean
|
||||
resizeSidebar: (width: number) => void
|
||||
toggleSidebar: () => void
|
||||
}
|
||||
|
|
@ -96,6 +97,7 @@ export function SessionFileBrowserTab(props: {
|
|||
sidebar={
|
||||
<SessionReviewV2Sidebar
|
||||
open={sidebarOpened()}
|
||||
transition={props.state.sidebarTransition()}
|
||||
title={<span class="truncate">{title()}</span>}
|
||||
filter={filter()}
|
||||
onFilterChange={setFilter}
|
||||
|
|
|
|||
65
packages/app/test-browser/review-panel-v2-state.test.ts
Normal file
65
packages/app/test-browser/review-panel-v2-state.test.ts
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
import { beforeAll, expect, mock, test } from "bun:test"
|
||||
import type { AsyncStorage } from "@solid-primitives/storage"
|
||||
import { createEffect, createRoot } from "solid-js"
|
||||
|
||||
let createReviewPanelV2State: typeof import("@/pages/session/v2/review-panel-v2-state").createReviewPanelV2State
|
||||
let read: ((value: string | null) => void) | undefined
|
||||
|
||||
const storage: AsyncStorage = {
|
||||
getItem: () => new Promise((resolve) => (read = resolve)),
|
||||
setItem: async () => undefined,
|
||||
removeItem: async () => undefined,
|
||||
clear: async () => undefined,
|
||||
key: async () => null,
|
||||
getLength: async () => 0,
|
||||
length: Promise.resolve(0),
|
||||
}
|
||||
|
||||
beforeAll(async () => {
|
||||
mock.module("@opencode-ai/session-ui/v2/session-review-v2", () => ({
|
||||
SESSION_REVIEW_V2_SIDEBAR_WIDTH_DEFAULT: 240,
|
||||
SESSION_REVIEW_V2_SIDEBAR_WIDTH_MIN: 200,
|
||||
SESSION_REVIEW_V2_SIDEBAR_WIDTH_MAX: 480,
|
||||
}))
|
||||
mock.module("@/context/platform", () => ({
|
||||
usePlatform: () => ({ platform: "desktop", storage: () => storage }),
|
||||
}))
|
||||
|
||||
createReviewPanelV2State = (await import("@/pages/session/v2/review-panel-v2-state")).createReviewPanelV2State
|
||||
})
|
||||
|
||||
test("enables sidebar motion only after custom width hydration", async () => {
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
createRoot((dispose) => {
|
||||
const state = createReviewPanelV2State()
|
||||
const transition =
|
||||
"sidebarTransition" in state && typeof state.sidebarTransition === "function"
|
||||
? (state.sidebarTransition as () => boolean)
|
||||
: undefined
|
||||
|
||||
try {
|
||||
expect(transition).toBeFunction()
|
||||
expect(transition?.()).toBeFalse()
|
||||
expect(state.sidebarWidth()).toBe(240)
|
||||
} catch (error) {
|
||||
dispose()
|
||||
reject(error)
|
||||
return
|
||||
}
|
||||
|
||||
createEffect(() => {
|
||||
if (!transition?.()) return
|
||||
try {
|
||||
expect(state.sidebarWidth()).toBe(360)
|
||||
dispose()
|
||||
resolve()
|
||||
} catch (error) {
|
||||
dispose()
|
||||
reject(error)
|
||||
}
|
||||
})
|
||||
|
||||
read?.(JSON.stringify({ sidebarOpened: true, sidebarWidth: 360, expandMode: "collapse" }))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
@ -38,7 +38,8 @@
|
|||
border-right-width: 0;
|
||||
}
|
||||
|
||||
[data-component="session-review-v2-sidebar-root"] [data-slot="session-review-v2-sidebar"]:not([data-resizing]) {
|
||||
[data-component="session-review-v2-sidebar-root"]
|
||||
[data-slot="session-review-v2-sidebar"][data-transition]:not([data-resizing]) {
|
||||
transition:
|
||||
width 200ms cubic-bezier(0.22, 1, 0.36, 1),
|
||||
border-right-width 200ms cubic-bezier(0.22, 1, 0.36, 1);
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ export type SessionReviewV2Props = {
|
|||
|
||||
export type SessionReviewV2SidebarProps = {
|
||||
open: boolean
|
||||
transition: boolean
|
||||
title?: JSX.Element
|
||||
stats?: JSX.Element
|
||||
filter: string
|
||||
|
|
@ -76,6 +77,7 @@ export function SessionReviewV2Sidebar(props: SessionReviewV2SidebarProps) {
|
|||
<Show when={props.open}>
|
||||
<aside
|
||||
data-slot="session-review-v2-sidebar"
|
||||
data-transition={props.transition ? "" : undefined}
|
||||
data-resizing={resizing() ? "" : undefined}
|
||||
style={{ width: `${width()}px` }}
|
||||
>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue