From 316779080855ed9fb1a5e4043c56082ff470e9af Mon Sep 17 00:00:00 2001 From: Alex Sanders Date: Wed, 11 Dec 2024 09:46:55 +0000 Subject: [PATCH] make theme props more explicit --- libs/@guardian/react-crossword/package.json | 4 +- .../react-crossword/src/@types/crossword.ts | 48 +++++++++++----- .../src/components/AnagramHelper.tsx | 4 +- .../src/components/Cell.stories.tsx | 14 ++--- .../react-crossword/src/components/Cell.tsx | 28 +++++----- .../react-crossword/src/components/Clue.tsx | 4 +- .../src/components/Controls.tsx | 4 +- .../src/components/Crossword.stories.tsx | 22 ++++---- .../react-crossword/src/components/Grid.tsx | 56 +++++++++++-------- .../src/components/SolutionDisplay.tsx | 28 +++++----- .../src/components/WordWheel.tsx | 4 +- .../src/layouts/ScreenLayout.tsx | 14 ++--- libs/@guardian/react-crossword/src/theme.ts | 33 ++++++----- pnpm-lock.yaml | 3 - 14 files changed, 146 insertions(+), 120 deletions(-) diff --git a/libs/@guardian/react-crossword/package.json b/libs/@guardian/react-crossword/package.json index 84d629c01..fcdebe4b5 100644 --- a/libs/@guardian/react-crossword/package.json +++ b/libs/@guardian/react-crossword/package.json @@ -60,7 +60,6 @@ "@emotion/react": "^11.11.3", "@guardian/libs": "^19.1.0", "@guardian/source": "^8.0.0", - "@guardian/source-development-kitchen": "^13.1.0", "@types/react": "^18.2.79", "react": "^18.2.0", "typescript": "~5.5.2" @@ -78,8 +77,7 @@ "command": "rollup -c", "dependencies": [ "../libs:build", - "../source:build", - "../source-development-kitchen:build" + "../source:build" ], "files": [ "src/**", diff --git a/libs/@guardian/react-crossword/src/@types/crossword.ts b/libs/@guardian/react-crossword/src/@types/crossword.ts index a5fd198af..762f22bd4 100644 --- a/libs/@guardian/react-crossword/src/@types/crossword.ts +++ b/libs/@guardian/react-crossword/src/@types/crossword.ts @@ -47,23 +47,41 @@ export type Separators = Array<{ }>; export type Theme = { - background: string; - foreground: string; - anagramHelperBackground: string; - text: string; - provisionalText: string; - errorText: string; - gutter: number; - highlight: string; - focus: string; - active: string; - unsavedBackground: string; - cellSize: number; - buttonBackground: string; - buttonBackgroundHover: string; - border: string; + /** The background colour of 'black' squares/dividers etc on the grid */ + gridBackgroundColor: string; + /** The background colour of 'white' squares on the grid */ + gridForegroundColor: string; + /** The size of the gap between grid cells */ + gridGutterSize: number; + /** The length of one side of a cell on on the grid */ + gridCellSize: number; + + /** The main text colour (grid text, clues etc) */ + textColor: string; + /** The colour of the currently selected cell border */ + focusColor: string; + /** The colour of cells/clues that are currently selected clue */ + selectedColor: string; + /** The colour of cells/clues that are related to the currently selected clue */ + relatedColor: string; + + /** The background colour of clue-helper buttons */ + buttonBackgroundColor: string; + /** The hover colour of clue-helper buttons */ + buttonBackgroundHoverColor: string; + + /** Border colour used to visually separate parts of the UI */ + borderColor: string; + + /** The minimum width of a clue */ clueMinWidth: number; + /** The maximum width of a clue */ clueMaxWidth: number; + + /** The background colour of the anagram helper */ + anagramHelperBackgroundColor: string; + /** The text colour of shuffled letter that are not yet on the grid */ + anagramHelperCandidateTextColor: string; }; export type Dimensions = { diff --git a/libs/@guardian/react-crossword/src/components/AnagramHelper.tsx b/libs/@guardian/react-crossword/src/components/AnagramHelper.tsx index b3219595e..fec58d681 100644 --- a/libs/@guardian/react-crossword/src/components/AnagramHelper.tsx +++ b/libs/@guardian/react-crossword/src/components/AnagramHelper.tsx @@ -68,7 +68,7 @@ export const AnagramHelper = () => { left: 0; display: flex; flex-direction: column; - background-color: ${theme.anagramHelperBackground}; + background-color: ${theme.anagramHelperBackgroundColor}; padding: 10px; min-height: fit-content; z-index: 2; @@ -158,7 +158,7 @@ export const AnagramHelper = () => { css={css` width: 100%; margin: ${space[4]}px 0 ${space[4]}px; - border-top: 1px solid ${theme.background}; + border-top: 1px solid ${theme.gridBackgroundColor}; `} /> {entry && } diff --git a/libs/@guardian/react-crossword/src/components/Cell.stories.tsx b/libs/@guardian/react-crossword/src/components/Cell.stories.tsx index 79ca8f34c..5f0a78b2f 100644 --- a/libs/@guardian/react-crossword/src/components/Cell.stories.tsx +++ b/libs/@guardian/react-crossword/src/components/Cell.stories.tsx @@ -18,12 +18,12 @@ const meta: Meta = { return ( @@ -126,7 +126,7 @@ export const BigCellProgressWithNumber: Story = { parameters: { theme: { ...defaultTheme, - cellSize: 50, + gridCellSize: 50, }, }, }; @@ -143,7 +143,7 @@ export const HugeCellProgressWithNumber: Story = { parameters: { theme: { ...defaultTheme, - cellSize: 100, + gridCellSize: 100, }, }, }; diff --git a/libs/@guardian/react-crossword/src/components/Cell.tsx b/libs/@guardian/react-crossword/src/components/Cell.tsx index 43a11fc26..c2df41410 100644 --- a/libs/@guardian/react-crossword/src/components/Cell.tsx +++ b/libs/@guardian/react-crossword/src/components/Cell.tsx @@ -32,44 +32,44 @@ const CellComponent = ({ ? 'transparent' : isHighlighted ? isActive - ? theme.active - : theme.highlight - : theme.foreground; + ? theme.selectedColor + : theme.relatedColor + : theme.gridForegroundColor; return ( {data.number && ( {data.number} )} {guess} diff --git a/libs/@guardian/react-crossword/src/components/Clue.tsx b/libs/@guardian/react-crossword/src/components/Clue.tsx index b5f80d738..0558c1fa5 100644 --- a/libs/@guardian/react-crossword/src/components/Clue.tsx +++ b/libs/@guardian/react-crossword/src/components/Clue.tsx @@ -35,9 +35,9 @@ const ClueComponent = ({ aria-selected={isHighlighted} css={css` background-color: ${isActive - ? theme.active + ? theme.selectedColor : isHighlighted - ? theme.highlight + ? theme.relatedColor : 'transparent'}; cursor: ${isHighlighted ? 'default' : 'pointer'}; opacity: ${isComplete ? 0.5 : 1}; diff --git a/libs/@guardian/react-crossword/src/components/Controls.tsx b/libs/@guardian/react-crossword/src/components/Controls.tsx index 0c9fff98e..950738c12 100644 --- a/libs/@guardian/react-crossword/src/components/Controls.tsx +++ b/libs/@guardian/react-crossword/src/components/Controls.tsx @@ -32,8 +32,8 @@ const ClueControls = ({ currentEntryId }: { currentEntryId: EntryID }) => { const { updateCell } = useUpdateCell(); const crosswordButtonTheme: Partial = { - backgroundPrimary: theme.buttonBackground, - backgroundPrimaryHover: theme.buttonBackgroundHover, + backgroundPrimary: theme.buttonBackgroundColor, + backgroundPrimaryHover: theme.buttonBackgroundHoverColor, }; const revealEntry = useCallback(() => { diff --git a/libs/@guardian/react-crossword/src/components/Crossword.stories.tsx b/libs/@guardian/react-crossword/src/components/Crossword.stories.tsx index e7083b10f..268fe09b3 100644 --- a/libs/@guardian/react-crossword/src/components/Crossword.stories.tsx +++ b/libs/@guardian/react-crossword/src/components/Crossword.stories.tsx @@ -134,17 +134,17 @@ export const CustomisedLayout: StoryFn = () => { export const Themed: Story = { args: { - background: + gridBackgroundColor: 'linear-gradient(217deg, rgba(255,0,0,.8), rgba(255,0,0,0) 70.71%), linear-gradient(127deg, rgba(0,255,0,.8), rgba(0,255,0,0) 70.71%), linear-gradient(336deg, rgba(0,0,255,.8), rgba(0,0,255,0) 70.71%)', - foreground: 'blue', - text: 'limegreen', - gutter: 0, - highlight: 'yellow', - focus: 'black', - active: 'orange', - cellSize: 30, - buttonBackground: 'cyan', - buttonBackgroundHover: 'magenta', - border: 'lightpink', + gridForegroundColor: 'blue', + textColor: 'limegreen', + gridGutterSize: 0, + relatedColor: 'yellow', + focusColor: 'black', + selectedColor: 'orange', + gridCellSize: 30, + buttonBackgroundColor: 'cyan', + buttonBackgroundHoverColor: 'magenta', + borderColor: 'lightpink', }, }; diff --git a/libs/@guardian/react-crossword/src/components/Grid.tsx b/libs/@guardian/react-crossword/src/components/Grid.tsx index 3a30eb3ac..b786c1601 100644 --- a/libs/@guardian/react-crossword/src/components/Grid.tsx +++ b/libs/@guardian/react-crossword/src/components/Grid.tsx @@ -13,8 +13,10 @@ import { useUpdateCell } from '../hooks/useUpdateCell'; import { keyDownRegex } from '../utils/keydownRegex'; import { Cell } from './Cell'; -const getCellPosition = (index: number, { cellSize, gutter }: Theme) => - index * (cellSize + gutter) + gutter; +const getCellPosition = ( + index: number, + { gridCellSize, gridGutterSize }: Theme, +) => index * (gridCellSize + gridGutterSize) + gridGutterSize; const Separator = memo( ({ @@ -32,35 +34,35 @@ const Separator = memo( const x = getCellPosition(position.x, theme); const y = getCellPosition(position.y, theme); - const { cellSize, gutter } = theme; + const { gridCellSize, gridGutterSize } = theme; // if this is a 'down' entry, we'll rotate the separator 90 degrees // around the center of the cell const transform: Partial> = { - down: `rotate(90 ${x + cellSize / 2} ${y + cellSize / 2})`, + down: `rotate(90 ${x + gridCellSize / 2} ${y + gridCellSize / 2})`, }; return type === '-' ? ( // draws a dash (-) that bisects the border with the next cell ) : ( // draws a thicker border with the next cell @@ -77,11 +79,17 @@ const FocusIndicator = ({ return ( { }, [handleKeyDown, selectClickedCell]); const height = - theme.cellSize * dimensions.rows + theme.gutter * (dimensions.rows + 1); + theme.gridCellSize * dimensions.rows + + theme.gridGutterSize * (dimensions.rows + 1); const width = - theme.cellSize * dimensions.cols + theme.gutter * (dimensions.cols + 1); + theme.gridCellSize * dimensions.cols + + theme.gridGutterSize * (dimensions.cols + 1); return ( {cellWithProgress.separator === '-' && ( @@ -77,10 +77,10 @@ export const SolutionDisplayCell = ({ css={css` position: absolute; height: 2px; - top: ${theme.cellSize / 2 - 0.5}px; - left: ${theme.cellSize - 5}px; + top: ${theme.gridCellSize / 2 - 0.5}px; + left: ${theme.gridCellSize - 5}px; width: 7px; - background-color: ${theme.background}; + background-color: ${theme.gridBackgroundColor}; z-index: 1; `} > @@ -89,7 +89,7 @@ export const SolutionDisplayCell = ({
{ css={css` ${textSansBold17} `} - fill={theme.text} + fill={theme.textColor} > {centerLetter} )} - {renderOuterLetters({ letters: wordWheelLetters, fill: theme.text })} + {renderOuterLetters({ letters: wordWheelLetters, fill: theme.textColor })} ); }; diff --git a/libs/@guardian/react-crossword/src/layouts/ScreenLayout.tsx b/libs/@guardian/react-crossword/src/layouts/ScreenLayout.tsx index b53ae6ae3..c474c0def 100644 --- a/libs/@guardian/react-crossword/src/layouts/ScreenLayout.tsx +++ b/libs/@guardian/react-crossword/src/layouts/ScreenLayout.tsx @@ -15,8 +15,8 @@ const CluesHeader = memo(({ direction }: { direction: Direction }) => {
{ - const { text, clueMinWidth, clueMaxWidth } = useTheme(); + const { textColor, clueMinWidth, clueMaxWidth } = useTheme(); const { showAnagramHelper } = useUIState(); const theme = useTheme(); - const { gutter, cellSize } = useTheme(); + const { gridGutterSize, gridCellSize } = useTheme(); const { dimensions } = useData(); const gridWidth = Math.max( - (cellSize + gutter) * dimensions.cols + gutter, + (gridCellSize + gridGutterSize) * dimensions.cols + gridGutterSize, 300, ); const oneColWidth = gridWidth + clueMinWidth; @@ -51,7 +51,7 @@ const Layout = ({ return (
diff --git a/libs/@guardian/react-crossword/src/theme.ts b/libs/@guardian/react-crossword/src/theme.ts index 1528be6cf..4a203b36f 100644 --- a/libs/@guardian/react-crossword/src/theme.ts +++ b/libs/@guardian/react-crossword/src/theme.ts @@ -2,21 +2,24 @@ import { palette } from '@guardian/source/foundations'; import type { Theme } from './@types/crossword'; export const defaultTheme: Theme = { - background: palette.neutral[7], - text: palette.neutral[10], - errorText: 'red', - provisionalText: palette.neutral[60], - unsavedBackground: 'lightPink', - foreground: palette.neutral[100], - gutter: 1, - highlight: 'lightpink', - focus: 'lime', - active: 'deeppink', - cellSize: 32, - buttonBackground: 'hotpink', - buttonBackgroundHover: 'lightpink', - border: 'orchid', - anagramHelperBackground: 'floralwhite', + gridBackgroundColor: palette.neutral[7], + gridForegroundColor: palette.neutral[100], + gridGutterSize: 1, + gridCellSize: 32, + + textColor: palette.neutral[10], + focusColor: 'lime', + selectedColor: 'deeppink', + relatedColor: 'lightpink', + + buttonBackgroundColor: 'hotpink', + buttonBackgroundHoverColor: 'lightpink', + + borderColor: 'orchid', + clueMinWidth: 240, clueMaxWidth: 480, + + anagramHelperBackgroundColor: 'floralwhite', + anagramHelperCandidateTextColor: palette.neutral[60], }; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2c1ce62cc..a60de7727 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -507,9 +507,6 @@ importers: libs/@guardian/react-crossword: dependencies: - '@guardian/source-development-kitchen': - specifier: ^13.1.0 - version: link:../source-development-kitchen tslib: specifier: 2.6.2 version: 2.6.2