Skip to content

Commit

Permalink
pass grid width to Layout component
Browse files Browse the repository at this point in the history
so that consumers can layout custom pages more easily
  • Loading branch information
sndrs committed Dec 12, 2024
1 parent 704ccd2 commit c0aca64
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 29 deletions.
1 change: 1 addition & 0 deletions libs/@guardian/react-crossword/src/@types/Layout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ export type LayoutProps = {
AnagramHelper: typeof AnagramHelper;
Clues: typeof Clues;
SavedMessage: ComponentType;
gridWidth: number;
};
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,16 @@ export const MultiplePlayersRow: StoryFn = () => {
};

export const CustomLayoutRaw: StoryFn = () => {
const Layout = ({ Clues, Grid, Controls, SavedMessage }: LayoutProps) => {
const Layout = ({
Clues,
Grid,
Controls,
SavedMessage,
gridWidth,
}: LayoutProps) => {
return (
<>
<p>gridWidth: {gridWidth}</p>
<Grid />
<Controls />
<SavedMessage />
Expand Down Expand Up @@ -103,13 +110,19 @@ export const CustomisedLayout: StoryFn = () => {
</h2>
);

const Layout = ({ Clues, Grid, Controls, SavedMessage }: LayoutProps) => {
const Layout = ({
Clues,
Grid,
Controls,
SavedMessage,
gridWidth,
}: LayoutProps) => {
return (
<div style={{ display: 'flex', alignItems: 'flex-start', gap: 20 }}>
<div style={{ flex: 1, minWidth: '15em' }}>
<Clues direction="across" Header={CluesHeader} />
</div>
<div style={{ flexBasis: 496, minWidth: '15em' }}>
<div style={{ flexBasis: gridWidth, minWidth: '15em' }}>
<Grid />
<Controls />
<div
Expand Down
23 changes: 19 additions & 4 deletions libs/@guardian/react-crossword/src/components/Crossword.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { css } from '@emotion/react';
import type { ComponentType, ReactNode } from 'react';
import { type ComponentType, type ReactNode, useMemo } from 'react';
import type { CAPICrossword } from '../@types/CAPI';
import type { Progress, Theme } from '../@types/crossword';
import type { LayoutProps } from '../@types/Layout';
import { ContextProvider } from '../context/ContextProvider';
import { useProgress } from '../context/Progress';
import { ScreenLayout } from '../layouts/ScreenLayout';
import { defaultTheme } from '../theme';
import { AnagramHelper } from './AnagramHelper';
import { Clues } from './Clues';
import { Controls } from './Controls';
Expand All @@ -30,7 +31,7 @@ const SavedMessage = () => {
);
};

const layoutProps: LayoutProps = {
const layoutComponents: Omit<LayoutProps, 'gridWidth'> = {
Grid,
Controls,
AnagramHelper,
Expand All @@ -47,9 +48,21 @@ export const Crossword = ({
}: CrosswordProps) => {
const LayoutComponent = Layout ?? ScreenLayout;

const theme = useMemo<Theme>(
() => ({ ...defaultTheme, ...userTheme }),
[userTheme],
);

const gridWidth = useMemo(
() =>
(theme.gridCellSize + theme.gridGutterSize) * data.dimensions.cols +
theme.gridGutterSize,
[theme.gridCellSize, theme.gridGutterSize, data.dimensions.cols],
);

return (
<ContextProvider
userTheme={userTheme}
theme={theme}
data={data}
userProgress={progress}
selectedEntryId={data.entries[0].id}
Expand All @@ -70,7 +83,9 @@ export const Crossword = ({
container-type: inline-size;
`}
>
{children ?? <LayoutComponent {...layoutProps} />}
{children ?? (
<LayoutComponent {...layoutComponents} gridWidth={gridWidth} />
)}
</div>
</ContextProvider>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,8 @@

import type { ReactNode } from 'react';
import type { CAPICrossword } from '../@types/CAPI';
import type { Progress } from '../@types/crossword';
import type { Progress, Theme } from '../@types/crossword';
import type { EntryID } from '../@types/Entry';
import type { CrosswordProps } from '../components/Crossword';
import { CurrentCellProvider } from './CurrentCell';
import { CurrentClueProvider } from './CurrentClue';
import { DataProvider } from './Data';
Expand All @@ -35,19 +34,19 @@ export const ContextProvider = ({
data,
selectedEntryId,
userProgress,
userTheme,
theme,
children,
}: {
data: CAPICrossword;
selectedEntryId?: EntryID;
userProgress?: Progress;
userTheme?: Partial<CrosswordProps>;
theme: Theme;
children: ReactNode;
}) => {
const { entries, dimensions, solutionAvailable, id } = data;

return (
<ThemeProvider theme={userTheme}>
<ThemeProvider theme={theme}>
<UIStateProvider>
<DataProvider
entries={entries}
Expand Down
12 changes: 3 additions & 9 deletions libs/@guardian/react-crossword/src/context/Theme.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,17 @@
import { createContext, type ReactNode, useContext, useMemo } from 'react';
import { createContext, type ReactNode, useContext } from 'react';
import type { Theme } from '../@types/crossword';
import { defaultTheme } from '../theme';

const ThemeContext = createContext<Theme | undefined>(undefined);

export const ThemeProvider = ({
theme,
children,
}: {
theme?: Partial<Theme>;
theme: Theme;
children: ReactNode;
}) => {
const finalTheme = useMemo<Theme>(
() => ({ ...defaultTheme, ...theme }),
[theme],
);

return (
<ThemeContext.Provider value={finalTheme}>{children}</ThemeContext.Provider>
<ThemeContext.Provider value={theme}>{children}</ThemeContext.Provider>
);
};

Expand Down
10 changes: 2 additions & 8 deletions libs/@guardian/react-crossword/src/layouts/ScreenLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { textSans12, textSans14 } from '@guardian/source/foundations';
import { memo } from 'react';
import type { Direction } from '../@types/Direction';
import type { LayoutProps } from '../@types/Layout';
import { useData } from '../context/Data';
import { useTheme } from '../context/Theme';
import { useUIState } from '../context/UI';

Expand Down Expand Up @@ -32,19 +31,14 @@ const Layout = ({
AnagramHelper,
Clues,
SavedMessage,
gridWidth: actualGridWidth,
}: LayoutProps) => {
const { textColor, clueMinWidth, clueMaxWidth } = useTheme();

const { showAnagramHelper } = useUIState();
const theme = useTheme();

const { gridGutterSize, gridCellSize } = useTheme();
const { dimensions } = useData();

const gridWidth = Math.max(
(gridCellSize + gridGutterSize) * dimensions.cols + gridGutterSize,
300,
);
const gridWidth = Math.max(actualGridWidth, 300);
const oneColWidth = gridWidth + clueMinWidth;
const twoColWidth = gridWidth + clueMinWidth * 2;

Expand Down

0 comments on commit c0aca64

Please sign in to comment.