Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,8 @@
}

.logoRow {
/* Containing block for .fileInput — see there. */
position: relative;
flex: 1;
display: flex;
justify-content: flex-end;
Expand Down Expand Up @@ -436,8 +438,15 @@
}
}

/* Hidden picker, opened from the row's click. Pinned to .logoRow's origin:
without a positioned ancestor its static position (deep in the panel's
scrolled content) was measured against the viewport and escaped main's
overflow clip, so the document grew to ~930px and Safari let the whole
embed scroll off the top, leaving blank body below. */
.fileInput {
position: absolute;
top: 0;
left: 0;
width: 0;
height: 0;
opacity: 0;
Expand Down
6 changes: 3 additions & 3 deletions components/grid-cards-demo/src/data/design.ts
Original file line number Diff line number Diff line change
Expand Up @@ -347,10 +347,10 @@ export const initialDesign: CardDesign = {
orientation: 'landscape',
};

/** The starting design for a theme: the card is ink on dark, white on light,
* so it reads against the stage it first appears on. */
/** The starting design for a theme: the card is ink on light, white on dark,
* so it contrasts with the stage it first appears on. */
export function initialDesignFor(theme: 'light' | 'dark'): CardDesign {
return { ...initialDesign, color: theme === 'dark' ? DESIGN_SWATCHES[0].color : DESIGN_SWATCHES[1].color };
return { ...initialDesign, color: theme === 'dark' ? DESIGN_SWATCHES[1].color : DESIGN_SWATCHES[0].color };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Dark mode flashes black

On a dark-mode load, the card state still starts from the always-black initialDesign, while this change makes the dark-theme default white. The effect applies that white default only after the initial render, so the card can briefly appear black before switching to white. Initializing the state from the active theme, or applying the default before paint, would avoid this visible flash.

Prompt To Fix With AI
This is a comment left during a code review.
Path: components/grid-cards-demo/src/data/design.ts
Line: 353

Comment:
**Dark mode flashes black**

On a dark-mode load, the card state still starts from the always-black `initialDesign`, while this change makes the dark-theme default white. The effect applies that white default only after the initial render, so the card can briefly appear black before switching to white. Initializing the state from the active theme, or applying the default before paint, would avoid this visible flash.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@greptileai Fixed in ba8ea15: the theme→design sync is now a useLayoutEffect, so on a dark load the swap to the white default flushes before paint instead of in a passive effect after the first frame. A lazy useState initializer wouldn't help here — useThemeMode hydrates with the server snapshot (light) and flips to dark in the same commit, so the initializer would still see light.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the clarification. Verified in ba8ea15: using useLayoutEffect addresses the flash before paint, and the hydrated theme snapshot means a lazy initializer would not solve it. Resolving this comment.

}

/** Field-by-field equality of two designs (layouts and gradients by value). */
Expand Down
11 changes: 7 additions & 4 deletions components/grid-cards-demo/src/hooks/useCardsDemoLogic.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client';

import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
import type { ApiCall } from '@/data/flow';
import {
ACTIONS,
Expand Down Expand Up @@ -97,10 +97,13 @@ export function useCardsDemoLogic() {
const theme = useThemeMode();
const [design, setDesign] = useState<CardDesign>(initialDesign);
// Until the visitor designs something, the card is the theme's default:
// ink on dark, white on light, following the theme if it changes. Reset
// (a design equal to a theme's default) hands it back to the theme.
// ink on light, white on dark, following the theme if it changes. Reset
// (a design equal to a theme's default) hands it back to the theme. A
// layout effect, so the swap lands before paint: the theme hydrates as
// light and flips to dark in the same commit, and the card must not show
// a frame of the other stage's color first.
const designed = useRef(false);
useEffect(() => {
useLayoutEffect(() => {
if (!designed.current) setDesign(initialDesignFor(theme));
}, [theme]);
// The latest design, readable from callbacks without re-binding them.
Expand Down
Loading