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
19 changes: 19 additions & 0 deletions docs/development.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Development Notes

## Debug UI switch

The landing page hides all debug controls by default in production builds.

To turn them back on locally, set this env var before running Vite:

```bash
VITE_ENABLE_DEBUG_UI=true
```

Debug UI is also enabled automatically when `import.meta.env.DEV` is true (normal `vite` dev mode).

When debug UI is enabled, you get:
- the floating control launcher,
- the inline control dock and external control panel mount,
- the `/` keyboard shortcut for opening controls,
- quick navigation actions for Depth Lab and Typography Lab.
142 changes: 91 additions & 51 deletions src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -386,11 +386,15 @@ const HOW_EXAMPLE = {
prompt: 'why do we have a surplus?',
};

function readAppView() {
function readAppView(isDebugUIEnabled = true) {
if (typeof window === 'undefined') {
return APP_VIEWS.home;
}

if (!isDebugUIEnabled) {
return APP_VIEWS.home;
}

const view = new URLSearchParams(window.location.search).get('view');

switch (view) {
Expand Down Expand Up @@ -2788,13 +2792,15 @@ function DepthLabView({
{isControlPanelVisible ? 'Hide config panel' : 'Show config panel'}
</button>

<button
type="button"
className="eli5-button eli5-button--secondary eli5-depth--1"
onClick={onOpenTypographyLab}
>
Open Typography Lab
</button>
{onOpenTypographyLab ? (
<button
type="button"
className="eli5-button eli5-button--secondary eli5-depth--1"
onClick={onOpenTypographyLab}
>
Open Typography Lab
</button>
) : null}

<button
type="button"
Expand Down Expand Up @@ -3002,13 +3008,15 @@ function TypographyLabView({
</div>

<div className="eli5-depth-lab__topbar-actions">
<button
type="button"
className="eli5-button eli5-button--secondary eli5-depth--1"
onClick={onOpenDepthLab}
>
Open Depth Lab
</button>
{onOpenDepthLab ? (
<button
type="button"
className="eli5-button eli5-button--secondary eli5-depth--1"
onClick={onOpenDepthLab}
>
Open Depth Lab
</button>
) : null}

<button
type="button"
Expand Down Expand Up @@ -4069,11 +4077,12 @@ function ScrollScrubMedia({
}

export default function App() {
const isDebugUIEnabled = import.meta.env.DEV || import.meta.env.VITE_ENABLE_DEBUG_UI === 'true';
const heroStageRef = useRef(null);
const playfieldBoardRef = useRef(null);
const howSectionRef = useRef(null);
const controlPanelWindowRef = useRef(null);
const [appView, setAppView] = useState(() => readAppView());
const [appView, setAppView] = useState(() => readAppView(isDebugUIEnabled));
const [activeExampleSlug, setActiveExampleSlug] = useState(EXAMPLES[0]?.slug ?? '');
const [heroTitleSlot, setHeroTitleSlot] = useState(() =>
buildHeroTitleSlot(buildFallbackBoardRects().hero),
Expand Down Expand Up @@ -4305,17 +4314,34 @@ export default function App() {
});
}, [heroSavedLayout]);

useEffect(() => {
if (typeof document === 'undefined') {
return;
}

document.documentElement.dataset.debugUi = isDebugUIEnabled ? 'true' : 'false';
}, [isDebugUIEnabled]);

useEffect(() => {
if (isDebugUIEnabled || appView === APP_VIEWS.home) {
return;
}

writeAppView(APP_VIEWS.home);
setAppView(APP_VIEWS.home);
}, [appView, isDebugUIEnabled]);

useEffect(() => {
const handlePopState = () => {
setAppView(readAppView());
setAppView(readAppView(isDebugUIEnabled));
};

window.addEventListener('popstate', handlePopState);

return () => {
window.removeEventListener('popstate', handlePopState);
};
}, []);
}, [isDebugUIEnabled]);

useEffect(() => {
if (appView === APP_VIEWS.home) {
Expand Down Expand Up @@ -4419,6 +4445,10 @@ export default function App() {
});

const openExternalControlPanel = useEffectEvent(() => {
if (!isDebugUIEnabled) {
return;
}

if (appView === APP_VIEWS.depthLab) {
setIsInlineFallbackOpen(true);
return;
Expand Down Expand Up @@ -4456,6 +4486,10 @@ export default function App() {
});

const toggleControlPanelVisibility = useEffectEvent(() => {
if (!isDebugUIEnabled) {
return;
}

if (appView === APP_VIEWS.depthLab) {
setIsInlineFallbackOpen((current) => !current);
return;
Expand Down Expand Up @@ -4501,6 +4535,10 @@ export default function App() {
}, []);

useEffect(() => {
if (!isDebugUIEnabled) {
return undefined;
}

const handleKeyDown = (event) => {
if (event.defaultPrevented || event.metaKey || event.ctrlKey || event.altKey) {
return;
Expand All @@ -4523,7 +4561,7 @@ export default function App() {
return () => {
window.removeEventListener('keydown', handleKeyDown);
};
}, [appView, toggleControlPanelVisibility]);
}, [appView, isDebugUIEnabled, toggleControlPanelVisibility]);

const activeExample =
EXAMPLES.find((example) => example.slug === activeExampleSlug) ?? EXAMPLES[0];
Expand Down Expand Up @@ -4558,7 +4596,7 @@ export default function App() {
<DepthLabView
isControlPanelVisible={isInlineFallbackOpen}
onToggleControlPanel={toggleControlPanelVisibility}
onOpenTypographyLab={() => handleSetAppView(APP_VIEWS.typographyLab)}
onOpenTypographyLab={isDebugUIEnabled ? () => handleSetAppView(APP_VIEWS.typographyLab) : undefined}
panelSurface={<ControlPanelSurface {...sharedPanelProps} />}
onReturnHome={() => handleSetAppView(APP_VIEWS.home)}
/>
Expand All @@ -4568,7 +4606,7 @@ export default function App() {
if (isTypographyLabView) {
return (
<TypographyLabView
onOpenDepthLab={() => handleSetAppView(APP_VIEWS.depthLab)}
onOpenDepthLab={isDebugUIEnabled ? () => handleSetAppView(APP_VIEWS.depthLab) : undefined}
onReturnHome={() => handleSetAppView(APP_VIEWS.home)}
/>
);
Expand Down Expand Up @@ -5143,39 +5181,41 @@ export default function App() {
</div>
</div>
</main>
<div
className={getLoadItemClass(
'eli5-control-launcher',
hasEnteredLoadCue(LOAD_CUES.controls),
'eli5-load-item--floating-ui',
)}
>
<button
type="button"
className="eli5-control-launcher__button eli5-depth--2"
onClick={toggleControlPanelVisibility}
{isDebugUIEnabled ? (
<div
className={getLoadItemClass(
'eli5-control-launcher',
hasEnteredLoadCue(LOAD_CUES.controls),
'eli5-load-item--floating-ui',
)}
>
{isControlPanelVisible ? 'Hide Control Panel (/)' : 'Show Control Panel (/)'}
</button>
<button
type="button"
className="eli5-control-launcher__button eli5-depth--2"
onClick={toggleControlPanelVisibility}
>
{isControlPanelVisible ? 'Hide Control Panel (/)' : 'Show Control Panel (/)'}
</button>

<button
type="button"
className="eli5-control-launcher__button eli5-depth--2 eli5-control-launcher__button--secondary"
onClick={() => handleSetAppView(APP_VIEWS.depthLab)}
>
Open Depth Lab
</button>
<button
type="button"
className="eli5-control-launcher__button eli5-depth--2 eli5-control-launcher__button--secondary"
onClick={() => handleSetAppView(APP_VIEWS.depthLab)}
>
Open Depth Lab
</button>

<button
type="button"
className="eli5-control-launcher__button eli5-depth--2 eli5-control-launcher__button--secondary"
onClick={() => handleSetAppView(APP_VIEWS.typographyLab)}
>
Open Typography Lab
</button>
</div>
<button
type="button"
className="eli5-control-launcher__button eli5-depth--2 eli5-control-launcher__button--secondary"
onClick={() => handleSetAppView(APP_VIEWS.typographyLab)}
>
Open Typography Lab
</button>
</div>
) : null}

{isInlineFallbackOpen ? (
{isDebugUIEnabled && isInlineFallbackOpen ? (
<div
className={getLoadItemClass(
'eli5-control-dock',
Expand All @@ -5194,7 +5234,7 @@ export default function App() {
</div>
) : null}

{controlPanelHost
{isDebugUIEnabled && controlPanelHost
? createPortal(
<ControlPanelSurface
{...sharedPanelProps}
Expand Down
8 changes: 8 additions & 0 deletions src/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -250,13 +250,21 @@ select {
}

.eli5-control-launcher {
display: none;
}

html[data-debug-ui='true'] .eli5-control-launcher {
display: grid;
justify-items: end;
gap: 10px;
width: min(250px, calc(100vw - 24px));
}

.eli5-control-dock {
display: none;
}

html[data-debug-ui='true'] .eli5-control-dock {
width: min(390px, calc(100vw - 24px));
Comment on lines +264 to 268
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Re-enable control dock when debug UI is active

This change hides .eli5-control-dock by default, but the debug override only restores width and never restores display, so the inline dock remains invisible even when debug UI is enabled. In practice, that breaks the fallback path where controls should appear in-page (for example when the popup window cannot open), leaving debug controls inaccessible in dev/debug sessions.

Useful? React with 👍 / 👎.

}

Expand Down