@mirasen/chessboard 1.2.4 → 1.3.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.
- package/CHANGELOG.md +50 -0
- package/README.md +72 -1
- package/dist/animation/planner.js +2 -1
- package/dist/extensions/build/index.d.ts +1 -1
- package/dist/extensions/first-party/annotations/update.js +1 -1
- package/dist/extensions/first-party/board-events/factory.js +2 -2
- package/dist/extensions/first-party/main-renderer/animation/factory.d.ts +2 -1
- package/dist/extensions/first-party/main-renderer/animation/factory.js +3 -2
- package/dist/extensions/first-party/main-renderer/animation/types.d.ts +2 -0
- package/dist/extensions/first-party/main-renderer/animation/update.js +4 -2
- package/dist/extensions/first-party/main-renderer/board/factory.d.ts +1 -1
- package/dist/extensions/first-party/main-renderer/board/factory.js +4 -4
- package/dist/extensions/first-party/main-renderer/board/render.js +1 -1
- package/dist/extensions/first-party/main-renderer/board/types.d.ts +1 -1
- package/dist/extensions/first-party/main-renderer/coordinates/factory.d.ts +1 -1
- package/dist/extensions/first-party/main-renderer/coordinates/factory.js +2 -2
- package/dist/extensions/first-party/main-renderer/coordinates/render.js +1 -1
- package/dist/extensions/first-party/main-renderer/coordinates/types.d.ts +1 -1
- package/dist/extensions/first-party/main-renderer/denormalize.d.ts +3 -0
- package/dist/extensions/first-party/main-renderer/denormalize.js +18 -0
- package/dist/extensions/first-party/main-renderer/drag/factory.d.ts +2 -1
- package/dist/extensions/first-party/main-renderer/drag/factory.js +2 -1
- package/dist/extensions/first-party/main-renderer/drag/render.js +18 -11
- package/dist/extensions/first-party/main-renderer/drag/types.d.ts +2 -0
- package/dist/extensions/first-party/main-renderer/drag/update.js +4 -2
- package/dist/extensions/first-party/main-renderer/factory.d.ts +2 -1
- package/dist/extensions/first-party/main-renderer/factory.js +46 -12
- package/dist/extensions/first-party/main-renderer/normalize.d.ts +3 -3
- package/dist/extensions/first-party/main-renderer/normalize.js +19 -7
- package/dist/extensions/first-party/main-renderer/pieces/suppress.js +2 -1
- package/dist/extensions/first-party/main-renderer/public-defaults.d.ts +3 -0
- package/dist/extensions/first-party/main-renderer/public-defaults.js +4 -0
- package/dist/extensions/first-party/main-renderer/types/extension.d.ts +8 -5
- package/dist/extensions/first-party/main-renderer/types/instance.d.ts +10 -8
- package/dist/extensions/first-party/main-renderer/types/internal.d.ts +6 -7
- package/dist/extensions/first-party/main-renderer/types/internal.js +24 -1
- package/dist/extensions/first-party/main-renderer/types/public.d.ts +9 -0
- package/dist/extensions/first-party/main-renderer/types/template.d.ts +12 -1
- package/dist/extensions/first-party/promotion/types/input.d.ts +2 -2
- package/dist/extensions/index.d.ts +1 -0
- package/dist/extensions/index.js +1 -0
- package/dist/extensions/types/basic/events.d.ts +30 -16
- package/dist/extensions/types/basic/interaction.d.ts +12 -2
- package/dist/extensions/types/surface/commands.d.ts +4 -2
- package/dist/index.d.ts +10 -0
- package/dist/index.js +11 -0
- package/dist/runtime/factory/input.js +50 -24
- package/dist/runtime/factory/main.js +11 -0
- package/dist/runtime/input/adapter/types.js +2 -1
- package/dist/runtime/input/controller/factory.js +36 -9
- package/dist/runtime/input/controller/helpers.d.ts +5 -0
- package/dist/runtime/input/controller/helpers.js +11 -0
- package/dist/runtime/input/controller/pointer.js +48 -21
- package/dist/runtime/input/controller/types.d.ts +13 -4
- package/dist/runtime/mutation/interaction.js +1 -1
- package/dist/runtime/mutation/types.d.ts +2 -2
- package/dist/state/interaction/config.d.ts +6 -0
- package/dist/state/interaction/config.js +30 -0
- package/dist/state/interaction/factory.js +15 -3
- package/dist/state/interaction/helpers.d.ts +18 -2
- package/dist/state/interaction/helpers.js +12 -0
- package/dist/state/interaction/mutation.d.ts +2 -0
- package/dist/state/interaction/reducers.d.ts +3 -0
- package/dist/state/interaction/reducers.js +22 -7
- package/dist/state/interaction/types/config.d.ts +9 -0
- package/dist/state/interaction/types/config.js +1 -0
- package/dist/state/interaction/types/input.d.ts +3 -0
- package/dist/state/interaction/types/internal.d.ts +14 -4
- package/dist/state/interaction/types/main.d.ts +11 -5
- package/dist/wrapper/factory.js +2 -0
- package/dist/wrapper/types.d.ts +1 -1
- package/package.json +5 -6
- package/dist/extensions/first-party/main-renderer/types/input.d.ts +0 -4
- /package/dist/extensions/first-party/main-renderer/types/{input.js → public.js} +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { isDragSessionActiveLiftedPiece } from '../../../../state/interaction/helpers.js';
|
|
1
2
|
export function calculateSuppressedSquares(_state, context, animationSuppressedSquares) {
|
|
2
3
|
const dragSession = context.currentFrame.state.interaction.dragSession;
|
|
3
|
-
const dragSquare = dragSession
|
|
4
|
+
const dragSquare = dragSession && isDragSessionActiveLiftedPiece(dragSession) ? dragSession.sourceSquare : null;
|
|
4
5
|
const result = new Set(animationSuppressedSquares);
|
|
5
6
|
if (dragSquare !== null) {
|
|
6
7
|
result.add(dragSquare);
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { denormalizeMainRendererConfig } from './denormalize.js';
|
|
2
|
+
import { DefaultMainRendererDesktopConfig, DefaultMainRendererMobileConfig } from './types/internal.js';
|
|
3
|
+
export const DefaultMainRendererDesktopConfigPublic = denormalizeMainRendererConfig(DefaultMainRendererDesktopConfig);
|
|
4
|
+
export const DefaultMainRendererMobileConfigPublic = denormalizeMainRendererConfig(DefaultMainRendererMobileConfig);
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import { ExtensionDefinition, ExtensionInstance } from '../../../types/extension.js';
|
|
2
|
-
import {
|
|
3
|
-
export type MainRendererInitOptions = Partial<MainRendererConfigInput>;
|
|
1
|
+
import type { ExtensionDefinition, ExtensionInstance } from '../../../types/extension.js';
|
|
2
|
+
import type { MainRendererConfigPublic, MainRendererSetConfigOptions } from './public.js';
|
|
4
3
|
export declare const EXTENSION_SLOTS: readonly ["defs", "board", "coordinates", "pieces", "animation", "drag"];
|
|
5
4
|
export type ExtensionSlotsType = typeof EXTENSION_SLOTS;
|
|
6
5
|
export declare const EXTENSION_ID: "renderer";
|
|
7
|
-
export
|
|
8
|
-
|
|
6
|
+
export interface RendererPublicAPI {
|
|
7
|
+
setConfig(options: MainRendererSetConfigOptions): void;
|
|
8
|
+
getConfig(): MainRendererConfigPublic;
|
|
9
|
+
}
|
|
10
|
+
export type MainRendererDefinition = ExtensionDefinition<typeof EXTENSION_ID, typeof EXTENSION_SLOTS, RendererPublicAPI>;
|
|
11
|
+
export type MainRendererInstance = ExtensionInstance<typeof EXTENSION_ID, typeof EXTENSION_SLOTS, RendererPublicAPI>;
|
|
9
12
|
export declare enum DirtyLayer {
|
|
10
13
|
Board = 1,// 1 << 0,
|
|
11
14
|
Coordinates = 2,// 1 << 1,
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { ExtensionRuntimeSurface } from '../../../types/surface/main.js';
|
|
2
|
-
import { ExtensionInternalBase } from '../../common/types.js';
|
|
3
|
-
import { MainRendererAnimation } from '../animation/types.js';
|
|
4
|
-
import { MainRendererBoard } from '../board/types.js';
|
|
5
|
-
import { MainRendererCoordinates } from '../coordinates/types.js';
|
|
6
|
-
import { MainRendererDrag } from '../drag/types.js';
|
|
1
|
+
import type { ExtensionRuntimeSurface } from '../../../types/surface/main.js';
|
|
2
|
+
import type { ExtensionInternalBase } from '../../common/types.js';
|
|
3
|
+
import type { MainRendererAnimation } from '../animation/types.js';
|
|
4
|
+
import type { MainRendererBoard } from '../board/types.js';
|
|
5
|
+
import type { MainRendererCoordinates } from '../coordinates/types.js';
|
|
6
|
+
import type { MainRendererDrag } from '../drag/types.js';
|
|
7
7
|
import type { PieceSymbolResolver } from '../piece-symbols.js';
|
|
8
|
-
import { MainRendererPieces } from '../pieces/types.js';
|
|
9
|
-
import { ExtensionSlotsType } from './extension.js';
|
|
8
|
+
import type { MainRendererPieces } from '../pieces/types.js';
|
|
9
|
+
import type { ExtensionSlotsType } from './extension.js';
|
|
10
|
+
import type { MainRendererConfig } from './internal.js';
|
|
10
11
|
export interface MainRendererInstanceInternal extends ExtensionInternalBase<ExtensionSlotsType> {
|
|
11
12
|
readonly board: MainRendererBoard;
|
|
12
13
|
readonly coordinates: MainRendererCoordinates;
|
|
@@ -15,4 +16,5 @@ export interface MainRendererInstanceInternal extends ExtensionInternalBase<Exte
|
|
|
15
16
|
readonly animation: MainRendererAnimation;
|
|
16
17
|
readonly runtimeSurface: ExtensionRuntimeSurface;
|
|
17
18
|
readonly pieceSymbolResolver: PieceSymbolResolver;
|
|
19
|
+
config: MainRendererConfig;
|
|
18
20
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import type { ReadonlyDeep } from 'type-fest';
|
|
2
|
+
import type { NonEmptyPieceCode } from '../../../../state/board/types/internal.js';
|
|
3
|
+
import type { TMainRendererConfig } from './template.js';
|
|
3
4
|
export interface ConfigColorPair {
|
|
4
5
|
light: string;
|
|
5
6
|
dark: string;
|
|
@@ -9,9 +10,7 @@ export interface ConfigColors {
|
|
|
9
10
|
coordinates: ConfigColorPair;
|
|
10
11
|
}
|
|
11
12
|
export type PieceUrls = Record<NonEmptyPieceCode, string>;
|
|
12
|
-
export type MainRendererConfig = TMainRendererConfig<PieceUrls
|
|
13
|
+
export type MainRendererConfig = ReadonlyDeep<TMainRendererConfig<PieceUrls>>;
|
|
13
14
|
export declare const CHESSNUT_PIECE_URLS: PieceUrls;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
*/
|
|
17
|
-
export declare const DEFAULT_MAIN_RENDERER_CONFIG: MainRendererConfig;
|
|
15
|
+
export declare const DefaultMainRendererDesktopConfig: MainRendererConfig;
|
|
16
|
+
export declare const DefaultMainRendererMobileConfig: MainRendererConfig;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { cloneDeep } from 'es-toolkit';
|
|
1
2
|
export const CHESSNUT_PIECE_URLS = {
|
|
2
3
|
[6 /* PieceCode.WhiteKing */]: new URL('../../../../../assets/pieces/chessnut/wK.svg', import.meta.url).toString(),
|
|
3
4
|
[5 /* PieceCode.WhiteQueen */]: new URL('../../../../../assets/pieces/chessnut/wQ.svg', import.meta.url).toString(),
|
|
@@ -15,7 +16,7 @@ export const CHESSNUT_PIECE_URLS = {
|
|
|
15
16
|
/**
|
|
16
17
|
* Default board renderer configuration.
|
|
17
18
|
*/
|
|
18
|
-
|
|
19
|
+
const DefaultMainRendererConfigPart = {
|
|
19
20
|
colors: {
|
|
20
21
|
board: {
|
|
21
22
|
light: '#d7dde5',
|
|
@@ -28,3 +29,25 @@ export const DEFAULT_MAIN_RENDERER_CONFIG = {
|
|
|
28
29
|
},
|
|
29
30
|
pieceUrls: CHESSNUT_PIECE_URLS
|
|
30
31
|
};
|
|
32
|
+
export const DefaultMainRendererDesktopConfig = {
|
|
33
|
+
...cloneDeep(DefaultMainRendererConfigPart),
|
|
34
|
+
drag: {
|
|
35
|
+
pieceScale: 1,
|
|
36
|
+
pieceAnchor: 'center',
|
|
37
|
+
pieceAnchorOffsetY: 0
|
|
38
|
+
},
|
|
39
|
+
animation: {
|
|
40
|
+
durationMs: 180
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
export const DefaultMainRendererMobileConfig = {
|
|
44
|
+
...cloneDeep(DefaultMainRendererConfigPart),
|
|
45
|
+
drag: {
|
|
46
|
+
pieceScale: 2,
|
|
47
|
+
pieceAnchor: 'bottom',
|
|
48
|
+
pieceAnchorOffsetY: 0.14
|
|
49
|
+
},
|
|
50
|
+
animation: {
|
|
51
|
+
durationMs: 180
|
|
52
|
+
}
|
|
53
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { PartialDeep, ReadonlyDeep, WritableDeep } from 'type-fest';
|
|
2
|
+
import type { PieceString } from '../../../../state/board/types/input.js';
|
|
3
|
+
import type { TMainRendererConfig } from './template.js';
|
|
4
|
+
export type PieceUrlsPublic = Record<PieceString, string>;
|
|
5
|
+
export type MainRendererConfigPublic = ReadonlyDeep<TMainRendererConfig<PieceUrlsPublic>>;
|
|
6
|
+
export interface MainRendererInitOptions extends PartialDeep<WritableDeep<MainRendererConfigPublic>> {
|
|
7
|
+
pieceUrls?: PieceUrlsPublic;
|
|
8
|
+
}
|
|
9
|
+
export type MainRendererSetConfigOptions = Omit<MainRendererInitOptions, 'pieceUrls'>;
|
|
@@ -1,5 +1,16 @@
|
|
|
1
|
-
import { ConfigColors } from './internal.js';
|
|
1
|
+
import type { ConfigColors } from './internal.js';
|
|
2
|
+
export type MainRendererConfigDragPieceAnchor = 'center' | 'bottom';
|
|
3
|
+
export interface MainRendererConfigDrag {
|
|
4
|
+
pieceScale: number;
|
|
5
|
+
pieceAnchor: MainRendererConfigDragPieceAnchor;
|
|
6
|
+
pieceAnchorOffsetY: number;
|
|
7
|
+
}
|
|
8
|
+
export interface MainRendererConfigAnimation {
|
|
9
|
+
durationMs: number;
|
|
10
|
+
}
|
|
2
11
|
export interface TMainRendererConfig<TPieceUrls> {
|
|
3
12
|
colors: ConfigColors;
|
|
4
13
|
pieceUrls: TPieceUrls;
|
|
14
|
+
drag: MainRendererConfigDrag;
|
|
15
|
+
animation: MainRendererConfigAnimation;
|
|
5
16
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { ColorShort, RolePromotionShort } from '../../../../state/board/types/input.js';
|
|
2
2
|
import { OpaqueColor } from '../../common/types.js';
|
|
3
|
-
import {
|
|
3
|
+
import { PieceUrlsPublic } from '../../main-renderer/types/public.js';
|
|
4
4
|
export type PromotionPieceString = `${ColorShort}${RolePromotionShort}`;
|
|
5
|
-
export type PromotionPieceUrlsInput = Pick<
|
|
5
|
+
export type PromotionPieceUrlsInput = Pick<PieceUrlsPublic, PromotionPieceString>;
|
|
6
6
|
export interface PromotionInitConfig {
|
|
7
7
|
squareColor?: OpaqueColor;
|
|
8
8
|
hoverColor?: OpaqueColor;
|
|
@@ -1 +1,2 @@
|
|
|
1
|
+
export { DefaultMainRendererDesktopConfigPublic as DefaultMainRendererDesktopConfig, DefaultMainRendererMobileConfigPublic as DefaultMainRendererMobileConfig } from './first-party/main-renderer/public-defaults.js';
|
|
1
2
|
export { builtInExtensionFactoryMap, type BuiltInExtensionId } from './types/wrapper.js';
|
package/dist/extensions/index.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
+
export { DefaultMainRendererDesktopConfigPublic as DefaultMainRendererDesktopConfig, DefaultMainRendererMobileConfigPublic as DefaultMainRendererMobileConfig } from './first-party/main-renderer/public-defaults.js';
|
|
1
2
|
export { builtInExtensionFactoryMap } from './types/wrapper.js';
|
|
@@ -11,29 +11,43 @@ export interface ScenePointerEvent {
|
|
|
11
11
|
readonly targetSquare: Square | null;
|
|
12
12
|
}
|
|
13
13
|
export type SceneEvent = ScenePointerEvent;
|
|
14
|
-
export type
|
|
15
|
-
type: '
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
export type RuntimeInteractionActionStartPendingLiftedDragSession = {
|
|
15
|
+
type: 'startLiftedDragSession';
|
|
16
|
+
phase: 'pending';
|
|
17
|
+
sourceSquare: Square;
|
|
18
|
+
targetSquare: Square;
|
|
18
19
|
startButton: number;
|
|
20
|
+
startPoint: ScenePoint;
|
|
21
|
+
thresholdPx: number;
|
|
19
22
|
};
|
|
20
|
-
export type
|
|
21
|
-
type: '
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
export type RuntimeInteractionActionStartActiveLiftedDragSession = {
|
|
24
|
+
type: 'startLiftedDragSession';
|
|
25
|
+
phase: 'active';
|
|
26
|
+
sourceSquare: Square;
|
|
27
|
+
targetSquare: Square;
|
|
24
28
|
startButton: number;
|
|
25
29
|
};
|
|
26
|
-
export type
|
|
27
|
-
type: '
|
|
28
|
-
|
|
30
|
+
export type RuntimeInteractionActionActivatePendingLiftedDragSession = {
|
|
31
|
+
type: 'activatePendingLiftedDragSession';
|
|
32
|
+
targetSquare: Square | null;
|
|
29
33
|
};
|
|
30
|
-
export type
|
|
31
|
-
type: '
|
|
32
|
-
|
|
34
|
+
export type RuntimeInteractionActionStartReleaseTargetingDragSession = {
|
|
35
|
+
type: 'startReleaseTargetingDragSession';
|
|
36
|
+
sourceSquare: Square;
|
|
37
|
+
targetSquare: Square;
|
|
38
|
+
startButton: number;
|
|
39
|
+
};
|
|
40
|
+
export type RuntimeInteractionActionCompleteCoreDragSessionTo = {
|
|
41
|
+
type: 'completeCoreDragSessionTo';
|
|
42
|
+
targetSquare: Square;
|
|
43
|
+
};
|
|
44
|
+
export type RuntimeInteractionActionCompleteExtensionDragSession = {
|
|
45
|
+
type: 'completeExtensionDragSession';
|
|
46
|
+
targetSquare: Square | null;
|
|
33
47
|
};
|
|
34
48
|
export type RuntimeInteractionActionUpdateDragSessionCurrentTarget = {
|
|
35
49
|
type: 'updateDragSessionCurrentTarget';
|
|
36
|
-
|
|
50
|
+
targetSquare: Square | null;
|
|
37
51
|
};
|
|
38
52
|
export type RuntimeInteractionActionCancelActiveInteraction = {
|
|
39
53
|
type: 'cancelActiveInteraction';
|
|
@@ -41,5 +55,5 @@ export type RuntimeInteractionActionCancelActiveInteraction = {
|
|
|
41
55
|
export type RuntimeInteractionActionCancelInteraction = {
|
|
42
56
|
type: 'cancelInteraction';
|
|
43
57
|
};
|
|
44
|
-
export type RuntimeInteractionAction =
|
|
58
|
+
export type RuntimeInteractionAction = RuntimeInteractionActionStartPendingLiftedDragSession | RuntimeInteractionActionStartActiveLiftedDragSession | RuntimeInteractionActionActivatePendingLiftedDragSession | RuntimeInteractionActionStartReleaseTargetingDragSession | RuntimeInteractionActionCompleteCoreDragSessionTo | RuntimeInteractionActionCompleteExtensionDragSession | RuntimeInteractionActionUpdateDragSessionCurrentTarget | RuntimeInteractionActionCancelActiveInteraction | RuntimeInteractionActionCancelInteraction;
|
|
45
59
|
export {};
|
|
@@ -1,15 +1,25 @@
|
|
|
1
|
-
import { ReadonlyDeep } from 'type-fest';
|
|
1
|
+
import type { ReadonlyDeep } from 'type-fest';
|
|
2
2
|
import type { PieceCode, Square } from '../../../state/board/types/internal.js';
|
|
3
|
+
import type { ScenePoint } from './transient-visuals.js';
|
|
3
4
|
export interface ExtensionDragSessionBase {
|
|
4
5
|
sourceSquare: Square | null;
|
|
5
6
|
sourcePieceCode: PieceCode | null;
|
|
6
7
|
targetSquare: Square | null;
|
|
7
8
|
startButton: number;
|
|
8
9
|
}
|
|
9
|
-
export interface
|
|
10
|
+
export interface ExtensionDragSessionLiftedPieceBase extends ExtensionDragSessionBase {
|
|
10
11
|
type: 'lifted-piece-drag';
|
|
11
12
|
sourcePieceCode: PieceCode;
|
|
12
13
|
}
|
|
14
|
+
export interface ExtensionDragSessionPendingLiftedPiece extends ExtensionDragSessionLiftedPieceBase {
|
|
15
|
+
phase: 'pending';
|
|
16
|
+
startPoint: ScenePoint;
|
|
17
|
+
thresholdPx: number;
|
|
18
|
+
}
|
|
19
|
+
export interface ExtensionDragSessionActiveLiftedPiece extends ExtensionDragSessionLiftedPieceBase {
|
|
20
|
+
phase: 'active';
|
|
21
|
+
}
|
|
22
|
+
export type ExtensionDragSessionLiftedPiece = ExtensionDragSessionPendingLiftedPiece | ExtensionDragSessionActiveLiftedPiece;
|
|
13
23
|
export interface ExtensionDragSessionReleaseTargeting extends ExtensionDragSessionBase {
|
|
14
24
|
type: 'release-targeting';
|
|
15
25
|
}
|
|
@@ -2,8 +2,8 @@ import { LayoutSnapshot } from '../../../layout/types.js';
|
|
|
2
2
|
import { ColorInput, MoveRequestInput, PiecePositionInput, PositionInput, SquareString } from '../../../state/board/types/input.js';
|
|
3
3
|
import { Move } from '../../../state/board/types/internal.js';
|
|
4
4
|
import { DeferredUIMoveResolutionDetails } from '../../../state/change/types/ui-move.js';
|
|
5
|
-
import { MovabilityInput } from '../../../state/interaction/types/input.js';
|
|
6
|
-
import { DragSessionExtensionOwned } from '../../../state/interaction/types/internal.js';
|
|
5
|
+
import { InteractionConfigInput, MovabilityInput } from '../../../state/interaction/types/input.js';
|
|
6
|
+
import { DragSessionExtensionOwned, InteractionConfigSnapshot } from '../../../state/interaction/types/internal.js';
|
|
7
7
|
import { RuntimeStateSnapshot } from '../../../state/types.js';
|
|
8
8
|
import { ExtensionDragSession } from '../basic/interaction.js';
|
|
9
9
|
export interface ExtensionRuntimeSurfaceCommandsSnapshot {
|
|
@@ -25,6 +25,8 @@ export interface ExtensionRuntimeSurfaceCommands {
|
|
|
25
25
|
startDrag(session: ExtensionDragSession): boolean;
|
|
26
26
|
clearActiveInteraction(): boolean;
|
|
27
27
|
clearInteraction(): boolean;
|
|
28
|
+
setInteractionConfig(config: InteractionConfigInput): boolean;
|
|
29
|
+
getInteractionConfig(): InteractionConfigSnapshot;
|
|
28
30
|
resolveDeferredUIMoveRequest(details: DeferredUIMoveResolutionDetails): Move;
|
|
29
31
|
cancelDeferredUIMoveRequest(): boolean;
|
|
30
32
|
requestRender(request: ExtensionRuntimeSurfaceCommandsRenderRequest): boolean;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
|
+
import type { MainRendererConfigPublic } from './extensions/first-party/main-renderer/types/public.js';
|
|
2
|
+
import { DefaultInteractionDesktopConfig, DefaultInteractionMobileConfig } from './state/interaction/config.js';
|
|
3
|
+
import type { InteractionConfig } from './state/interaction/types/config.js';
|
|
1
4
|
export type { ColorInput, MoveRequestInput, PiecePositionRecordString, PositionInput } from './state/board/types/input.js';
|
|
2
5
|
export type { MoveOutput } from './state/board/types/output.js';
|
|
3
6
|
export type { MovabilityInput, MoveDestinationInput } from './state/interaction/types/input.js';
|
|
4
7
|
export { createBoard } from './wrapper/factory.js';
|
|
5
8
|
export type { Chessboard, ChessboardExtensionInput, ChessboardInitOptions } from './wrapper/types.js';
|
|
9
|
+
export interface ChessboardConfig {
|
|
10
|
+
readonly interaction: InteractionConfig;
|
|
11
|
+
readonly renderer: MainRendererConfigPublic;
|
|
12
|
+
}
|
|
13
|
+
export { DefaultInteractionDesktopConfig, DefaultInteractionMobileConfig };
|
|
14
|
+
export declare const DefaultChessboardDesktopConfig: ChessboardConfig;
|
|
15
|
+
export declare const DefaultChessboardMobileConfig: ChessboardConfig;
|
package/dist/index.js
CHANGED
|
@@ -1 +1,12 @@
|
|
|
1
|
+
import { DefaultMainRendererDesktopConfig, DefaultMainRendererMobileConfig } from './extensions/index.js';
|
|
2
|
+
import { DefaultInteractionDesktopConfig, DefaultInteractionMobileConfig } from './state/interaction/config.js';
|
|
1
3
|
export { createBoard } from './wrapper/factory.js';
|
|
4
|
+
export { DefaultInteractionDesktopConfig, DefaultInteractionMobileConfig };
|
|
5
|
+
export const DefaultChessboardDesktopConfig = {
|
|
6
|
+
interaction: DefaultInteractionDesktopConfig,
|
|
7
|
+
renderer: DefaultMainRendererDesktopConfig
|
|
8
|
+
};
|
|
9
|
+
export const DefaultChessboardMobileConfig = {
|
|
10
|
+
interaction: DefaultInteractionMobileConfig,
|
|
11
|
+
renderer: DefaultMainRendererMobileConfig
|
|
12
|
+
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import assert from '@ktarmyshov/assert';
|
|
2
2
|
import { isEmptyPieceCode } from '../../state/board/check.js';
|
|
3
|
-
import { isDragSessionCoreOwned } from '../../state/interaction/helpers.js';
|
|
3
|
+
import { isDragSessionActiveLiftedPiece, isDragSessionCoreOwned, isDragSessionReleaseTargeting } from '../../state/interaction/helpers.js';
|
|
4
|
+
import { isStartPendingLiftedDragSessionInput } from '../input/controller/helpers.js';
|
|
4
5
|
import { runtimeRunMutationPipeline } from '../mutation/run.js';
|
|
5
6
|
import { uiMoveCompleteTo } from './helpers.js';
|
|
6
7
|
export function notifyExtensionCancelDragIfOwned(internalState, dragSession) {
|
|
@@ -18,68 +19,93 @@ export function createRuntimeInteractionSurface(state) {
|
|
|
18
19
|
const internalState = state();
|
|
19
20
|
return internalState.state.board.getPieceCodeAt(square);
|
|
20
21
|
},
|
|
21
|
-
|
|
22
|
+
startLiftedDragSession(input) {
|
|
22
23
|
const internalState = state();
|
|
23
24
|
const interactionMutationSession = internalState.mutation.getSession();
|
|
24
25
|
const interaction = internalState.state.interaction;
|
|
25
|
-
const pieceCode = internalState.state.board.getPieceCodeAt(
|
|
26
|
+
const pieceCode = internalState.state.board.getPieceCodeAt(input.sourceSquare);
|
|
26
27
|
assert(!isEmptyPieceCode(pieceCode), 'Cannot start a lifted-piece-drag session from an empty square');
|
|
27
28
|
const interactionSource = {
|
|
28
|
-
square:
|
|
29
|
+
square: input.sourceSquare,
|
|
29
30
|
pieceCode
|
|
30
31
|
};
|
|
31
32
|
interaction.setSelected(interactionSource, interactionMutationSession);
|
|
32
|
-
const dragSession =
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
33
|
+
const dragSession = isStartPendingLiftedDragSessionInput(input)
|
|
34
|
+
? {
|
|
35
|
+
owner: 'core',
|
|
36
|
+
type: 'lifted-piece-drag',
|
|
37
|
+
phase: 'pending',
|
|
38
|
+
sourceSquare: interactionSource.square,
|
|
39
|
+
sourcePieceCode: interactionSource.pieceCode,
|
|
40
|
+
targetSquare: input.targetSquare,
|
|
41
|
+
startButton: input.startButton,
|
|
42
|
+
startPoint: input.startPoint,
|
|
43
|
+
thresholdPx: input.thresholdPx
|
|
44
|
+
}
|
|
45
|
+
: {
|
|
46
|
+
owner: 'core',
|
|
47
|
+
type: 'lifted-piece-drag',
|
|
48
|
+
phase: 'active',
|
|
49
|
+
sourceSquare: interactionSource.square,
|
|
50
|
+
sourcePieceCode: interactionSource.pieceCode,
|
|
51
|
+
targetSquare: input.targetSquare,
|
|
52
|
+
startButton: input.startButton
|
|
53
|
+
};
|
|
40
54
|
interaction.setDragSession(dragSession, interactionMutationSession);
|
|
41
55
|
runtimeRunMutationPipeline(internalState);
|
|
42
56
|
},
|
|
57
|
+
activatePendingLiftedDragSession(input) {
|
|
58
|
+
const internalState = state();
|
|
59
|
+
const mutationSession = internalState.mutation.getSession();
|
|
60
|
+
const interaction = internalState.state.interaction;
|
|
61
|
+
interaction.activatePendingLiftedDragSession(input.targetSquare, mutationSession);
|
|
62
|
+
runtimeRunMutationPipeline(internalState);
|
|
63
|
+
},
|
|
43
64
|
transientInput(input) {
|
|
44
65
|
const internalState = state();
|
|
45
66
|
internalState.renderSystem.requestRenderVisuals(input);
|
|
46
67
|
},
|
|
47
|
-
|
|
68
|
+
completeCoreDragSessionTo(target) {
|
|
48
69
|
const internalState = state();
|
|
49
70
|
const mutationSession = internalState.mutation.getSession();
|
|
50
71
|
const interaction = internalState.state.interaction;
|
|
72
|
+
const currentDragSession = interaction.dragSession;
|
|
73
|
+
assert(currentDragSession !== null &&
|
|
74
|
+
isDragSessionCoreOwned(currentDragSession) &&
|
|
75
|
+
(isDragSessionActiveLiftedPiece(currentDragSession) ||
|
|
76
|
+
isDragSessionReleaseTargeting(currentDragSession)), 'completeCoreDragSessionTo requires a core-owned active lifted-piece or release-targeting drag session');
|
|
51
77
|
interaction.updateDragSessionCurrentTarget(target, mutationSession);
|
|
52
78
|
const dragSession = interaction.dragSession;
|
|
53
|
-
assert(isDragSessionCoreOwned(dragSession), 'completeDragTo can only be called for core-owned drag sessions');
|
|
54
79
|
uiMoveCompleteTo(internalState, target);
|
|
55
|
-
mutationSession.addMutation('runtime.interaction.
|
|
80
|
+
mutationSession.addMutation('runtime.interaction.completeCoreDragSessionTo', true, dragSession);
|
|
56
81
|
runtimeRunMutationPipeline(internalState);
|
|
57
82
|
},
|
|
58
|
-
|
|
83
|
+
completeExtensionDragSession(target) {
|
|
59
84
|
const internalState = state();
|
|
60
85
|
const mutationSession = internalState.mutation.getSession();
|
|
61
86
|
const interaction = internalState.state.interaction;
|
|
87
|
+
const currentDragSession = interaction.dragSession;
|
|
88
|
+
assert(currentDragSession !== null && !isDragSessionCoreOwned(currentDragSession), 'completeExtensionDragSession can only be called for extension-owned drag sessions');
|
|
62
89
|
interaction.updateDragSessionCurrentTarget(target, mutationSession);
|
|
63
90
|
const dragSession = interaction.dragSession;
|
|
64
|
-
assert(!isDragSessionCoreOwned(dragSession), 'completeExtensionDrag can only be called for extension-owned drag sessions');
|
|
65
91
|
internalState.extensionSystem.completeDrag(dragSession);
|
|
66
92
|
internalState.state.interaction.setDragSession(null, mutationSession);
|
|
67
|
-
mutationSession.addMutation('runtime.interaction.
|
|
93
|
+
mutationSession.addMutation('runtime.interaction.completeExtensionDragSession', true, dragSession);
|
|
68
94
|
runtimeRunMutationPipeline(internalState);
|
|
69
95
|
},
|
|
70
|
-
|
|
96
|
+
startReleaseTargetingDragSession(input) {
|
|
71
97
|
const internalState = state();
|
|
72
98
|
const mutationSession = internalState.mutation.getSession();
|
|
73
99
|
const interaction = internalState.state.interaction;
|
|
74
|
-
assert(interaction.selected !== null, '
|
|
75
|
-
assert(interaction.selected.square ===
|
|
100
|
+
assert(interaction.selected !== null, 'startReleaseTargetingDragSession requires a selected piece');
|
|
101
|
+
assert(interaction.selected.square === input.sourceSquare, 'startReleaseTargetingDragSession source must match selected square');
|
|
76
102
|
const dragSession = {
|
|
77
103
|
owner: 'core',
|
|
78
104
|
type: 'release-targeting',
|
|
79
|
-
sourceSquare:
|
|
105
|
+
sourceSquare: input.sourceSquare,
|
|
80
106
|
sourcePieceCode: interaction.selected.pieceCode,
|
|
81
|
-
targetSquare:
|
|
82
|
-
startButton
|
|
107
|
+
targetSquare: input.targetSquare,
|
|
108
|
+
startButton: input.startButton
|
|
83
109
|
};
|
|
84
110
|
interaction.setDragSession(dragSession, mutationSession);
|
|
85
111
|
runtimeRunMutationPipeline(internalState);
|
|
@@ -91,6 +91,17 @@ function createExtensionRuntimeSurfaceCommandsInternalSurface(getInternalState)
|
|
|
91
91
|
runtimeRunMutationPipeline(state);
|
|
92
92
|
return changed;
|
|
93
93
|
},
|
|
94
|
+
setInteractionConfig(config) {
|
|
95
|
+
const state = getInternalState();
|
|
96
|
+
const mutationSession = state.mutation.getSession();
|
|
97
|
+
const changed = state.state.interaction.setConfig(config, mutationSession);
|
|
98
|
+
runtimeRunMutationPipeline(state);
|
|
99
|
+
return changed;
|
|
100
|
+
},
|
|
101
|
+
getInteractionConfig() {
|
|
102
|
+
const state = getInternalState();
|
|
103
|
+
return state.state.interaction.getConfig();
|
|
104
|
+
},
|
|
94
105
|
select(square) {
|
|
95
106
|
const state = getInternalState();
|
|
96
107
|
const mutationSession = state.mutation.getSession();
|
|
@@ -19,22 +19,49 @@ export function createInteractionController(options) {
|
|
|
19
19
|
transmitTransientInput(internalState, context);
|
|
20
20
|
return; // The event has been handled by the surface (extensions)
|
|
21
21
|
}
|
|
22
|
+
else if (context.rawEvent.type === 'dragstart') {
|
|
23
|
+
// Prevent native drag-and-drop behavior to avoid conflicts with custom drag handling
|
|
24
|
+
context.rawEvent.preventDefault();
|
|
25
|
+
}
|
|
22
26
|
if (action) {
|
|
23
27
|
switch (action.type) {
|
|
24
|
-
case '
|
|
25
|
-
internalState.surface.
|
|
28
|
+
case 'startLiftedDragSession':
|
|
29
|
+
internalState.surface.startLiftedDragSession(action.phase === 'pending'
|
|
30
|
+
? {
|
|
31
|
+
phase: 'pending',
|
|
32
|
+
sourceSquare: action.sourceSquare,
|
|
33
|
+
targetSquare: action.targetSquare,
|
|
34
|
+
startButton: action.startButton,
|
|
35
|
+
startPoint: action.startPoint,
|
|
36
|
+
thresholdPx: action.thresholdPx
|
|
37
|
+
}
|
|
38
|
+
: {
|
|
39
|
+
phase: 'active',
|
|
40
|
+
sourceSquare: action.sourceSquare,
|
|
41
|
+
targetSquare: action.targetSquare,
|
|
42
|
+
startButton: action.startButton
|
|
43
|
+
});
|
|
44
|
+
break;
|
|
45
|
+
case 'activatePendingLiftedDragSession':
|
|
46
|
+
internalState.surface.activatePendingLiftedDragSession({
|
|
47
|
+
targetSquare: action.targetSquare
|
|
48
|
+
});
|
|
26
49
|
break;
|
|
27
|
-
case '
|
|
28
|
-
internalState.surface.
|
|
50
|
+
case 'startReleaseTargetingDragSession':
|
|
51
|
+
internalState.surface.startReleaseTargetingDragSession({
|
|
52
|
+
sourceSquare: action.sourceSquare,
|
|
53
|
+
targetSquare: action.targetSquare,
|
|
54
|
+
startButton: action.startButton
|
|
55
|
+
});
|
|
29
56
|
break;
|
|
30
|
-
case '
|
|
31
|
-
internalState.surface.
|
|
57
|
+
case 'completeCoreDragSessionTo':
|
|
58
|
+
internalState.surface.completeCoreDragSessionTo(action.targetSquare);
|
|
32
59
|
break;
|
|
33
|
-
case '
|
|
34
|
-
internalState.surface.
|
|
60
|
+
case 'completeExtensionDragSession':
|
|
61
|
+
internalState.surface.completeExtensionDragSession(action.targetSquare);
|
|
35
62
|
break;
|
|
36
63
|
case 'updateDragSessionCurrentTarget':
|
|
37
|
-
internalState.surface.updateDragSessionCurrentTarget(action.
|
|
64
|
+
internalState.surface.updateDragSessionCurrentTarget(action.targetSquare);
|
|
38
65
|
break;
|
|
39
66
|
case 'cancelActiveInteraction':
|
|
40
67
|
internalState.surface.cancelActiveInteraction();
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
+
import type { ScenePoint } from '../../../extensions/types/basic/transient-visuals.js';
|
|
1
2
|
import type { Square } from '../../../state/board/types/internal.js';
|
|
2
3
|
import type { InteractionStateSnapshot } from '../../../state/interaction/types/main.js';
|
|
4
|
+
import type { StartActiveLiftedDragSessionInput, StartLiftedDragSessionInput, StartPendingLiftedDragSessionInput } from './types.js';
|
|
3
5
|
export declare function buttonToButtonsMask(button: number): number | null;
|
|
4
6
|
export declare function canMoveTo(snapshot: InteractionStateSnapshot, target: Square): boolean;
|
|
7
|
+
export declare function isStartPendingLiftedDragSessionInput(input: StartLiftedDragSessionInput): input is StartPendingLiftedDragSessionInput;
|
|
8
|
+
export declare function isStartActiveLiftedDragSessionInput(input: StartLiftedDragSessionInput): input is StartActiveLiftedDragSessionInput;
|
|
9
|
+
export declare function isMovementBeyondThreshold(start: ScenePoint, current: ScenePoint, thresholdPx: number): boolean;
|
|
@@ -26,3 +26,14 @@ export function canMoveTo(snapshot, target) {
|
|
|
26
26
|
// strict: target must be in the computed active destinations
|
|
27
27
|
return snapshot.activeDestinations.has(target);
|
|
28
28
|
}
|
|
29
|
+
export function isStartPendingLiftedDragSessionInput(input) {
|
|
30
|
+
return input.phase === 'pending';
|
|
31
|
+
}
|
|
32
|
+
export function isStartActiveLiftedDragSessionInput(input) {
|
|
33
|
+
return input.phase === 'active';
|
|
34
|
+
}
|
|
35
|
+
export function isMovementBeyondThreshold(start, current, thresholdPx) {
|
|
36
|
+
const dx = current.x - start.x;
|
|
37
|
+
const dy = current.y - start.y;
|
|
38
|
+
return dx * dx + dy * dy >= thresholdPx * thresholdPx;
|
|
39
|
+
}
|