feat(ui): add ParamPiecePicker component
This commit is contained in:
parent
d4931a50ee
commit
90942bc4a6
2 changed files with 74 additions and 0 deletions
39
packages/chess/src/ui/ParamPiecePicker.test.tsx
Normal file
39
packages/chess/src/ui/ParamPiecePicker.test.tsx
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { renderToStaticMarkup } from 'react-dom/server';
|
||||||
|
import { describe, it, expect, vi } from 'vitest';
|
||||||
|
import { ParamPiecePicker } from './ParamPiecePicker';
|
||||||
|
|
||||||
|
describe('ParamPiecePicker', () => {
|
||||||
|
const pieces = [
|
||||||
|
{ id: 1, type: 'queen', color: 'white' as const, square: 28 }, // e4
|
||||||
|
{ id: 2, type: 'knight', color: 'black' as const, square: 62 }, // g8
|
||||||
|
];
|
||||||
|
|
||||||
|
it('renders dropdown listing pieces with color, type and square name', () => {
|
||||||
|
const html = renderToStaticMarkup(
|
||||||
|
<ParamPiecePicker
|
||||||
|
value={1}
|
||||||
|
onChange={() => {}}
|
||||||
|
pieces={pieces}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(html).toContain('white queen at e4');
|
||||||
|
expect(html).toContain('black knight at g8');
|
||||||
|
expect(html).toContain('value="1"');
|
||||||
|
expect(html).toContain('value="2"');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('calls onChange with entityId when selecting an option', () => {
|
||||||
|
// Testing React component events without testing-library:
|
||||||
|
// We instantiate the component directly and call its props.onChange to verify the type
|
||||||
|
const onChange = vi.fn();
|
||||||
|
const component = ParamPiecePicker({ value: 1, onChange, pieces });
|
||||||
|
|
||||||
|
// Trigger the onChange handler passed to the select element
|
||||||
|
component.props.onChange({ target: { value: '2' } } as unknown as React.ChangeEvent<HTMLSelectElement>);
|
||||||
|
|
||||||
|
expect(onChange).toHaveBeenCalledTimes(1);
|
||||||
|
expect(onChange).toHaveBeenCalledWith(2);
|
||||||
|
});
|
||||||
|
});
|
||||||
35
packages/chess/src/ui/ParamPiecePicker.tsx
Normal file
35
packages/chess/src/ui/ParamPiecePicker.tsx
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { squareToAlgebraic } from '../coord';
|
||||||
|
|
||||||
|
export interface ParamPiecePickerProps {
|
||||||
|
value: number | undefined;
|
||||||
|
onChange: (entityId: number) => void;
|
||||||
|
pieces: readonly {
|
||||||
|
id: number;
|
||||||
|
type: string;
|
||||||
|
color: "white" | "black";
|
||||||
|
square: number;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ParamPiecePicker({ value, onChange, pieces }: ParamPiecePickerProps) {
|
||||||
|
return (
|
||||||
|
<select
|
||||||
|
value={value ?? ''}
|
||||||
|
onChange={(e) => {
|
||||||
|
const val = e.target.value;
|
||||||
|
if (val) {
|
||||||
|
onChange(Number(val));
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
className="p-1 text-sm bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded"
|
||||||
|
>
|
||||||
|
<option value="" disabled>Select a piece</option>
|
||||||
|
{pieces.map((p) => (
|
||||||
|
<option key={p.id} value={p.id}>
|
||||||
|
{p.color} {p.type} at {squareToAlgebraic(p.square)}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
);
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue