Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crossword inputs in all cells not just the current one #1891

Open
wants to merge 6 commits into
base: sndrs/grid-a11y
Choose a base branch
from
Open
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
16 changes: 9 additions & 7 deletions libs/@guardian/react-crossword/src/components/Cell.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { Meta, StoryObj } from '@storybook/react';
import type { Theme } from '../@types/crossword';
import { ThemeProvider, useTheme } from '../context/Theme';
import { defaultTheme } from '../theme';
import type { CellProps } from './Cell';
import type { BaseCellProps } from './Cell';
import { Cell } from './Cell';

const meta: Meta<typeof Cell> = {
Expand Down Expand Up @@ -39,28 +39,30 @@ const meta: Meta<typeof Cell> = {
],
};

const args: CellProps = {
const args: BaseCellProps = {
x: 0,
y: 0,
data: {
x: 0,
y: 0,
group: ['1-across'],
},
isBlackCell: false,
};

export default meta;
type Story = StoryObj<typeof Cell>;

export const Default: Story = { args };
export const Default: Story = {
args: {
...args,
},
};

export const Black: Story = {
args: {
...args,
data: {
...args.data,
group: undefined,
},
isBlackCell: true,
},
};

Expand Down
188 changes: 93 additions & 95 deletions libs/@guardian/react-crossword/src/components/Cell.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { css } from '@emotion/react';
import { textSans12 } from '@guardian/source/foundations';
import { forwardRef, memo } from 'react';
import type { SVGProps } from 'react';
import { memo } from 'react';
import type { Cell as CellType } from '../@types/crossword';
import { useTheme } from '../context/Theme';

export type CellProps = {
export type BaseCellProps = {
data: CellType;
x: number;
y: number;
Expand All @@ -14,102 +15,99 @@ export type CellProps = {
isConnected?: boolean;
/** is the cell for the selected clue? */
isSelected?: boolean;
} & React.SVGProps<SVGGElement>;
};

const CellComponent = forwardRef<SVGGElement, CellProps>(
(
{
data,
x,
y,
guess = '',
isBlackCell,
isConnected,
isSelected,
children,
...props
},
ref,
) => {
const theme = useTheme();
export type CellProps = BaseCellProps & SVGProps<SVGGElement>;

const backgroundColor = isBlackCell
? 'transparent'
: isConnected
? isSelected
? theme.selectedColor
: theme.connectedColor
: theme.gridForegroundColor;
const CellComponent = ({
data,
x,
y,
guess = '',
isBlackCell,
isConnected,
isSelected,
children,
...props
}: CellProps) => {
const theme = useTheme();

return (
<g {...props} ref={ref}>
<rect
x={x}
y={y}
width={theme.gridCellSize}
height={theme.gridCellSize}
fill={backgroundColor}
aria-hidden="true"
role="presentation"
/>
{!isBlackCell && (
<>
{data.number && (
<text
x={x}
y={y}
dx={Math.max(1, theme.gridCellSize * 0.05)}
dy={Math.max(9, theme.gridCellSize * 0.22)}
fill={theme.textColor}
css={css`
${textSans12};
font-size: ${Math.max(
9,
Math.round(theme.gridCellSize * 0.2),
)}px;
`}
aria-hidden="true"
role="presentation"
>
{data.number}
</text>
)}
const backgroundColor = isBlackCell
? 'transparent'
: isConnected
? isSelected
? theme.selectedColor
: theme.connectedColor
: theme.gridForegroundColor;

{children ? (
<foreignObject
x={x}
y={y}
width={theme.gridCellSize}
height={theme.gridCellSize}
css={css`
position: relative;
`}
>
{children}
</foreignObject>
) : (
<text
x={x + theme.gridCellSize / 2}
y={y + theme.gridCellSize / 2}
dy={theme.gridCellSize * 0.07}
textAnchor="middle"
dominantBaseline="middle"
fill={theme.textColor}
css={css`
${textSans12};
font-size: ${theme.gridCellSize * 0.6}px;
`}
aria-hidden="true"
role="presentation"
>
{guess}
</text>
)}
</>
)}
</g>
);
},
);
return (
<g {...props}>
<rect
x={x}
y={y}
width={theme.gridCellSize}
height={theme.gridCellSize}
fill={backgroundColor}
aria-hidden="true"
role="presentation"
/>
{!isBlackCell && (
<>
{data.number && (
<text
x={x}
y={y}
dx={Math.max(1, theme.gridCellSize * 0.05)}
dy={Math.max(9, theme.gridCellSize * 0.22)}
fill={theme.textColor}
css={css`
${textSans12};
font-size: ${Math.max(
9,
Math.round(theme.gridCellSize * 0.2),
)}px;
`}
aria-hidden="true"
role="presentation"
>
{data.number}
</text>
)}

{children ? (
<foreignObject
x={x}
y={y}
width={theme.gridCellSize}
height={theme.gridCellSize}
css={css`
position: relative;
`}
>
{children}
</foreignObject>
) : (
<text
x={x + theme.gridCellSize / 2}
y={y + theme.gridCellSize / 2}
dy={theme.gridCellSize * 0.07}
textAnchor="middle"
dominantBaseline="middle"
fill={theme.textColor}
css={css`
${textSans12};
font-size: ${theme.gridCellSize * 0.6}px;
`}
aria-hidden="true"
role="presentation"
>
{guess}
</text>
)}
</>
)}
</g>
);
};

export const Cell = memo(CellComponent);
10 changes: 7 additions & 3 deletions libs/@guardian/react-crossword/src/components/Clues.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,13 @@ export const Clues = ({ direction, Header }: Props) => {
const selectClue = useCallback(
(entry: CAPIEntry) => {
setCurrentEntryId(entry.id);
setCurrentCell(
cells.getByCoords({ x: entry.position.x, y: entry.position.y }),
);
const newCell = cells.getByCoords({
x: entry.position.x,
y: entry.position.y,
});
if (newCell) {
setCurrentCell(newCell);
}
},
[cells, setCurrentCell, setCurrentEntryId],
);
Expand Down
Loading
Loading