Skip to content

Commit

Permalink
Make examples page mobile friendly
Browse files Browse the repository at this point in the history
  • Loading branch information
mhawryluk committed Sep 16, 2024
1 parent 71ad2af commit 928c02d
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 33 deletions.
8 changes: 8 additions & 0 deletions apps/typegpu-docs/src/assets/hamburger.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions apps/typegpu-docs/src/components/CodeEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,12 @@ export function CodeEditor(props: Props) {
value={code}
onChange={handleChange}
beforeMount={handleEditorWillMount}
options={{
minimap: {
enabled: false,
},
}}
className="py-16 md:py-0 bg-tameplum-50"
/>
);
}
38 changes: 20 additions & 18 deletions apps/typegpu-docs/src/components/ControlPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -162,27 +162,29 @@ export function ControlPanel() {
const exampleControlParams = useAtomValue(exampleControlsAtom);

return (
<div className="flex flex-col gap-4 p-6 bg-grayscale-0 rounded-xl">
<h2 className="text-xl font-medium">Control panel</h2>
<label className="flex items-center justify-between gap-3 text-sm cursor-pointer">
<span>Show left menu</span>
<Toggle
checked={menuShowing}
onChange={(e) => setMenuShowing(e.target.checked)}
/>
</label>
<label className="flex items-center justify-between gap-3 text-sm cursor-pointer">
<span>Show code editor</span>
<Toggle
checked={codeEditorShowing}
onChange={(e) => setCodeEditorShowing(e.target.checked)}
/>
</label>
<div className="flex flex-col gap-4 p-6 bg-grayscale-0 rounded-xl max-h-[50%] md:max-h-full">
<div className="hidden md:flex flex-col gap-4">
<h2 className="text-xl font-medium">Control panel</h2>
<label className="flex items-center justify-between gap-3 text-sm cursor-pointer">
<span>Show left menu</span>
<Toggle
checked={menuShowing}
onChange={(e) => setMenuShowing(e.target.checked)}
/>
</label>
<label className="flex items-center justify-between gap-3 text-sm cursor-pointer">
<span>Show code editor</span>
<Toggle
checked={codeEditorShowing}
onChange={(e) => setCodeEditorShowing(e.target.checked)}
/>
</label>

<hr />
<hr />
</div>

<h2 className="text-xl font-medium">Example controls</h2>
<div className="grid items-center grid-cols-2 gap-4">
<div className="grid items-center grid-cols-2 gap-4 overflow-auto p-1">
{exampleControlParams.map((param) => paramToControlRow(param))}
</div>
</div>
Expand Down
55 changes: 48 additions & 7 deletions apps/typegpu-docs/src/components/ExampleLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,67 @@
import { useAtomValue } from 'jotai';
import cs from 'classnames';
import { useAtom, useAtomValue } from 'jotai';
import DiscordIconSvg from '../assets/discord-icon.svg';
import GithubIconSvg from '../assets/github-icon.svg';
import { menuShownAtom } from '../utils/examples/menuShownAtom';
import HamburgerSvg from '../assets/hamburger.svg';
import { codeEditorShownMobileAtom } from '../utils/examples/codeEditorShownAtom';
import {
menuShownAtom,
menuShownMobileAtom,
} from '../utils/examples/menuShownAtom';
import ExampleList from './ExampleList';
import ExamplePage from './ExamplePage';

const isDev = import.meta.env.DEV;

export function ExampleLayout() {
const menuShown = useAtomValue(menuShownAtom);
const [menuShownMobile, setMenuShownMobile] = useAtom(menuShownMobileAtom);
const [codeShownMobile, setCodeShownMobile] = useAtom(
codeEditorShownMobileAtom,
);

return (
<div className="flex h-screen p-4 gap-4 bg-tameplum-50">
{menuShown ? <SideMenu /> : null}
<ExamplePage />
</div>
<>
<div className="md:hidden flex absolute top-4 left-4 z-50 gap-4 text-sm">
{menuShownMobile ? null : (
<button
className="bg-white rounded-[6.25rem] px-5 py-2.5 hover:bg-grayscale-20 border-grayscale-20 border-2"
type="button"
onClick={() => setMenuShownMobile(true)}
>
<img src={HamburgerSvg.src} alt="menu" className="h-6 w-6" />
</button>
)}

<button
type="button"
className="bg-white rounded-[6.25rem] text-sm px-5 py-2.5 hover:bg-grayscale-20 border-grayscale-20 border-2"
onClick={() => setCodeShownMobile(!codeShownMobile)}
>
{codeShownMobile ? 'Preview' : 'Code'}
</button>
</div>

<div className="flex h-screen p-4 gap-4 bg-tameplum-50">
{menuShown ? <SideMenu /> : null}
<ExamplePage />
</div>
</>
);
}

function SideMenu() {
const menuShownMobile = useAtomValue(menuShownMobileAtom);

return (
<aside className="flex flex-col bg-white rounded-2xl w-[18.75rem] p-5 gap-5">
<aside
className={cs(
menuShownMobile
? 'absolute inset-0 z-50 w-full md:static'
: 'hidden md:flex',
'flex flex-col bg-white md:rounded-2xl md:w-[18.75rem] p-5 gap-5',
)}
>
<header className="grid gap-5">
<div className="grid place-items-center">
<a href="/TypeGPU" className="block cursor-pointer">
Expand Down
5 changes: 4 additions & 1 deletion apps/typegpu-docs/src/components/ExampleLink.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import cs from 'classnames';
import { useAtom } from 'jotai';
import { useAtom, useSetAtom } from 'jotai';
import { RESET } from 'jotai/utils';
import type { MouseEvent } from 'react';
import SelectedDotSvg from '../assets/selected-dot.svg';
import { currentExampleAtom } from '../utils/examples/currentExampleAtom';
import { PLAYGROUND_KEY } from '../utils/examples/exampleContent';
import { menuShownMobileAtom } from '../utils/examples/menuShownAtom';
import useEvent from '../utils/useEvent';

type Props = {
Expand All @@ -16,10 +17,12 @@ export function ExampleLink(props: Props) {
const { exampleKey, children } = props;

const [currentExample, setCurrentExample] = useAtom(currentExampleAtom);
const setMenuShownMobile = useSetAtom(menuShownMobileAtom);

const handleClick = useEvent((e: MouseEvent) => {
e.preventDefault();
setCurrentExample(exampleKey ?? RESET);
setMenuShownMobile(false);
});

const active =
Expand Down
21 changes: 14 additions & 7 deletions apps/typegpu-docs/src/components/ExampleView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ import { useAtomValue, useSetAtom } from 'jotai';
import { compressToEncodedURIComponent } from 'lz-string';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { debounce } from 'remeda';
import { codeEditorShownAtom } from '../utils/examples/codeEditorShownAtom';
import {
codeEditorShownAtom,
codeEditorShownMobileAtom,
} from '../utils/examples/codeEditorShownAtom';
import { currentExampleAtom } from '../utils/examples/currentExampleAtom';
import { ExecutionCancelledError } from '../utils/examples/errors';
import { PLAYGROUND_KEY } from '../utils/examples/exampleContent';
Expand Down Expand Up @@ -88,6 +91,7 @@ export function ExampleView({ example, isPlayground = false }: Props) {
const [snackbarText, setSnackbarText] = useState<string | undefined>();
const setCurrentExample = useSetAtom(currentExampleAtom);
const codeEditorShowing = useAtomValue(codeEditorShownAtom);
const codeEditorMobileShowing = useAtomValue(codeEditorShownMobileAtom);

const setCodeWrapper = isPlayground
? useCallback(
Expand Down Expand Up @@ -120,17 +124,15 @@ export function ExampleView({ example, isPlayground = false }: Props) {
<>
{snackbarText ? <Snackbar text={snackbarText} /> : null}

<div className="grid gap-4 grid-cols-[1fr_18.75rem] h-full">
<div
className={cs('grid gap-4', codeEditorShowing ? 'grid-rows-2' : '')}
>
<div className="flex flex-col md:grid gap-4 md:grid-cols-[1fr_18.75rem] h-full">
<div className="flex-1 grid gap-4">
<div
style={{
scrollbarGutter: 'stable both-edges',
}}
className={cs(
'flex justify-evenly items-center flex-wrap overflow-auto h-full',
codeEditorShowing ? 'max-h-[calc(50vh-3rem)]' : '',
codeEditorShowing ? 'md:max-h-[calc(50vh-3rem)]' : '',
)}
>
{/* Note: This is a temporary measure to allow for simple examples that do not require the @typegpu/example-toolkit package. */}
Expand Down Expand Up @@ -187,7 +189,12 @@ export function ExampleView({ example, isPlayground = false }: Props) {
</div>

{codeEditorShowing ? (
<div className="relative h-full">
<div
className={cs(
codeEditorMobileShowing ? 'absolute z-20' : 'hidden md:block',
'md:relative h-full w-full',
)}
>
<div className="absolute inset-0">
<CodeEditor code={code} onCodeChange={handleCodeChange} />
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { atom } from 'jotai';

export const codeEditorShownAtom = atom(true);
export const codeEditorShownMobileAtom = atom(false);
1 change: 1 addition & 0 deletions apps/typegpu-docs/src/utils/examples/menuShownAtom.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { atom } from 'jotai';

export const menuShownAtom = atom(true);
export const menuShownMobileAtom = atom(false);

0 comments on commit 928c02d

Please sign in to comment.