@connectorvol/chess-widgets 8.0.1 → 9.0.1

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.
Files changed (48) hide show
  1. package/dist/(components)/BoardSettingsTrigger.svelte +10 -0
  2. package/dist/(components)/BoardSettingsTrigger.svelte.d.ts +18 -0
  3. package/dist/constants/default-board-appearance-settings.d.ts +9 -0
  4. package/dist/constants/default-board-appearance-settings.js +30 -0
  5. package/dist/constants/editable-board-settings.d.ts +3 -21
  6. package/dist/constants/editable-board-settings.js +24 -19
  7. package/dist/game-analyzer/GameAnalyzer.svelte +28 -10
  8. package/dist/game-analyzer/gameAnalyzer.svelte.js +6 -9
  9. package/dist/game-analyzer/types.d.ts +13 -8
  10. package/dist/index.d.ts +9 -1
  11. package/dist/index.js +6 -0
  12. package/dist/position-editor/EditPanel.svelte +9 -6
  13. package/dist/puzzle/puzzleCreatedPayload.d.ts +17 -0
  14. package/dist/puzzle/puzzleData.d.ts +4 -0
  15. package/dist/puzzle/puzzleData.js +10 -0
  16. package/dist/puzzle/puzzlePreviewConstants.d.ts +4 -0
  17. package/dist/puzzle/puzzlePreviewConstants.js +4 -0
  18. package/dist/puzzle/puzzlePreviewPathNags.d.ts +6 -0
  19. package/dist/puzzle/puzzlePreviewPathNags.js +35 -0
  20. package/dist/puzzle/puzzleSolverForkAnnotations.d.ts +2 -4
  21. package/dist/puzzle/puzzleSolverForkAnnotations.js +13 -22
  22. package/dist/puzzle/puzzleStepPreviewSolver.d.ts +13 -1
  23. package/dist/puzzle/puzzleStepPreviewSolver.js +69 -9
  24. package/dist/puzzle/syncPuzzleBranchNags.d.ts +14 -0
  25. package/dist/puzzle/syncPuzzleBranchNags.js +125 -0
  26. package/dist/puzzle-creation/OpeningTagHoverPreview.svelte +81 -0
  27. package/dist/puzzle-creation/OpeningTagHoverPreview.svelte.d.ts +11 -0
  28. package/dist/puzzle-creation/PuzzleBoardTreeViewerPane.svelte +198 -98
  29. package/dist/puzzle-creation/PuzzleBoardTreeViewerPane.svelte.d.ts +20 -2
  30. package/dist/puzzle-creation/PuzzleCreationWizard.svelte +100 -106
  31. package/dist/puzzle-creation/PuzzleCreationWizard.svelte.d.ts +47 -3
  32. package/dist/puzzle-creation/PuzzlePgnBoardTreeEditor.svelte +945 -498
  33. package/dist/puzzle-creation/PuzzleWizardTagsStep.svelte +36 -0
  34. package/dist/puzzle-creation/PuzzleWizardTagsStep.svelte.d.ts +12 -0
  35. package/dist/puzzle-creation/StepMoves.svelte +210 -188
  36. package/dist/puzzle-creation/StepPosition.svelte +35 -9
  37. package/dist/puzzle-creation/StepPreview.svelte +24 -11
  38. package/dist/puzzle-creation/StepPreview.svelte.d.ts +3 -1
  39. package/dist/puzzle-creation/StepTags.svelte +270 -0
  40. package/dist/puzzle-creation/StepTags.svelte.d.ts +19 -0
  41. package/dist/puzzle-creation/buildPuzzleWizardBoardSettings.d.ts +9 -0
  42. package/dist/puzzle-creation/buildPuzzleWizardBoardSettings.js +19 -0
  43. package/dist/puzzle-creation/createPuzzleLineEditingBoard.d.ts +10 -3
  44. package/dist/puzzle-creation/createPuzzleLineEditingBoard.js +14 -9
  45. package/dist/puzzle-creation/puzzleWizardState.d.ts +35 -0
  46. package/dist/puzzle-creation/puzzleWizardState.js +37 -0
  47. package/dist/puzzle-creation/types.d.ts +36 -10
  48. package/package.json +22 -17
@@ -1,6 +1,6 @@
1
1
  import type { Snippet } from "svelte";
2
- import type { BoardApi } from "@connectorvol/chessboard";
3
- import type { ChessTree } from "@connectorvol/tree";
2
+ import type { BoardApi, TChessBoardDesignSettings } from "@connectorvol/chessboard";
3
+ import type { ChessTree, TTreeViewerTheme } from "@connectorvol/tree";
4
4
  /**
5
5
  * Представляет свойства панели разметки «доска и просмотр дерева партии».
6
6
  */
@@ -9,6 +9,13 @@ interface Props {
9
9
  * Возвращает API шахматной доски для компонента `Chessboard`.
10
10
  */
11
11
  chessboard: BoardApi;
12
+ /**
13
+ * Возвращает снимок дизайна, передаваемый в `<Chessboard design={...} />`.
14
+ * Опционально: если не передан, доска читает дизайн из контекста
15
+ * (`setBoardDesignSettingsContext`), что позволяет реактивно подхватывать
16
+ * изменения из `<BoardSettings />`.
17
+ */
18
+ chessboardDesign?: TChessBoardDesignSettings;
12
19
  /**
13
20
  * Возвращает экземпляр дерева ходов для `TreeViewer`.
14
21
  */
@@ -37,6 +44,17 @@ interface Props {
37
44
  * Возвращает признак возможности выбора узлов в дереве.
38
45
  */
39
46
  selectable?: boolean;
47
+ /**
48
+ * Возвращает true, если в режиме правки показывать группу NAG «Задача (развилка)»
49
+ * рядом с кнопками undo/redo на ходах из развилки.
50
+ */
51
+ showPuzzleBranchNags?: boolean;
52
+ /**
53
+ * Возвращает тему `TreeViewer` (фон, границы, текст). По умолчанию
54
+ * подстраивается под `mode-watcher` (dark → `TREE_VIEWER_DARK_THEME`,
55
+ * иначе `TREE_VIEWER_LIGHT_THEME`).
56
+ */
57
+ theme?: TTreeViewerTheme;
40
58
  /**
41
59
  * Возвращает дополнительные классы Tailwind для корневого контейнера.
42
60
  */
@@ -1,71 +1,81 @@
1
1
  <script lang="ts" module>
2
2
  export type { TPuzzleCreationWizardProps } from "./types.js";
3
+ export type {
4
+ TPuzzleWizardCoreState,
5
+ TPuzzleWizardState,
6
+ } from "./puzzleWizardState.js";
3
7
  </script>
4
8
 
5
- <script lang="ts">
6
- import { untrack } from "svelte";
9
+ <script lang="ts" generics="S extends TPuzzleWizardCoreState">
10
+ import type { Snippet } from "svelte";
7
11
 
12
+ import { Wizard } from "@connectorvol/shared";
13
+ import type { TWizardStep, TWizardStepContext } from "@connectorvol/shared";
8
14
  import StepMoves from "./StepMoves.svelte";
9
15
  import StepPosition from "./StepPosition.svelte";
10
16
  import StepPreview from "./StepPreview.svelte";
11
- import type { TPuzzleCreationWizardProps } from "./types.js";
12
- import {
13
- createEmptyTreeFromFen,
14
- createInitialPuzzleData,
15
- type PuzzleData,
16
- } from "../puzzle/puzzleData.js";
17
+ import type { TPuzzleCreatedPayload } from "../puzzle/puzzleCreatedPayload.js";
18
+ import type { TPuzzleWizardCoreState } from "./puzzleWizardState.js";
19
+ import { PUZZLE_WIZARD_CORE_STEPS } from "./puzzleWizardState.js";
20
+ import { createEmptyTreeFromFen } from "../puzzle/puzzleData.js";
17
21
  import { PgnOps } from "@connectorvol/chessops/pgnOps.svelte";
18
22
  import { ChessTree, createPgnFromTree } from "@connectorvol/tree";
19
23
  import {
20
24
  CHESSBOARD_THEMES,
21
25
  Draggable,
26
+ type ChessboardTheme,
22
27
  type IChessBoardActions,
23
28
  } from "@connectorvol/chessboard";
24
29
  import { calculatePly, Color, Square } from "@connectorvol/shared";
25
30
 
26
31
  import { createPuzzleLineEditingBoardApi } from "./createPuzzleLineEditingBoard.js";
32
+ import { syncPuzzleBranchNagsOnTree } from "../puzzle/syncPuzzleBranchNags.js";
33
+ import { DEFAULT_BOARD_APPEARANCE_SETTINGS } from "../constants/default-board-appearance-settings.js";
34
+ import type { TChessboardAppearanceSettings } from "./types.js";
35
+ import { derived } from "svelte/store";
36
+
37
+ interface Props {
38
+ /** Возвращает общий state визарда (двухсторонняя привязка). */
39
+ wizardState: S;
40
+ /** Возвращает колбэк завершения с шага превью без доп. шагов. */
41
+ onPuzzleCreated: (payload: TPuzzleCreatedPayload) => void;
42
+ /** Возвращает колбэк завершения с доп. шага (`wizard.done()`). */
43
+ onDone?: (state: S) => void;
44
+ /** Возвращает seed FEN для сброса шага визарда при изменении. */
45
+ fen?: string;
46
+ /** Возвращает тему оформления шахматной доски. */
47
+ boardTheme?: ChessboardTheme;
48
+ /** Возвращает визуальные настройки доски. */
49
+ boardAppearanceSettings?: TChessboardAppearanceSettings;
50
+ /** Возвращает дополнительные шаги после превью. */
51
+ additionalSteps?: readonly TWizardStep[];
52
+ /** Возвращает snippet дополнительных шагов. */
53
+ additionalStep?: Snippet<[TWizardStepContext<S>]>;
54
+ }
27
55
 
28
- const {
56
+ let {
57
+ wizardState = $bindable(),
29
58
  onPuzzleCreated,
59
+ onDone,
30
60
  fen: fenProp,
31
61
  boardTheme,
32
- boardAppearanceSettings,
33
- }: TPuzzleCreationWizardProps = $props();
62
+ boardAppearanceSettings = DEFAULT_BOARD_APPEARANCE_SETTINGS,
63
+ additionalSteps = [],
64
+ additionalStep,
65
+ }: Props = $props();
34
66
 
35
- /**
36
- * Представляет нормализацию входного FEN из пропса (пустая строка трактуется как отсутствие значения).
37
- */
38
- function wizardSeedFen(prop: string | undefined): string | undefined {
39
- const t = prop?.trim();
40
- return t ? t : undefined;
41
- }
67
+ const hasAdditionalSteps = $derived(additionalSteps.length > 0);
68
+ const steps = $derived([...PUZZLE_WIZARD_CORE_STEPS, ...additionalSteps]);
42
69
 
43
- let step = $state<1 | 2 | 3>(1);
44
- let puzzleData = $derived<PuzzleData>(
45
- createInitialPuzzleData(wizardSeedFen(fenProp)),
70
+ let chess = $derived(
71
+ new PgnOps(wizardState.puzzleData.initialFen, "chess"),
46
72
  );
47
-
48
- /** Возвращает PGN дерева решения для превью на шаге 3. */
49
- let solutionPgnForPreview = $state("");
50
-
51
- function handleMovesBack() {
52
- step = 1;
53
- }
54
-
55
- function handleMovesNext(moves: string[]) {
56
- puzzleData.moves = moves;
57
- solutionPgnForPreview = createPgnFromTree(tree.rootNode);
58
- step = 3;
59
- }
60
-
61
- function handlePreviewBack() {
62
- step = 2;
63
- }
64
-
65
- let chess = $derived(new PgnOps(puzzleData.initialFen, "chess"));
66
73
  let tree = $derived(
67
- new ChessTree(createEmptyTreeFromFen(puzzleData.initialFen)),
74
+ new ChessTree(
75
+ createEmptyTreeFromFen(wizardState.puzzleData.initialFen),
76
+ ),
68
77
  );
78
+
69
79
  const addMoveToTree = (san: string) => {
70
80
  const move = chess.makeSanMove(san);
71
81
  if (!move) return;
@@ -111,7 +121,7 @@
111
121
  },
112
122
  afterPieceMove: () => {
113
123
  const side = chess.turn();
114
- chessboard.draggable =
124
+ chessboardApi.draggable =
115
125
  side === Color.WHITE ? Draggable.WHITE : Draggable.BLACK;
116
126
  },
117
127
  },
@@ -127,86 +137,70 @@
127
137
  });
128
138
  }
129
139
 
130
- let chessboard = $derived(createMainChessboard(puzzleData.initialFen));
140
+ let chessboard = $derived(
141
+ createMainChessboard(wizardState.puzzleData.initialFen),
142
+ );
143
+ let chessboardApi = $derived(chessboard.api);
144
+
145
+ // ponytail: компонент только читает контекст дизайна. Дизайн для доски шага 2,
146
+ // который раньше поднимался через `setBoardDesignSettingsContext`, теперь
147
+ // пробрасывается явно пропом `chessboardDesign` в `<StepMoves />`.
148
+ const chessboardDesign = $derived(chessboard.design);
131
149
 
132
150
  /**
133
- * Представляет сброс мастера при смене входного FEN извне (шаг 1 и черновик ходов обнуляются).
151
+ * Представляет переход со шага построения линии на превью.
134
152
  */
135
- $effect(() => {
136
- const seed = wizardSeedFen(fenProp);
137
- const next = createInitialPuzzleData(seed);
138
- untrack(() => {
139
- puzzleData = next;
140
- step = 1;
141
- solutionPgnForPreview = "";
142
- });
143
- });
144
-
145
- function handlePositionNext(fen: string) {
146
- puzzleData.initialFen = fen;
147
- step = 2;
153
+ function handleMovesNext(moves: string[]) {
154
+ wizardState.puzzleData.moves = moves;
155
+ syncPuzzleBranchNagsOnTree(
156
+ tree,
157
+ wizardState.puzzleData.initialFen.trim().split(/\s+/)[1] === "b"
158
+ ? Color.BLACK
159
+ : Color.WHITE,
160
+ );
161
+ wizardState.solutionPgn = createPgnFromTree(tree.rootNode);
148
162
  }
149
163
  </script>
150
164
 
151
- <div class="mx-4 lg:container lg:mx-auto">
152
- <div class="flex flex-col gap-4 pt-4 pb-0">
153
- <div class="flex items-center gap-2">
154
- <span
155
- class="flex h-8 w-8 items-center justify-center rounded-full text-sm font-medium"
156
- class:bg-primary={step >= 1}
157
- class:bg-muted={step < 1}
158
- class:text-primary-foreground={step >= 1}
159
- >
160
- 1
161
- </span>
162
- <span class="text-sm">Позиция</span>
163
- <span class="h-px flex-1 bg-border"></span>
164
- <span
165
- class="flex h-8 w-8 items-center justify-center rounded-full text-sm font-medium"
166
- class:bg-primary={step >= 2}
167
- class:bg-muted={step < 2}
168
- class:text-primary-foreground={step >= 2}
169
- >
170
- 2
171
- </span>
172
- <span class="text-sm">Ходы</span>
173
- <span class="h-px flex-1 bg-border"></span>
174
- <span
175
- class="flex h-8 w-8 items-center justify-center rounded-full text-sm font-medium"
176
- class:bg-primary={step >= 3}
177
- class:bg-muted={step < 3}
178
- class:text-primary-foreground={step >= 3}
179
- >
180
- 3
181
- </span>
182
- <span class="text-sm">Превью</span>
183
- </div>
184
-
185
- {#if step === 1}
165
+ <Wizard bind:wizardState {steps} resetSignal={fenProp} {onDone}>
166
+ {#snippet children(w)}
167
+ {#if w.currentStep === 1}
186
168
  <StepPosition
187
- initialFen={puzzleData.initialFen}
188
- onNext={handlePositionNext}
169
+ initialFen={w.state.puzzleData.initialFen}
170
+ onNext={(fen) => {
171
+ w.state.puzzleData.initialFen = fen;
172
+ w.next();
173
+ }}
189
174
  {boardTheme}
190
175
  {boardAppearanceSettings}
191
176
  />
192
- {:else if step === 2}
177
+ {:else if w.currentStep === 2}
193
178
  <StepMoves
194
- {puzzleData}
179
+ puzzleData={w.state.puzzleData}
195
180
  {chess}
196
181
  {tree}
197
- {chessboard}
198
- onBack={handleMovesBack}
199
- onNext={handleMovesNext}
182
+ chessboard={chessboardApi}
183
+ {chessboardDesign}
184
+ onBack={w.back}
185
+ onNext={(moves) => {
186
+ handleMovesNext(moves);
187
+ w.next();
188
+ }}
200
189
  />
201
- {:else}
190
+ {:else if w.currentStep === 3}
202
191
  <StepPreview
203
- {puzzleData}
204
- solutionPgn={solutionPgnForPreview}
205
- onBack={handlePreviewBack}
206
- {onPuzzleCreated}
192
+ puzzleData={w.state.puzzleData}
193
+ solutionPgn={w.state.solutionPgn}
194
+ onBack={w.back}
195
+ onNext={hasAdditionalSteps ? w.next : undefined}
196
+ onPuzzleCreated={hasAdditionalSteps
197
+ ? undefined
198
+ : onPuzzleCreated}
207
199
  {boardTheme}
208
200
  {boardAppearanceSettings}
209
201
  />
202
+ {:else if additionalStep}
203
+ {@render additionalStep(w)}
210
204
  {/if}
211
- </div>
212
- </div>
205
+ {/snippet}
206
+ </Wizard>
@@ -1,5 +1,49 @@
1
1
  export type { TPuzzleCreationWizardProps } from "./types.js";
2
- import type { TPuzzleCreationWizardProps } from "./types.js";
3
- declare const PuzzleCreationWizard: import("svelte").Component<TPuzzleCreationWizardProps, {}, "">;
4
- type PuzzleCreationWizard = ReturnType<typeof PuzzleCreationWizard>;
2
+ export type { TPuzzleWizardCoreState, TPuzzleWizardState, } from "./puzzleWizardState.js";
3
+ import type { Snippet } from "svelte";
4
+ import type { TWizardStep, TWizardStepContext } from "@connectorvol/shared";
5
+ import type { TPuzzleCreatedPayload } from "../puzzle/puzzleCreatedPayload.js";
6
+ import type { TPuzzleWizardCoreState } from "./puzzleWizardState.js";
7
+ import { type ChessboardTheme } from "@connectorvol/chessboard";
8
+ import type { TChessboardAppearanceSettings } from "./types.js";
9
+ declare function $$render<S extends TPuzzleWizardCoreState>(): {
10
+ props: {
11
+ /** Возвращает общий state визарда (двухсторонняя привязка). */
12
+ wizardState: S;
13
+ /** Возвращает колбэк завершения с шага превью без доп. шагов. */
14
+ onPuzzleCreated: (payload: TPuzzleCreatedPayload) => void;
15
+ /** Возвращает колбэк завершения с доп. шага (`wizard.done()`). */
16
+ onDone?: (state: S) => void;
17
+ /** Возвращает seed FEN для сброса шага визарда при изменении. */
18
+ fen?: string;
19
+ /** Возвращает тему оформления шахматной доски. */
20
+ boardTheme?: ChessboardTheme;
21
+ /** Возвращает визуальные настройки доски. */
22
+ boardAppearanceSettings?: TChessboardAppearanceSettings;
23
+ /** Возвращает дополнительные шаги после превью. */
24
+ additionalSteps?: readonly TWizardStep[];
25
+ /** Возвращает snippet дополнительных шагов. */
26
+ additionalStep?: Snippet<[TWizardStepContext<S>]>;
27
+ };
28
+ exports: {};
29
+ bindings: "wizardState";
30
+ slots: {};
31
+ events: {};
32
+ };
33
+ declare class __sveltets_Render<S extends TPuzzleWizardCoreState> {
34
+ props(): ReturnType<typeof $$render<S>>['props'];
35
+ events(): ReturnType<typeof $$render<S>>['events'];
36
+ slots(): ReturnType<typeof $$render<S>>['slots'];
37
+ bindings(): "wizardState";
38
+ exports(): {};
39
+ }
40
+ interface $$IsomorphicComponent {
41
+ new <S extends TPuzzleWizardCoreState>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<S>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<S>['props']>, ReturnType<__sveltets_Render<S>['events']>, ReturnType<__sveltets_Render<S>['slots']>> & {
42
+ $$bindings?: ReturnType<__sveltets_Render<S>['bindings']>;
43
+ } & ReturnType<__sveltets_Render<S>['exports']>;
44
+ <S extends TPuzzleWizardCoreState>(internal: unknown, props: ReturnType<__sveltets_Render<S>['props']> & {}): ReturnType<__sveltets_Render<S>['exports']>;
45
+ z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
46
+ }
47
+ declare const PuzzleCreationWizard: $$IsomorphicComponent;
48
+ type PuzzleCreationWizard<S extends TPuzzleWizardCoreState> = InstanceType<typeof PuzzleCreationWizard<S>>;
5
49
  export default PuzzleCreationWizard;