@ankhorage/zora 25.11.0 → 26.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +1 -4
- package/dist/capabilities/index.js +65 -41
- package/dist/capabilities/index.js.map +3 -3
- package/dist/features/chess/adapters/inbound/ChessBoard.d.ts +1 -1
- package/dist/features/chess/adapters/inbound/ChessBoard.d.ts.map +1 -1
- package/dist/features/chess/adapters/inbound/ChessBoard.js +130 -83
- package/dist/features/chess/adapters/inbound/ChessBoard.js.map +1 -1
- package/dist/features/chess/meta.d.ts +97 -72
- package/dist/features/chess/meta.d.ts.map +1 -1
- package/dist/features/chess/meta.js +64 -40
- package/dist/features/chess/meta.js.map +1 -1
- package/dist/features/chess/public.d.ts +1 -7
- package/dist/features/chess/public.d.ts.map +1 -1
- package/dist/features/chess/public.js +0 -6
- package/dist/features/chess/public.js.map +1 -1
- package/dist/features/chess/utils/createChessBoardCellPressHandler.d.ts +6 -0
- package/dist/features/chess/utils/createChessBoardCellPressHandler.d.ts.map +1 -0
- package/dist/features/chess/utils/createChessBoardCellPressHandler.js +17 -0
- package/dist/features/chess/utils/createChessBoardCellPressHandler.js.map +1 -0
- package/dist/features/chess/utils/createChessBoardCells.d.ts +12 -0
- package/dist/features/chess/utils/createChessBoardCells.d.ts.map +1 -0
- package/dist/features/chess/utils/createChessBoardCells.js +28 -0
- package/dist/features/chess/utils/createChessBoardCells.js.map +1 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphController.d.ts +2 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphController.d.ts.map +1 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphController.js +68 -4
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphController.js.map +1 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphResizeObserver.d.ts +3 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphResizeObserver.d.ts.map +1 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphResizeObserver.js +41 -8
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphResizeObserver.js.map +1 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphRuntime.d.ts.map +1 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphRuntime.js +6 -2
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphRuntime.js.map +1 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/shouldFitGraphAfterLayout.d.ts +2 -2
- package/dist/features/graph-view/adapters/inbound/web-artifact/shouldFitGraphAfterLayout.d.ts.map +1 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/shouldFitGraphAfterLayout.js +3 -3
- package/dist/features/graph-view/adapters/inbound/web-artifact/shouldFitGraphAfterLayout.js.map +1 -1
- package/dist/readerFree.d.ts +2 -2
- package/dist/readerFree.d.ts.map +1 -1
- package/dist/readerFree.js +1 -1
- package/dist/readerFree.js.map +1 -1
- package/dist/types/authoring.d.ts +2 -1
- package/dist/types/authoring.d.ts.map +1 -1
- package/dist/types/authoring.js.map +1 -1
- package/dist/types/chess.d.ts +27 -20
- package/dist/types/chess.d.ts.map +1 -1
- package/dist/types/chess.js.map +1 -1
- package/package.json +31 -92
- package/src/features/chess/adapters/inbound/ChessBoard.tsx +263 -112
- package/src/features/chess/meta.ts +64 -40
- package/src/features/chess/public.test.tsx +77 -228
- package/src/features/chess/public.ts +2 -9
- package/src/features/chess/utils/createChessBoardCellPressHandler.ts +30 -0
- package/src/features/chess/utils/createChessBoardCells.ts +54 -0
- package/src/features/chessTabletopOwnership.test.ts +3 -7
- package/src/features/graph-view/adapters/inbound/web-artifact/createGraphController.test.ts +145 -1
- package/src/features/graph-view/adapters/inbound/web-artifact/createGraphController.ts +86 -5
- package/src/features/graph-view/adapters/inbound/web-artifact/createGraphResizeObserver.test.ts +163 -6
- package/src/features/graph-view/adapters/inbound/web-artifact/createGraphResizeObserver.ts +57 -8
- package/src/features/graph-view/adapters/inbound/web-artifact/createGraphRuntime.test.ts +42 -0
- package/src/features/graph-view/adapters/inbound/web-artifact/createGraphRuntime.ts +7 -1
- package/src/features/graph-view/adapters/inbound/web-artifact/shouldFitGraphAfterLayout.test.ts +7 -3
- package/src/features/graph-view/adapters/inbound/web-artifact/shouldFitGraphAfterLayout.ts +7 -3
- package/src/features/registry/componentMeta.test.ts +12 -1
- package/src/readerFree.ts +3 -15
- package/src/types/authoring.ts +2 -1
- package/src/types/chess.ts +28 -21
- package/web-dist/chunks/Accordion-91sjb3zh.js +453 -0
- package/web-dist/components/chess-board/ChessBoard.js +2 -1
- package/web-dist/components/graph-view/GraphView.js +107 -17
- package/web-dist/components/opening-book/OpeningBook.js +2 -1
- package/web-dist/manifest.json +8 -4
- package/dist/features/chess/utils/chessEngine.d.ts +0 -8
- package/dist/features/chess/utils/chessEngine.d.ts.map +0 -1
- package/dist/features/chess/utils/chessEngine.js +0 -71
- package/dist/features/chess/utils/chessEngine.js.map +0 -1
- package/dist/features/chess/utils/chessSquares.d.ts +0 -4
- package/dist/features/chess/utils/chessSquares.d.ts.map +0 -1
- package/dist/features/chess/utils/chessSquares.js +0 -3
- package/dist/features/chess/utils/chessSquares.js.map +0 -1
- package/dist/features/chess/utils/createBoardSquares.d.ts +0 -4
- package/dist/features/chess/utils/createBoardSquares.d.ts.map +0 -1
- package/dist/features/chess/utils/createBoardSquares.js +0 -9
- package/dist/features/chess/utils/createBoardSquares.js.map +0 -1
- package/dist/features/chess/utils/getSquareFile.d.ts +0 -4
- package/dist/features/chess/utils/getSquareFile.d.ts.map +0 -1
- package/dist/features/chess/utils/getSquareFile.js +0 -5
- package/dist/features/chess/utils/getSquareFile.js.map +0 -1
- package/dist/features/chess/utils/getSquareRank.d.ts +0 -4
- package/dist/features/chess/utils/getSquareRank.d.ts.map +0 -1
- package/dist/features/chess/utils/getSquareRank.js +0 -5
- package/dist/features/chess/utils/getSquareRank.js.map +0 -1
- package/dist/features/chess/utils/isLightSquare.d.ts +0 -4
- package/dist/features/chess/utils/isLightSquare.d.ts.map +0 -1
- package/dist/features/chess/utils/isLightSquare.js +0 -6
- package/dist/features/chess/utils/isLightSquare.js.map +0 -1
- package/src/features/chess/utils/chessEngine.test.ts +0 -35
- package/src/features/chess/utils/chessEngine.ts +0 -83
- package/src/features/chess/utils/chessSquares.ts +0 -6
- package/src/features/chess/utils/createBoardSquares.ts +0 -13
- package/src/features/chess/utils/getSquareFile.ts +0 -6
- package/src/features/chess/utils/getSquareRank.ts +0 -6
- package/src/features/chess/utils/isLightSquare.ts +0 -8
- package/web-dist/chunks/Accordion-xcm1qc39.js +0 -3813
package/src/types/chess.ts
CHANGED
|
@@ -4,33 +4,36 @@ import type { ZoraBaseProps } from './base';
|
|
|
4
4
|
|
|
5
5
|
export type ChessBoardOrientation = 'white' | 'black';
|
|
6
6
|
export type ChessPieceCode = string;
|
|
7
|
-
export type ChessSquareId =
|
|
8
|
-
`${'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h'}${1 | 2 | 3 | 4 | 5 | 6 | 7 | 8}`;
|
|
9
|
-
export type ChessPromotionPiece = 'q' | 'r' | 'b' | 'n';
|
|
10
7
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
readonly
|
|
14
|
-
readonly
|
|
8
|
+
/** A caller-owned cell location in a rectangular chess presentation board. */
|
|
9
|
+
export interface ChessBoardCell {
|
|
10
|
+
readonly column: number;
|
|
11
|
+
readonly row: number;
|
|
15
12
|
}
|
|
16
13
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
readonly
|
|
20
|
-
readonly
|
|
21
|
-
|
|
14
|
+
/** The bounded presentation dimensions supported by ChessBoard. */
|
|
15
|
+
export interface ChessBoardDimensions {
|
|
16
|
+
readonly columns: number;
|
|
17
|
+
readonly rows: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface ChessMoveAttempt {
|
|
21
|
+
readonly from: ChessBoardCell;
|
|
22
|
+
readonly to: ChessBoardCell;
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
export interface ChessPieceState {
|
|
25
26
|
readonly color: 'black' | 'white';
|
|
26
27
|
readonly piece: ChessPieceCode;
|
|
27
|
-
readonly
|
|
28
|
+
readonly cell: ChessBoardCell;
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
export interface ChessPieceRenderContext {
|
|
31
32
|
readonly color: string;
|
|
32
33
|
readonly piece: ChessPieceCode;
|
|
33
|
-
readonly
|
|
34
|
+
readonly cell: ChessBoardCell;
|
|
35
|
+
/** Available cell edge length in pixels. */
|
|
36
|
+
readonly size: number;
|
|
34
37
|
}
|
|
35
38
|
|
|
36
39
|
export type ChessPieceRenderer = (context: ChessPieceRenderContext) => React.ReactNode;
|
|
@@ -65,20 +68,24 @@ export interface OpeningBookColorScheme {
|
|
|
65
68
|
export type OpeningBookColorOverrides = Partial<OpeningBookColorScheme>;
|
|
66
69
|
|
|
67
70
|
export interface ChessBoardProps extends ZoraBaseProps {
|
|
68
|
-
|
|
71
|
+
/** Number of displayed columns, from 2 through 24. */
|
|
72
|
+
readonly columns?: number;
|
|
73
|
+
/** Number of displayed rows, from 2 through 24. */
|
|
74
|
+
readonly rows?: number;
|
|
69
75
|
readonly pieces?: readonly ChessPieceState[];
|
|
70
76
|
readonly orientation?: ChessBoardOrientation;
|
|
71
|
-
readonly
|
|
72
|
-
readonly legalTargets?: readonly
|
|
77
|
+
readonly selectedCell?: ChessBoardCell | null;
|
|
78
|
+
readonly legalTargets?: readonly ChessBoardCell[];
|
|
73
79
|
readonly lastMove?: ChessMoveAttempt | null;
|
|
74
80
|
readonly disabled?: boolean;
|
|
75
81
|
readonly showCoordinates?: boolean;
|
|
76
|
-
|
|
82
|
+
/** Enables explicit editor resize controls when a dimensions callback is supplied. */
|
|
83
|
+
readonly resizable?: boolean;
|
|
77
84
|
readonly colorScheme?: ChessBoardColorOverrides;
|
|
78
|
-
readonly
|
|
85
|
+
readonly onCellPress?: (cell: ChessBoardCell) => void;
|
|
79
86
|
readonly onMoveAttempt?: (move: ChessMoveAttempt) => void;
|
|
80
|
-
|
|
81
|
-
readonly
|
|
87
|
+
/** Receives a caller-owned resize proposal; ZORA never mutates board dimensions. */
|
|
88
|
+
readonly onDimensionsChange?: (dimensions: ChessBoardDimensions) => void;
|
|
82
89
|
readonly renderPiece?: ChessPieceRenderer;
|
|
83
90
|
}
|
|
84
91
|
|
|
@@ -0,0 +1,453 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import {
|
|
3
|
+
GridView2
|
|
4
|
+
} from "./Accordion-t0k1cjca.js";
|
|
5
|
+
import {
|
|
6
|
+
withZoraThemeScope
|
|
7
|
+
} from "./Accordion-vj1m2wck.js";
|
|
8
|
+
import {
|
|
9
|
+
useZoraTheme2
|
|
10
|
+
} from "./Accordion-srjya6dz.js";
|
|
11
|
+
import {
|
|
12
|
+
require_cjs
|
|
13
|
+
} from "./Accordion-xgpzh4wq.js";
|
|
14
|
+
import {
|
|
15
|
+
__toESM
|
|
16
|
+
} from "./Accordion-nh0cs9hq.js";
|
|
17
|
+
|
|
18
|
+
// src/features/chess/adapters/inbound/ChessBoard.tsx
|
|
19
|
+
var import_react_native = __toESM(require_cjs(), 1);
|
|
20
|
+
import React from "react";
|
|
21
|
+
|
|
22
|
+
// src/features/chess/utils/createChessBoardCellPressHandler.ts
|
|
23
|
+
function createChessBoardCellPressHandler({
|
|
24
|
+
disabled,
|
|
25
|
+
interactionPolicy,
|
|
26
|
+
onCellPress,
|
|
27
|
+
onMoveAttempt,
|
|
28
|
+
selectedCell
|
|
29
|
+
}) {
|
|
30
|
+
return (cell) => {
|
|
31
|
+
if (disabled || interactionPolicy === "passive")
|
|
32
|
+
return;
|
|
33
|
+
onCellPress?.(cell);
|
|
34
|
+
if (selectedCell === null || selectedCell === undefined || cellsEqual(selectedCell, cell)) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
onMoveAttempt?.({ from: selectedCell, to: cell });
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function cellsEqual(left, right) {
|
|
41
|
+
return left.column === right.column && left.row === right.row;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// src/features/chess/utils/createChessBoardCells.ts
|
|
45
|
+
var minimumDimension = 2;
|
|
46
|
+
var maximumDimension = 24;
|
|
47
|
+
function createChessBoardCells(columns, rows, orientation) {
|
|
48
|
+
validateChessBoardDimensions(columns, rows);
|
|
49
|
+
return Array.from({ length: rows }, (_, rowIndex) => Array.from({ length: columns }, (_, columnIndex) => {
|
|
50
|
+
const column = columnIndex + 1;
|
|
51
|
+
const row = rowIndex + 1;
|
|
52
|
+
return {
|
|
53
|
+
column,
|
|
54
|
+
height: 1,
|
|
55
|
+
id: `${column}:${row}`,
|
|
56
|
+
row,
|
|
57
|
+
width: 1,
|
|
58
|
+
x: orientation === "white" ? columnIndex : columns - column,
|
|
59
|
+
y: orientation === "white" ? rows - row : rowIndex
|
|
60
|
+
};
|
|
61
|
+
})).flat();
|
|
62
|
+
}
|
|
63
|
+
function validateChessBoardDimensions(columns, rows) {
|
|
64
|
+
if (![columns, rows].every((dimension) => Number.isInteger(dimension) && dimension >= minimumDimension && dimension <= maximumDimension)) {
|
|
65
|
+
throw new RangeError(`ChessBoard dimensions must be whole numbers from ${minimumDimension} through ${maximumDimension}.`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// src/features/chess/utils/createChessBoardColorScheme.ts
|
|
70
|
+
function createChessBoardColorScheme(theme, overrides) {
|
|
71
|
+
return {
|
|
72
|
+
border: theme.semantics.neutral.divider,
|
|
73
|
+
coordinateText: theme.semantics.content.muted,
|
|
74
|
+
darkPiece: theme.semantics.content.default,
|
|
75
|
+
darkSquare: theme.semantics.neutral.surfaceHover,
|
|
76
|
+
darkSquareText: theme.semantics.content.muted,
|
|
77
|
+
lastMoveFrom: theme.semantics.warning.softBg,
|
|
78
|
+
lastMoveTo: theme.semantics.warning.softBg,
|
|
79
|
+
legalTarget: theme.semantics.success.softBg,
|
|
80
|
+
lightPiece: theme.semantics.content.default,
|
|
81
|
+
lightSquare: theme.semantics.neutral.surface,
|
|
82
|
+
lightSquareText: theme.semantics.content.muted,
|
|
83
|
+
selectedSquare: theme.semantics.action.primary.softBg,
|
|
84
|
+
...overrides
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// src/features/chess/adapters/inbound/ChessBoard.tsx
|
|
89
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
90
|
+
var symbols = new Map([
|
|
91
|
+
["white:p", "♙"],
|
|
92
|
+
["white:n", "♘"],
|
|
93
|
+
["white:b", "♗"],
|
|
94
|
+
["white:r", "♖"],
|
|
95
|
+
["white:q", "♕"],
|
|
96
|
+
["white:k", "♔"],
|
|
97
|
+
["black:p", "♟"],
|
|
98
|
+
["black:n", "♞"],
|
|
99
|
+
["black:b", "♝"],
|
|
100
|
+
["black:r", "♜"],
|
|
101
|
+
["black:q", "♛"],
|
|
102
|
+
["black:k", "♚"]
|
|
103
|
+
]);
|
|
104
|
+
var minimumDimension2 = 2;
|
|
105
|
+
var maximumDimension2 = 24;
|
|
106
|
+
var ChessBoard2 = withZoraThemeScope(ChessBoardInner);
|
|
107
|
+
function ChessBoardInner({
|
|
108
|
+
columns = 8,
|
|
109
|
+
rows = 8,
|
|
110
|
+
pieces,
|
|
111
|
+
orientation = "white",
|
|
112
|
+
selectedCell = null,
|
|
113
|
+
legalTargets = [],
|
|
114
|
+
lastMove = null,
|
|
115
|
+
disabled = false,
|
|
116
|
+
showCoordinates = false,
|
|
117
|
+
resizable = false,
|
|
118
|
+
colorScheme,
|
|
119
|
+
onCellPress,
|
|
120
|
+
onMoveAttempt,
|
|
121
|
+
onDimensionsChange,
|
|
122
|
+
renderPiece,
|
|
123
|
+
interactionPolicy,
|
|
124
|
+
testID
|
|
125
|
+
}) {
|
|
126
|
+
const { theme } = useZoraTheme2();
|
|
127
|
+
const colors = createChessBoardColorScheme(theme, colorScheme);
|
|
128
|
+
const dimensions = React.useMemo(() => ({ columns, rows }), [columns, rows]);
|
|
129
|
+
const [width, setWidth] = React.useState(0);
|
|
130
|
+
const cells = React.useMemo(() => createChessBoardCells(columns, rows, orientation), [columns, orientation, rows]);
|
|
131
|
+
const piecesByCell = React.useMemo(() => new Map((pieces ?? []).map((piece) => [getCellKey(piece.cell), piece])), [pieces]);
|
|
132
|
+
const cellById = React.useMemo(() => new Map(cells.map((cell) => [cell.id, cell])), [cells]);
|
|
133
|
+
const legalTargetSet = React.useMemo(() => new Set(legalTargets.map(getCellKey)), [legalTargets]);
|
|
134
|
+
const pressCell = createChessBoardCellPressHandler({
|
|
135
|
+
disabled,
|
|
136
|
+
interactionPolicy,
|
|
137
|
+
onCellPress,
|
|
138
|
+
onMoveAttempt,
|
|
139
|
+
selectedCell
|
|
140
|
+
});
|
|
141
|
+
const canResize = resizable && onDimensionsChange !== undefined && !disabled && interactionPolicy !== "passive";
|
|
142
|
+
const height = width * (dimensions.rows / dimensions.columns);
|
|
143
|
+
const cellSize = width / dimensions.columns;
|
|
144
|
+
return /* @__PURE__ */ jsxs(import_react_native.View, {
|
|
145
|
+
accessibilityLabel: "Chess board",
|
|
146
|
+
onLayout: (event) => setWidth(event.nativeEvent.layout.width),
|
|
147
|
+
style: [
|
|
148
|
+
styles.board,
|
|
149
|
+
{
|
|
150
|
+
aspectRatio: dimensions.columns / dimensions.rows,
|
|
151
|
+
borderColor: colors.border,
|
|
152
|
+
opacity: disabled ? 0.56 : 1
|
|
153
|
+
}
|
|
154
|
+
],
|
|
155
|
+
testID,
|
|
156
|
+
children: [
|
|
157
|
+
width > 0 ? /* @__PURE__ */ jsx(GridView2, {
|
|
158
|
+
contentHeight: dimensions.rows,
|
|
159
|
+
contentWidth: dimensions.columns,
|
|
160
|
+
defaultViewport: { pixelsPerUnitX: cellSize, pixelsPerUnitY: cellSize },
|
|
161
|
+
height,
|
|
162
|
+
interactionPolicy: "passive",
|
|
163
|
+
items: cells,
|
|
164
|
+
overscanPixels: 0,
|
|
165
|
+
renderItem: (item) => {
|
|
166
|
+
const cell = cellById.get(item.id);
|
|
167
|
+
return cell === undefined ? null : renderChessBoardCell({
|
|
168
|
+
cell,
|
|
169
|
+
cellSize,
|
|
170
|
+
colors,
|
|
171
|
+
disabled: disabled || interactionPolicy === "passive",
|
|
172
|
+
lastMove,
|
|
173
|
+
legalTargetSet,
|
|
174
|
+
onPress: pressCell,
|
|
175
|
+
piece: piecesByCell.get(item.id),
|
|
176
|
+
renderPiece,
|
|
177
|
+
selectedCell,
|
|
178
|
+
showCoordinates,
|
|
179
|
+
testID
|
|
180
|
+
});
|
|
181
|
+
},
|
|
182
|
+
width
|
|
183
|
+
}) : null,
|
|
184
|
+
canResize ? renderChessBoardResizeActions(dimensions, onDimensionsChange, testID) : null
|
|
185
|
+
]
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
function renderChessBoardCell({
|
|
189
|
+
cell,
|
|
190
|
+
cellSize,
|
|
191
|
+
colors,
|
|
192
|
+
disabled,
|
|
193
|
+
lastMove,
|
|
194
|
+
legalTargetSet,
|
|
195
|
+
onPress,
|
|
196
|
+
piece,
|
|
197
|
+
renderPiece,
|
|
198
|
+
selectedCell,
|
|
199
|
+
showCoordinates,
|
|
200
|
+
testID
|
|
201
|
+
}) {
|
|
202
|
+
const light = (cell.column + cell.row) % 2 === 1;
|
|
203
|
+
const key = getCellKey(cell);
|
|
204
|
+
const backgroundColor = cellsEqual2(selectedCell, cell) ? colors.selectedSquare : legalTargetSet.has(key) ? colors.legalTarget : cellsEqual2(lastMove?.from, cell) ? colors.lastMoveFrom : cellsEqual2(lastMove?.to, cell) ? colors.lastMoveTo : light ? colors.lightSquare : colors.darkSquare;
|
|
205
|
+
const pieceContent = piece === undefined ? null : renderPiece ? renderPiece({
|
|
206
|
+
cell,
|
|
207
|
+
color: piece.color === "white" ? colors.lightPiece : colors.darkPiece,
|
|
208
|
+
piece: piece.piece,
|
|
209
|
+
size: cellSize
|
|
210
|
+
}) : symbols.get(`${piece.color}:${piece.piece.toLowerCase()}`) ?? piece.piece;
|
|
211
|
+
const coordinate = formatCellCoordinate(cell);
|
|
212
|
+
return /* @__PURE__ */ jsxs(import_react_native.Pressable, {
|
|
213
|
+
accessibilityLabel: coordinate,
|
|
214
|
+
accessibilityRole: "button",
|
|
215
|
+
accessibilityState: { disabled },
|
|
216
|
+
disabled,
|
|
217
|
+
onPress: () => onPress(cell),
|
|
218
|
+
style: [styles.square, { backgroundColor }],
|
|
219
|
+
testID: testID === undefined ? undefined : `${testID}-cell-${coordinate}`,
|
|
220
|
+
children: [
|
|
221
|
+
showCoordinates ? /* @__PURE__ */ jsx(import_react_native.Text, {
|
|
222
|
+
style: [
|
|
223
|
+
styles.coordinate,
|
|
224
|
+
{ color: light ? colors.lightSquareText : colors.darkSquareText }
|
|
225
|
+
],
|
|
226
|
+
children: coordinate
|
|
227
|
+
}) : null,
|
|
228
|
+
piece === undefined ? null : /* @__PURE__ */ jsx(import_react_native.View, {
|
|
229
|
+
pointerEvents: "none",
|
|
230
|
+
style: styles.pieceContainer,
|
|
231
|
+
children: renderPiece ? pieceContent : /* @__PURE__ */ jsx(import_react_native.Text, {
|
|
232
|
+
style: [
|
|
233
|
+
styles.piece,
|
|
234
|
+
{
|
|
235
|
+
color: piece.color === "white" ? colors.lightPiece : colors.darkPiece,
|
|
236
|
+
fontSize: cellSize * 0.58,
|
|
237
|
+
lineHeight: cellSize * 0.7
|
|
238
|
+
}
|
|
239
|
+
],
|
|
240
|
+
children: pieceContent
|
|
241
|
+
})
|
|
242
|
+
})
|
|
243
|
+
]
|
|
244
|
+
}, key);
|
|
245
|
+
}
|
|
246
|
+
function renderChessBoardResizeActions(dimensions, onDimensionsChange, testID) {
|
|
247
|
+
return /* @__PURE__ */ jsxs(import_react_native.View, {
|
|
248
|
+
accessibilityLabel: "Chess board dimensions",
|
|
249
|
+
style: styles.resizeActions,
|
|
250
|
+
children: [
|
|
251
|
+
renderResizeAction("Add row", { ...dimensions, rows: dimensions.rows + 1 }, onDimensionsChange, dimensions.rows < maximumDimension2, testID),
|
|
252
|
+
renderResizeAction("Remove row", { ...dimensions, rows: dimensions.rows - 1 }, onDimensionsChange, dimensions.rows > minimumDimension2, testID),
|
|
253
|
+
renderResizeAction("Add column", { ...dimensions, columns: dimensions.columns + 1 }, onDimensionsChange, dimensions.columns < maximumDimension2, testID),
|
|
254
|
+
renderResizeAction("Remove column", { ...dimensions, columns: dimensions.columns - 1 }, onDimensionsChange, dimensions.columns > minimumDimension2, testID)
|
|
255
|
+
]
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
function renderResizeAction(label, dimensions, onDimensionsChange, enabled, testID) {
|
|
259
|
+
return /* @__PURE__ */ jsx(import_react_native.Pressable, {
|
|
260
|
+
accessibilityLabel: label,
|
|
261
|
+
accessibilityRole: "button",
|
|
262
|
+
disabled: !enabled,
|
|
263
|
+
onPress: () => onDimensionsChange(dimensions),
|
|
264
|
+
testID: testID === undefined ? undefined : `${testID}-${label.toLowerCase().replace(" ", "-")}`,
|
|
265
|
+
children: /* @__PURE__ */ jsx(import_react_native.Text, {
|
|
266
|
+
children: label
|
|
267
|
+
})
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
function cellsEqual2(left, right) {
|
|
271
|
+
if (!left || !right)
|
|
272
|
+
return false;
|
|
273
|
+
return left.column === right.column && left.row === right.row;
|
|
274
|
+
}
|
|
275
|
+
function formatCellCoordinate(cell) {
|
|
276
|
+
return `${String.fromCharCode(96 + cell.column)}${cell.row}`;
|
|
277
|
+
}
|
|
278
|
+
function getCellKey(cell) {
|
|
279
|
+
return `${cell.column}:${cell.row}`;
|
|
280
|
+
}
|
|
281
|
+
var styles = import_react_native.StyleSheet.create({
|
|
282
|
+
board: {
|
|
283
|
+
borderRadius: 12,
|
|
284
|
+
borderWidth: import_react_native.StyleSheet.hairlineWidth,
|
|
285
|
+
overflow: "hidden",
|
|
286
|
+
width: "100%"
|
|
287
|
+
},
|
|
288
|
+
coordinate: {
|
|
289
|
+
fontSize: 9,
|
|
290
|
+
fontWeight: "600",
|
|
291
|
+
left: 3,
|
|
292
|
+
opacity: 0.72,
|
|
293
|
+
position: "absolute",
|
|
294
|
+
top: 2,
|
|
295
|
+
zIndex: 2
|
|
296
|
+
},
|
|
297
|
+
piece: { fontWeight: "600" },
|
|
298
|
+
pieceContainer: {
|
|
299
|
+
alignItems: "center",
|
|
300
|
+
bottom: 0,
|
|
301
|
+
justifyContent: "center",
|
|
302
|
+
left: 0,
|
|
303
|
+
position: "absolute",
|
|
304
|
+
right: 0,
|
|
305
|
+
top: 0
|
|
306
|
+
},
|
|
307
|
+
resizeActions: { flexDirection: "row", gap: 8, padding: 8 },
|
|
308
|
+
square: { alignItems: "center", justifyContent: "center", position: "relative" }
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
// src/features/chess/adapters/inbound/OpeningBook.tsx
|
|
312
|
+
var import_react_native2 = __toESM(require_cjs(), 1);
|
|
313
|
+
|
|
314
|
+
// src/features/chess/utils/createOpeningBookColorScheme.ts
|
|
315
|
+
function createOpeningBookColorScheme(theme, overrides) {
|
|
316
|
+
return {
|
|
317
|
+
border: theme.semantics.neutral.divider,
|
|
318
|
+
metricSurface: theme.semantics.neutral.surface,
|
|
319
|
+
primaryText: theme.semantics.content.default,
|
|
320
|
+
secondaryText: theme.semantics.content.muted,
|
|
321
|
+
selectedSurface: theme.semantics.action.primary.softBg,
|
|
322
|
+
surface: theme.semantics.neutral.surface,
|
|
323
|
+
surfaceHover: theme.semantics.neutral.surfaceHover,
|
|
324
|
+
titleText: theme.semantics.content.default,
|
|
325
|
+
...overrides
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// src/features/chess/adapters/inbound/OpeningBook.tsx
|
|
330
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
331
|
+
var OpeningBook2 = withZoraThemeScope(OpeningBookInner);
|
|
332
|
+
function rate(label, value) {
|
|
333
|
+
if (value === undefined || !Number.isFinite(value))
|
|
334
|
+
return;
|
|
335
|
+
return `${label} ${Math.round(value <= 1 ? value * 100 : value)}%`;
|
|
336
|
+
}
|
|
337
|
+
function moveKey(move) {
|
|
338
|
+
return move.uci ?? move.fen ?? move.san;
|
|
339
|
+
}
|
|
340
|
+
function OpeningBookInner({
|
|
341
|
+
moves = [],
|
|
342
|
+
title = "Opening book",
|
|
343
|
+
loading = false,
|
|
344
|
+
errorText,
|
|
345
|
+
emptyText = "No book moves for this position.",
|
|
346
|
+
selectedMove = null,
|
|
347
|
+
colorScheme,
|
|
348
|
+
onMovePress,
|
|
349
|
+
interactionPolicy,
|
|
350
|
+
testID
|
|
351
|
+
}) {
|
|
352
|
+
const { theme } = useZoraTheme2();
|
|
353
|
+
const colors = createOpeningBookColorScheme(theme, colorScheme);
|
|
354
|
+
const stateText = loading ? "Loading opening moves…" : errorText ?? emptyText;
|
|
355
|
+
const showState = loading || errorText !== undefined || moves.length === 0;
|
|
356
|
+
return /* @__PURE__ */ jsxs2(import_react_native2.View, {
|
|
357
|
+
accessibilityLabel: title,
|
|
358
|
+
style: [
|
|
359
|
+
styles2.root,
|
|
360
|
+
{
|
|
361
|
+
borderColor: colors.border,
|
|
362
|
+
backgroundColor: colors.surface
|
|
363
|
+
}
|
|
364
|
+
],
|
|
365
|
+
testID,
|
|
366
|
+
children: [
|
|
367
|
+
/* @__PURE__ */ jsx2(import_react_native2.Text, {
|
|
368
|
+
style: [styles2.title, { color: colors.titleText }],
|
|
369
|
+
children: title
|
|
370
|
+
}),
|
|
371
|
+
!showState ? /* @__PURE__ */ jsx2(import_react_native2.View, {
|
|
372
|
+
style: styles2.moves,
|
|
373
|
+
children: moves.map((move) => {
|
|
374
|
+
const selected = selectedMove !== null && (selectedMove === move.san || selectedMove === move.uci || selectedMove === move.fen);
|
|
375
|
+
const details = [
|
|
376
|
+
move.eco,
|
|
377
|
+
move.name,
|
|
378
|
+
move.games === undefined ? undefined : `${move.games} games`
|
|
379
|
+
].filter((part) => typeof part === "string" && part.length > 0);
|
|
380
|
+
const stats = [
|
|
381
|
+
rate("W", move.whiteWinRate),
|
|
382
|
+
rate("D", move.drawRate),
|
|
383
|
+
rate("B", move.blackWinRate)
|
|
384
|
+
].filter((part) => part !== undefined);
|
|
385
|
+
return /* @__PURE__ */ jsxs2(import_react_native2.Pressable, {
|
|
386
|
+
accessibilityRole: "button",
|
|
387
|
+
disabled: onMovePress === undefined || interactionPolicy === "passive",
|
|
388
|
+
onPress: () => {
|
|
389
|
+
if (interactionPolicy === "passive")
|
|
390
|
+
return;
|
|
391
|
+
onMovePress?.(move);
|
|
392
|
+
},
|
|
393
|
+
style: [
|
|
394
|
+
styles2.move,
|
|
395
|
+
{
|
|
396
|
+
backgroundColor: selected ? colors.selectedSurface : colors.surfaceHover,
|
|
397
|
+
borderColor: colors.border
|
|
398
|
+
}
|
|
399
|
+
],
|
|
400
|
+
testID: testID ? `${testID}-move-${move.san}` : undefined,
|
|
401
|
+
children: [
|
|
402
|
+
/* @__PURE__ */ jsxs2(import_react_native2.View, {
|
|
403
|
+
style: styles2.moveMain,
|
|
404
|
+
children: [
|
|
405
|
+
/* @__PURE__ */ jsx2(import_react_native2.Text, {
|
|
406
|
+
style: [styles2.san, { color: colors.primaryText }],
|
|
407
|
+
children: move.san
|
|
408
|
+
}),
|
|
409
|
+
/* @__PURE__ */ jsx2(import_react_native2.Text, {
|
|
410
|
+
style: [styles2.meta, { color: colors.secondaryText }],
|
|
411
|
+
children: details.length > 0 ? details.join(" · ") : "Book move"
|
|
412
|
+
})
|
|
413
|
+
]
|
|
414
|
+
}),
|
|
415
|
+
stats.length > 0 ? /* @__PURE__ */ jsx2(import_react_native2.View, {
|
|
416
|
+
style: [styles2.metric, { backgroundColor: colors.metricSurface }],
|
|
417
|
+
children: /* @__PURE__ */ jsx2(import_react_native2.Text, {
|
|
418
|
+
style: [styles2.metricText, { color: colors.secondaryText }],
|
|
419
|
+
children: stats.join(" ")
|
|
420
|
+
})
|
|
421
|
+
}) : null
|
|
422
|
+
]
|
|
423
|
+
}, moveKey(move));
|
|
424
|
+
})
|
|
425
|
+
}) : /* @__PURE__ */ jsx2(import_react_native2.Text, {
|
|
426
|
+
style: [styles2.stateText, { color: colors.secondaryText }],
|
|
427
|
+
children: stateText
|
|
428
|
+
})
|
|
429
|
+
]
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
var styles2 = import_react_native2.StyleSheet.create({
|
|
433
|
+
root: { borderRadius: 12, borderWidth: import_react_native2.StyleSheet.hairlineWidth, gap: 10, padding: 12 },
|
|
434
|
+
title: { fontSize: 15, fontWeight: "700", lineHeight: 20 },
|
|
435
|
+
stateText: { fontSize: 13, lineHeight: 18 },
|
|
436
|
+
moves: { gap: 8 },
|
|
437
|
+
move: {
|
|
438
|
+
alignItems: "center",
|
|
439
|
+
borderRadius: 10,
|
|
440
|
+
borderWidth: import_react_native2.StyleSheet.hairlineWidth,
|
|
441
|
+
flexDirection: "row",
|
|
442
|
+
gap: 10,
|
|
443
|
+
justifyContent: "space-between",
|
|
444
|
+
paddingHorizontal: 10,
|
|
445
|
+
paddingVertical: 8
|
|
446
|
+
},
|
|
447
|
+
moveMain: { flex: 1, gap: 2 },
|
|
448
|
+
san: { fontSize: 16, fontWeight: "700", lineHeight: 20 },
|
|
449
|
+
meta: { fontSize: 12, lineHeight: 16 },
|
|
450
|
+
metric: { borderRadius: 999, paddingHorizontal: 8, paddingVertical: 4 },
|
|
451
|
+
metricText: { fontSize: 11, fontWeight: "600" }
|
|
452
|
+
});
|
|
453
|
+
export { ChessBoard2, OpeningBook2 };
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
'use client';
|
|
2
|
+
import"../../chunks/Accordion-t0k1cjca.js";
|
|
2
3
|
import"../../chunks/Accordion-6wrr910w.js";
|
|
3
4
|
import"../../chunks/Accordion-vj1m2wck.js";
|
|
4
5
|
import {
|
|
5
6
|
ChessBoard2,
|
|
6
7
|
OpeningBook2
|
|
7
|
-
} from "../../chunks/Accordion-
|
|
8
|
+
} from "../../chunks/Accordion-91sjb3zh.js";
|
|
8
9
|
import"../../chunks/Accordion-srjya6dz.js";
|
|
9
10
|
import"../../chunks/Accordion-xgpzh4wq.js";
|
|
10
11
|
export {
|