@dxos/plugin-chess 0.8.4-main.5ea62a8 → 0.8.4-main.66e292d

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 (107) hide show
  1. package/dist/lib/browser/{ChessboardContainer-HBHUXBG3.mjs → ChessboardContainer-5YXEM4VR.mjs} +20 -20
  2. package/dist/lib/browser/ChessboardContainer-5YXEM4VR.mjs.map +7 -0
  3. package/dist/lib/browser/blueprint-definition-Y5Y4YGNL.mjs +11 -0
  4. package/dist/lib/browser/{chunk-VTIITHYS.mjs → chunk-3LPE2B5J.mjs} +30 -14
  5. package/dist/lib/browser/chunk-3LPE2B5J.mjs.map +7 -0
  6. package/dist/lib/browser/{chunk-UDWRTBWA.mjs → chunk-5DOZV3PW.mjs} +113 -143
  7. package/dist/lib/browser/chunk-5DOZV3PW.mjs.map +7 -0
  8. package/dist/lib/browser/{chunk-T275KG4U.mjs → chunk-CCF24VRU.mjs} +13 -14
  9. package/dist/lib/browser/chunk-CCF24VRU.mjs.map +7 -0
  10. package/dist/lib/browser/{chunk-PE3IWOFR.mjs → chunk-DUO4WTAM.mjs} +5 -5
  11. package/dist/lib/browser/chunk-DUO4WTAM.mjs.map +7 -0
  12. package/dist/lib/browser/{chunk-H65TQTPW.mjs → chunk-Q5TZCIH7.mjs} +2 -2
  13. package/dist/lib/browser/index.mjs +30 -29
  14. package/dist/lib/browser/index.mjs.map +3 -3
  15. package/dist/lib/browser/{intent-resolver-DA5H5633.mjs → intent-resolver-KPGHK5JU.mjs} +5 -5
  16. package/dist/lib/browser/{intent-resolver-DA5H5633.mjs.map → intent-resolver-KPGHK5JU.mjs.map} +1 -1
  17. package/dist/lib/browser/meta.json +1 -1
  18. package/dist/lib/browser/{react-surface-FSDNVKZN.mjs → react-surface-3YST34QI.mjs} +7 -7
  19. package/dist/lib/browser/{react-surface-FSDNVKZN.mjs.map → react-surface-3YST34QI.mjs.map} +1 -1
  20. package/dist/lib/browser/types/index.mjs +2 -2
  21. package/dist/lib/node-esm/{ChessboardContainer-PF75AEMW.mjs → ChessboardContainer-7OQ6TOKB.mjs} +20 -20
  22. package/dist/lib/node-esm/ChessboardContainer-7OQ6TOKB.mjs.map +7 -0
  23. package/dist/lib/node-esm/blueprint-definition-GR6OLMB6.mjs +12 -0
  24. package/dist/lib/node-esm/{chunk-3NZRGOSV.mjs → chunk-F3HFLDV5.mjs} +30 -14
  25. package/dist/lib/node-esm/chunk-F3HFLDV5.mjs.map +7 -0
  26. package/dist/lib/node-esm/{chunk-PIRITYWV.mjs → chunk-F4C2HVZL.mjs} +113 -143
  27. package/dist/lib/node-esm/chunk-F4C2HVZL.mjs.map +7 -0
  28. package/dist/lib/node-esm/{chunk-6OWCPDUA.mjs → chunk-KNOOJFIR.mjs} +5 -5
  29. package/dist/lib/node-esm/chunk-KNOOJFIR.mjs.map +7 -0
  30. package/dist/lib/node-esm/{chunk-5DYLCQBR.mjs → chunk-QKXLEJNZ.mjs} +13 -14
  31. package/dist/lib/node-esm/chunk-QKXLEJNZ.mjs.map +7 -0
  32. package/dist/lib/node-esm/{chunk-IFDV434X.mjs → chunk-VVXTAVIS.mjs} +2 -2
  33. package/dist/lib/node-esm/index.mjs +30 -29
  34. package/dist/lib/node-esm/index.mjs.map +3 -3
  35. package/dist/lib/node-esm/{intent-resolver-PODONUD3.mjs → intent-resolver-ZAELGF7I.mjs} +5 -5
  36. package/dist/lib/node-esm/{intent-resolver-PODONUD3.mjs.map → intent-resolver-ZAELGF7I.mjs.map} +1 -1
  37. package/dist/lib/node-esm/meta.json +1 -1
  38. package/dist/lib/node-esm/{react-surface-2TW3PIGQ.mjs → react-surface-KV2KBSIU.mjs} +7 -7
  39. package/dist/lib/node-esm/{react-surface-2TW3PIGQ.mjs.map → react-surface-KV2KBSIU.mjs.map} +1 -1
  40. package/dist/lib/node-esm/types/index.mjs +2 -2
  41. package/dist/types/src/ChessPlugin.d.ts +1 -1
  42. package/dist/types/src/ChessPlugin.d.ts.map +1 -1
  43. package/dist/types/src/capabilities/artifact-definition.d.ts.map +1 -1
  44. package/dist/types/src/capabilities/blueprint-definition.d.ts +2 -2
  45. package/dist/types/src/capabilities/blueprint-definition.d.ts.map +1 -1
  46. package/dist/types/src/components/Card.stories.d.ts +11 -3
  47. package/dist/types/src/components/Card.stories.d.ts.map +1 -1
  48. package/dist/types/src/components/Chessboard.d.ts +11 -12
  49. package/dist/types/src/components/Chessboard.d.ts.map +1 -1
  50. package/dist/types/src/components/Chessboard.stories.d.ts +14 -9
  51. package/dist/types/src/components/Chessboard.stories.d.ts.map +1 -1
  52. package/dist/types/src/components/ChessboardArticle.d.ts +2 -1
  53. package/dist/types/src/components/ChessboardArticle.d.ts.map +1 -1
  54. package/dist/types/src/components/{ChessboardInfo.d.ts → Info.d.ts} +5 -5
  55. package/dist/types/src/components/Info.d.ts.map +1 -0
  56. package/dist/types/src/functions/create.d.ts +2 -2
  57. package/dist/types/src/functions/create.d.ts.map +1 -1
  58. package/dist/types/src/functions/move.d.ts +1 -1
  59. package/dist/types/src/functions/move.d.ts.map +1 -1
  60. package/dist/types/src/functions/play.d.ts +2 -1
  61. package/dist/types/src/functions/play.d.ts.map +1 -1
  62. package/dist/types/src/meta.d.ts +0 -1
  63. package/dist/types/src/meta.d.ts.map +1 -1
  64. package/dist/types/src/translations.d.ts +9 -6
  65. package/dist/types/src/translations.d.ts.map +1 -1
  66. package/dist/types/src/types/Chess.d.ts +3 -3
  67. package/dist/types/src/types/Chess.d.ts.map +1 -1
  68. package/dist/types/src/types/ChessAction.d.ts +1 -1
  69. package/dist/types/src/types/ChessAction.d.ts.map +1 -1
  70. package/dist/types/tsconfig.tsbuildinfo +1 -1
  71. package/package.json +42 -36
  72. package/src/ChessPlugin.tsx +45 -51
  73. package/src/capabilities/artifact-definition.ts +3 -2
  74. package/src/capabilities/blueprint-definition.ts +3 -3
  75. package/src/components/Card.stories.tsx +3 -5
  76. package/src/components/Chessboard.stories.tsx +3 -4
  77. package/src/components/Chessboard.tsx +79 -55
  78. package/src/components/ChessboardArticle.tsx +22 -18
  79. package/src/components/ChessboardContainer.tsx +1 -1
  80. package/src/components/{ChessboardInfo.tsx → Info.tsx} +103 -40
  81. package/src/functions/create.ts +4 -2
  82. package/src/functions/move.ts +4 -2
  83. package/src/functions/play.ts +13 -3
  84. package/src/meta.ts +4 -4
  85. package/src/translations.ts +9 -6
  86. package/src/types/Chess.ts +20 -28
  87. package/src/types/ChessAction.ts +1 -1
  88. package/dist/lib/browser/ChessboardContainer-HBHUXBG3.mjs.map +0 -7
  89. package/dist/lib/browser/blueprint-definition-W5PLLXPP.mjs +0 -11
  90. package/dist/lib/browser/chunk-PE3IWOFR.mjs.map +0 -7
  91. package/dist/lib/browser/chunk-T275KG4U.mjs.map +0 -7
  92. package/dist/lib/browser/chunk-UDWRTBWA.mjs.map +0 -7
  93. package/dist/lib/browser/chunk-VTIITHYS.mjs.map +0 -7
  94. package/dist/lib/node-esm/ChessboardContainer-PF75AEMW.mjs.map +0 -7
  95. package/dist/lib/node-esm/blueprint-definition-PR5YZC6M.mjs +0 -12
  96. package/dist/lib/node-esm/chunk-3NZRGOSV.mjs.map +0 -7
  97. package/dist/lib/node-esm/chunk-5DYLCQBR.mjs.map +0 -7
  98. package/dist/lib/node-esm/chunk-6OWCPDUA.mjs.map +0 -7
  99. package/dist/lib/node-esm/chunk-PIRITYWV.mjs.map +0 -7
  100. package/dist/types/src/components/ChessboardInfo.d.ts.map +0 -1
  101. package/dist/types/src/components/ChessboardPlayers.d.ts +0 -8
  102. package/dist/types/src/components/ChessboardPlayers.d.ts.map +0 -1
  103. package/src/components/ChessboardPlayers.tsx +0 -98
  104. /package/dist/lib/browser/{blueprint-definition-W5PLLXPP.mjs.map → blueprint-definition-Y5Y4YGNL.mjs.map} +0 -0
  105. /package/dist/lib/browser/{chunk-H65TQTPW.mjs.map → chunk-Q5TZCIH7.mjs.map} +0 -0
  106. /package/dist/lib/node-esm/{blueprint-definition-PR5YZC6M.mjs.map → blueprint-definition-GR6OLMB6.mjs.map} +0 -0
  107. /package/dist/lib/node-esm/{chunk-IFDV434X.mjs.map → chunk-VVXTAVIS.mjs.map} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/plugin-chess",
3
- "version": "0.8.4-main.5ea62a8",
3
+ "version": "0.8.4-main.66e292d",
4
4
  "description": "Chess for new plugin",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -20,6 +20,12 @@
20
20
  "types": "./dist/types/src/types/index.d.ts",
21
21
  "browser": "./dist/lib/browser/types/index.mjs",
22
22
  "node": "./dist/lib/node-esm/types/index.mjs"
23
+ },
24
+ "./functions": {
25
+ "source": "./src/functions/index.ts",
26
+ "types": "./dist/types/src/functions/index.d.ts",
27
+ "browser": "./dist/lib/browser/functions/index.mjs",
28
+ "node": "./dist/lib/node-esm/functions/index.mjs"
23
29
  }
24
30
  },
25
31
  "types": "dist/types/src/index.d.ts",
@@ -36,46 +42,46 @@
36
42
  ],
37
43
  "dependencies": {
38
44
  "@preact-signals/safe-react": "^0.9.0",
39
- "@preact/signals-core": "^1.9.0",
45
+ "@preact/signals-core": "^1.12.1",
40
46
  "chess.js": "^1.0.0",
41
- "effect": "3.17.7",
42
- "@dxos/ai": "0.8.4-main.5ea62a8",
43
- "@dxos/app-framework": "0.8.4-main.5ea62a8",
44
- "@dxos/assistant": "0.8.4-main.5ea62a8",
45
- "@dxos/display-name": "0.8.4-main.5ea62a8",
46
- "@dxos/blueprints": "0.8.4-main.5ea62a8",
47
- "@dxos/async": "0.8.4-main.5ea62a8",
48
- "@dxos/echo": "0.8.4-main.5ea62a8",
49
- "@dxos/echo-schema": "0.8.4-main.5ea62a8",
50
- "@dxos/functions": "0.8.4-main.5ea62a8",
51
- "@dxos/live-object": "0.8.4-main.5ea62a8",
52
- "@dxos/plugin-client": "0.8.4-main.5ea62a8",
53
- "@dxos/log": "0.8.4-main.5ea62a8",
54
- "@dxos/plugin-graph": "0.8.4-main.5ea62a8",
55
- "@dxos/plugin-space": "0.8.4-main.5ea62a8",
56
- "@dxos/react-client": "0.8.4-main.5ea62a8",
57
- "@dxos/react-ui-gameboard": "0.8.4-main.5ea62a8",
58
- "@dxos/react-ui-stack": "0.8.4-main.5ea62a8",
59
- "@dxos/schema": "0.8.4-main.5ea62a8",
60
- "@dxos/util": "0.8.4-main.5ea62a8",
61
- "@dxos/invariant": "0.8.4-main.5ea62a8"
47
+ "effect": "3.18.3",
48
+ "@dxos/ai": "0.8.4-main.66e292d",
49
+ "@dxos/assistant": "0.8.4-main.66e292d",
50
+ "@dxos/async": "0.8.4-main.66e292d",
51
+ "@dxos/blueprints": "0.8.4-main.66e292d",
52
+ "@dxos/display-name": "0.8.4-main.66e292d",
53
+ "@dxos/invariant": "0.8.4-main.66e292d",
54
+ "@dxos/echo": "0.8.4-main.66e292d",
55
+ "@dxos/functions": "0.8.4-main.66e292d",
56
+ "@dxos/live-object": "0.8.4-main.66e292d",
57
+ "@dxos/plugin-client": "0.8.4-main.66e292d",
58
+ "@dxos/plugin-graph": "0.8.4-main.66e292d",
59
+ "@dxos/log": "0.8.4-main.66e292d",
60
+ "@dxos/plugin-space": "0.8.4-main.66e292d",
61
+ "@dxos/react-client": "0.8.4-main.66e292d",
62
+ "@dxos/react-ui-gameboard": "0.8.4-main.66e292d",
63
+ "@dxos/react-ui-sfx": "0.8.4-main.66e292d",
64
+ "@dxos/react-ui-stack": "0.8.4-main.66e292d",
65
+ "@dxos/schema": "0.8.4-main.66e292d",
66
+ "@dxos/util": "0.8.4-main.66e292d",
67
+ "@dxos/app-framework": "0.8.4-main.66e292d"
62
68
  },
63
69
  "devDependencies": {
64
- "@types/react": "~18.2.0",
65
- "@types/react-dom": "~18.2.0",
66
- "react": "~18.2.0",
67
- "react-dom": "~18.2.0",
68
- "vite": "7.1.1",
69
- "@dxos/plugin-theme": "0.8.4-main.5ea62a8",
70
- "@dxos/react-ui-theme": "0.8.4-main.5ea62a8",
71
- "@dxos/storybook-utils": "0.8.4-main.5ea62a8",
72
- "@dxos/react-ui": "0.8.4-main.5ea62a8"
70
+ "@types/react": "~19.2.2",
71
+ "@types/react-dom": "~19.2.2",
72
+ "react": "~19.2.0",
73
+ "react-dom": "~19.2.0",
74
+ "vite": "7.1.9",
75
+ "@dxos/plugin-theme": "0.8.4-main.66e292d",
76
+ "@dxos/react-ui-theme": "0.8.4-main.66e292d",
77
+ "@dxos/react-ui": "0.8.4-main.66e292d",
78
+ "@dxos/storybook-utils": "0.8.4-main.66e292d"
73
79
  },
74
80
  "peerDependencies": {
75
- "react": "~18.2.0",
76
- "react-dom": "~18.2.0",
77
- "@dxos/react-ui": "0.8.4-main.5ea62a8",
78
- "@dxos/react-ui-theme": "0.8.4-main.5ea62a8"
81
+ "react": "^19.0.0",
82
+ "react-dom": "^19.0.0",
83
+ "@dxos/react-ui": "0.8.4-main.66e292d",
84
+ "@dxos/react-ui-theme": "0.8.4-main.66e292d"
79
85
  },
80
86
  "publishConfig": {
81
87
  "access": "public"
@@ -3,59 +3,53 @@
3
3
  //
4
4
 
5
5
  import { Capabilities, Events, contributes, createIntent, defineModule, definePlugin } from '@dxos/app-framework';
6
- import { ClientEvents } from '@dxos/plugin-client';
7
- import { SpaceCapabilities } from '@dxos/plugin-space';
8
- import { defineObjectForm } from '@dxos/plugin-space/types';
6
+ import { ClientCapabilities, ClientEvents } from '@dxos/plugin-client';
7
+ import { type CreateObjectIntent } from '@dxos/plugin-space/types';
9
8
 
10
- import { BLUEPRINT_KEY, BlueprintDefinition, IntentResolver, ReactSurface } from './capabilities';
9
+ import { BlueprintDefinition, CHESS_BLUEPRINT_KEY, IntentResolver, ReactSurface } from './capabilities';
11
10
  import { meta } from './meta';
12
11
  import { translations } from './translations';
13
12
  import { Chess, ChessAction } from './types';
14
13
 
15
- export const ChessPlugin = () =>
16
- definePlugin(meta, [
17
- defineModule({
18
- id: `${meta.id}/module/translations`,
19
- activatesOn: Events.SetupTranslations,
20
- activate: () => contributes(Capabilities.Translations, translations),
21
- }),
22
- defineModule({
23
- id: `${meta.id}/module/metadata`,
24
- activatesOn: Events.SetupMetadata,
25
- activate: () =>
26
- contributes(Capabilities.Metadata, {
27
- id: Chess.Game.typename,
28
- metadata: {
29
- icon: 'ph--shield-chevron--regular',
30
- blueprints: [BLUEPRINT_KEY],
31
- },
32
- }),
33
- }),
34
- defineModule({
35
- id: `${meta.id}/module/object-form`,
36
- activatesOn: ClientEvents.SetupSchema,
37
- activate: () =>
38
- contributes(
39
- SpaceCapabilities.ObjectForm,
40
- defineObjectForm({
41
- objectSchema: Chess.Game,
42
- getIntent: () => createIntent(ChessAction.Create),
43
- }),
44
- ),
45
- }),
46
- defineModule({
47
- id: `${meta.id}/module/react-surface`,
48
- activatesOn: Events.SetupReactSurface,
49
- activate: ReactSurface,
50
- }),
51
- defineModule({
52
- id: `${meta.id}/module/intent-resolver`,
53
- activatesOn: Events.SetupIntentResolver,
54
- activate: IntentResolver,
55
- }),
56
- defineModule({
57
- id: `${meta.id}/module/blueprint`,
58
- activatesOn: Events.SetupArtifactDefinition,
59
- activate: BlueprintDefinition,
60
- }),
61
- ]);
14
+ export const ChessPlugin = definePlugin(meta, () => [
15
+ defineModule({
16
+ id: `${meta.id}/module/translations`,
17
+ activatesOn: Events.SetupTranslations,
18
+ activate: () => contributes(Capabilities.Translations, translations),
19
+ }),
20
+ defineModule({
21
+ id: `${meta.id}/module/metadata`,
22
+ activatesOn: Events.SetupMetadata,
23
+ activate: () =>
24
+ contributes(Capabilities.Metadata, {
25
+ id: Chess.Game.typename,
26
+ metadata: {
27
+ icon: 'ph--shield-chevron--regular',
28
+ iconHue: 'amber',
29
+ blueprints: [CHESS_BLUEPRINT_KEY],
30
+ createObjectIntent: (() => createIntent(ChessAction.Create)) satisfies CreateObjectIntent,
31
+ addToCollectionOnCreate: true,
32
+ },
33
+ }),
34
+ }),
35
+ defineModule({
36
+ id: `${meta.id}/module/schema`,
37
+ activatesOn: ClientEvents.SetupSchema,
38
+ activate: () => contributes(ClientCapabilities.Schema, [Chess.Game]),
39
+ }),
40
+ defineModule({
41
+ id: `${meta.id}/module/react-surface`,
42
+ activatesOn: Events.SetupReactSurface,
43
+ activate: ReactSurface,
44
+ }),
45
+ defineModule({
46
+ id: `${meta.id}/module/intent-resolver`,
47
+ activatesOn: Events.SetupIntentResolver,
48
+ activate: IntentResolver,
49
+ }),
50
+ defineModule({
51
+ id: `${meta.id}/module/blueprint`,
52
+ activatesOn: Events.SetupArtifactDefinition,
53
+ activate: BlueprintDefinition,
54
+ }),
55
+ ]);
@@ -6,7 +6,8 @@
6
6
  // @ts-nocheck
7
7
 
8
8
  import { Chess as ChessJS } from 'chess.js';
9
- import { Schema, pipe } from 'effect';
9
+ import * as Function from 'effect/Function';
10
+ import * as Schema from 'effect/Schema';
10
11
 
11
12
  import { ToolResult, createTool } from '@dxos/ai';
12
13
  import { Capabilities, type PromiseIntentDispatcher, chain, contributes, createIntent } from '@dxos/app-framework';
@@ -50,7 +51,7 @@ export default () => {
50
51
  execute: async ({ pgn }, { extensions }) => {
51
52
  invariant(extensions?.space, 'No space');
52
53
  invariant(extensions?.dispatch, 'No intent dispatcher');
53
- const intent = pipe(
54
+ const intent = Function.pipe(
54
55
  createIntent(ChessAction.Create, { pgn }),
55
56
  chain(SpaceAction.AddObject, { target: extensions.space }),
56
57
  );
@@ -9,17 +9,17 @@ import { trim } from '@dxos/util';
9
9
 
10
10
  import { create, move, play } from '../functions';
11
11
 
12
- export const BLUEPRINT_KEY = 'dxos.org/blueprint/chess';
13
-
14
12
  const functions: FunctionDefinition[] = [create, move, play];
15
13
 
14
+ export const CHESS_BLUEPRINT_KEY = 'dxos.org/blueprint/chess';
15
+
16
16
  export default () => {
17
17
  return [
18
18
  contributes(Capabilities.Functions, functions),
19
19
  contributes(
20
20
  Capabilities.BlueprintDefinition,
21
21
  Blueprint.make({
22
- key: BLUEPRINT_KEY,
22
+ key: CHESS_BLUEPRINT_KEY,
23
23
  name: 'Chess',
24
24
  tools: Blueprint.toolDefinitions({ functions }),
25
25
  instructions: Template.make({
@@ -2,13 +2,11 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import '@dxos-theme';
6
-
7
5
  import { type Meta, type StoryObj } from '@storybook/react-vite';
8
6
  import React from 'react';
9
7
 
8
+ import { withTheme } from '@dxos/react-ui/testing';
10
9
  import { CardContainer } from '@dxos/react-ui-stack/testing';
11
- import { withTheme } from '@dxos/storybook-utils';
12
10
 
13
11
  import { meta as pluginMeta } from '../meta';
14
12
  import { Chess } from '../types';
@@ -20,7 +18,7 @@ type DefaultStoryProps = {
20
18
  game: Chess.Game;
21
19
  };
22
20
 
23
- const meta: Meta<DefaultStoryProps> = {
21
+ const meta = {
24
22
  title: 'plugins/plugin-chess/Card',
25
23
  render: ({ role, game }) => (
26
24
  <CardContainer icon={pluginMeta.icon} role={role}>
@@ -36,7 +34,7 @@ const meta: Meta<DefaultStoryProps> = {
36
34
  layout: 'centered',
37
35
  },
38
36
  tags: ['cards'],
39
- };
37
+ } satisfies Meta<DefaultStoryProps>;
40
38
 
41
39
  export default meta;
42
40
 
@@ -2,12 +2,10 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import '@dxos-theme';
6
-
7
5
  import { type Meta, type StoryObj } from '@storybook/react-vite';
8
6
 
9
7
  import { withClientProvider } from '@dxos/react-client/testing';
10
- import { withLayout, withTheme } from '@dxos/storybook-utils';
8
+ import { withTheme } from '@dxos/react-ui/testing';
11
9
 
12
10
  import { translations } from '../translations';
13
11
  import { Chess } from '../types';
@@ -17,8 +15,9 @@ import { ChessboardArticle } from './ChessboardArticle';
17
15
  const meta = {
18
16
  title: 'plugins/plugin-chess/Chessboard',
19
17
  component: ChessboardArticle,
20
- decorators: [withClientProvider({ createIdentity: true }), withTheme, withLayout({ fullscreen: true })],
18
+ decorators: [withTheme, withClientProvider({ createIdentity: true })],
21
19
  parameters: {
20
+ layout: 'fullscreen',
22
21
  translations,
23
22
  },
24
23
  } satisfies Meta<typeof ChessboardArticle>;
@@ -18,15 +18,17 @@ import {
18
18
  ChessModel,
19
19
  Gameboard,
20
20
  type GameboardRootProps,
21
- Chessboard as NativeChessboard,
22
- type ChessboardProps as NativeChessboardProps,
21
+ Chessboard as NaturalChessboard,
22
+ type ChessboardProps as NaturalChessboardProps,
23
+ getRawPgn,
24
+ useGameboardContext,
23
25
  } from '@dxos/react-ui-gameboard';
26
+ import { useSoundEffect } from '@dxos/react-ui-sfx';
24
27
  import { mx } from '@dxos/react-ui-theme';
25
28
 
26
29
  import { type Chess } from '../types';
27
30
 
28
- import { ChessboardInfo, type ChessboardInfoProps } from './ChessboardInfo';
29
- import { ChessboardPlayers, type ChessboardPlayersProps } from './ChessboardPlayers';
31
+ import { Info, type InfoProps } from './Info';
30
32
 
31
33
  export interface ChessboardController {
32
34
  setMoveNumber(index: number): void;
@@ -42,12 +44,13 @@ export class ExtendedChessModel extends ChessModel {
42
44
  // Root
43
45
  //
44
46
 
45
- type ChessboardRootProps = PropsWithChildren<{
47
+ type RootProps = PropsWithChildren<{
46
48
  game: Chess.Game;
47
49
  }>;
48
50
 
49
- const ChessboardRoot = forwardRef<ChessboardController, ChessboardRootProps>(({ game, children }, forwardedRef) => {
51
+ const Root = forwardRef<ChessboardController, RootProps>(({ game, children }, forwardedRef) => {
50
52
  const model = useMemo(() => new ExtendedChessModel(game), []);
53
+ const click = useSoundEffect('Click');
51
54
 
52
55
  // Controller.
53
56
  useImperativeHandle(forwardedRef, () => {
@@ -57,57 +60,34 @@ const ChessboardRoot = forwardRef<ChessboardController, ChessboardRootProps>(({
57
60
  }, [model]);
58
61
 
59
62
  // External change.
63
+ // NOTE: Warning if user has not interacted with the board.
60
64
  useEffect(() => {
61
- model.update(game.pgn);
62
- }, [game.pgn]);
63
-
64
- // Keyboard navigation.
65
- const ref = useRef<HTMLDivElement>(null);
66
- useEffect(() => {
67
- if (!ref.current) {
68
- return;
69
- }
70
-
71
- return addEventListener(ref.current, 'keydown', (ev) => {
72
- switch (ev.key) {
73
- case 'ArrowUp':
74
- model.setMoveIndex(0);
75
- break;
76
- case 'ArrowDown':
77
- model.setMoveIndex(model.game.history().length);
78
- break;
79
- case 'ArrowLeft':
80
- if (model.moveIndex.value > 0) {
81
- model.setMoveIndex(model.moveIndex.value - 1);
82
- }
83
- break;
84
- case 'ArrowRight':
85
- if (model.moveIndex.value < model.game.history().length) {
86
- model.setMoveIndex(model.moveIndex.value + 1);
87
- }
88
- break;
65
+ if (model.pgn !== getRawPgn(game.pgn ?? '')) {
66
+ const silent = model.pgn === '*';
67
+ model.update(game.pgn);
68
+ if (!silent) {
69
+ void click.play();
89
70
  }
90
- });
91
- }, [model]);
71
+ }
72
+ }, [game.pgn]);
92
73
 
93
74
  // Move.
94
75
  const handleDrop = useCallback<NonNullable<GameboardRootProps<ChessModel>['onDrop']>>(
95
76
  (move) => {
96
- if (model.makeMove(move)) {
97
- game.pgn = model.pgn;
98
- return true;
77
+ if (!model.makeMove(move)) {
78
+ return false;
99
79
  }
100
80
 
101
- return false;
81
+ void click.play();
82
+ game.pgn = model.pgn;
83
+ return true;
102
84
  },
103
85
  [model],
104
86
  );
105
87
 
106
88
  return (
107
89
  <Gameboard.Root model={model} onDrop={handleDrop}>
108
- <div ref={ref} role='none' tabIndex={0} className='grid grow outline-none'>
109
- {children}
110
- </div>
90
+ {children}
111
91
  </Gameboard.Root>
112
92
  );
113
93
  });
@@ -118,9 +98,9 @@ const ChessboardRoot = forwardRef<ChessboardController, ChessboardRootProps>(({
118
98
 
119
99
  type Role = 'card--popover' | 'card--intrinsic' | 'card--extrinsic';
120
100
 
121
- type ChessboardContentProps = ThemedClassName<PropsWithChildren<{ role?: Role }>>;
101
+ type ContentProps = ThemedClassName<PropsWithChildren<{ role?: Role }>>;
122
102
 
123
- const ChessboardContent = ({ classNames, children, role }: ChessboardContentProps) => {
103
+ const Content = ({ classNames, children, role }: ContentProps) => {
124
104
  return (
125
105
  <Gameboard.Content
126
106
  classNames={mx(classNames, role === 'card--popover' && 'size-container popover-square')}
@@ -132,22 +112,66 @@ const ChessboardContent = ({ classNames, children, role }: ChessboardContentProp
132
112
  );
133
113
  };
134
114
 
115
+ //
116
+ // Board
117
+ //
118
+
119
+ type BoardProps = NaturalChessboardProps;
120
+
121
+ const Board = (props: BoardProps) => {
122
+ const { model } = useGameboardContext<ChessModel>(Board.displayName);
123
+
124
+ // Keyboard navigation.
125
+ const ref = useRef<HTMLDivElement>(null);
126
+ useEffect(() => {
127
+ if (!ref.current) {
128
+ return;
129
+ }
130
+
131
+ // Participate in keyboard navigation (set tabIndex={0})
132
+ ref.current.setAttribute('data-arrow-keys', 'all');
133
+
134
+ return addEventListener(ref.current, 'keydown', (ev) => {
135
+ switch (ev.key) {
136
+ case 'ArrowUp':
137
+ model.setMoveIndex(0);
138
+ break;
139
+ case 'ArrowDown':
140
+ model.setMoveIndex(model.game.history().length);
141
+ break;
142
+ case 'ArrowLeft':
143
+ if (model.moveIndex.value > 0) {
144
+ model.setMoveIndex(model.moveIndex.value - 1);
145
+ }
146
+ break;
147
+ case 'ArrowRight':
148
+ if (model.moveIndex.value < model.game.history().length) {
149
+ model.setMoveIndex(model.moveIndex.value + 1);
150
+ }
151
+ break;
152
+ }
153
+ });
154
+ }, [model]);
155
+
156
+ return <NaturalChessboard ref={ref} {...props} />;
157
+ };
158
+
159
+ Board.displayName = 'Chessboard.Board';
160
+
135
161
  //
136
162
  // Chessboard
137
163
  //
138
164
 
139
165
  export const Chessboard = {
140
- Root: ChessboardRoot,
141
- Content: ChessboardContent,
142
- Board: NativeChessboard,
143
- Info: ChessboardInfo,
144
- Players: ChessboardPlayers,
166
+ Root: Root,
167
+ Content: Content,
168
+ Board: Board,
169
+ Info: Info,
145
170
  };
146
171
 
147
172
  export type {
148
- ChessboardRootProps,
149
- ChessboardContentProps,
150
- NativeChessboardProps as ChessboardBoardProps,
151
- ChessboardInfoProps,
152
- ChessboardPlayersProps,
173
+ RootProps as ChessboardRootProps,
174
+ ContentProps as ChessboardContentProps,
175
+ BoardProps as ChessboardBoardProps,
176
+ InfoProps as ChessboardInfoProps,
153
177
  };
@@ -4,7 +4,7 @@
4
4
 
5
5
  import React, { useCallback, useRef, useState } from 'react';
6
6
 
7
- import { IconButton, useTranslation } from '@dxos/react-ui';
7
+ import { Toolbar, useTranslation } from '@dxos/react-ui';
8
8
  import { type Player } from '@dxos/react-ui-gameboard';
9
9
  import { StackItem } from '@dxos/react-ui-stack';
10
10
  import { mx } from '@dxos/react-ui-theme';
@@ -14,7 +14,7 @@ import { type Chess } from '../types';
14
14
 
15
15
  import { Chessboard, type ChessboardController, type ChessboardInfoProps } from './Chessboard';
16
16
 
17
- export const ChessboardArticle = ({ game }: { game: Chess.Game }) => {
17
+ export const ChessboardArticle = ({ game, role }: { game: Chess.Game; role?: string }) => {
18
18
  const { t } = useTranslation(meta.id);
19
19
  const [orientation, setOrientation] = useState<Player>('white');
20
20
  const [open, setOpen] = useState(true);
@@ -26,11 +26,28 @@ export const ChessboardArticle = ({ game }: { game: Chess.Game }) => {
26
26
  }, []);
27
27
 
28
28
  return (
29
- <StackItem.Content classNames='@container bs-full is-full overflow-hidden'>
29
+ <StackItem.Content toolbar classNames='@container'>
30
30
  <Chessboard.Root game={game} ref={controller}>
31
- <div className={mx('grid grid-rows-[1fr_4rem] bs-full is-full gap-2', open && '@3xl:grid-cols-[1fr_320px]')}>
31
+ <Toolbar.Root>
32
+ <Toolbar.IconButton
33
+ icon='ph--info--regular'
34
+ iconOnly
35
+ label={t('toggle info button')}
36
+ disabled={open}
37
+ classNames={mx('invisible @3xl:visible')}
38
+ onClick={() => setOpen((open) => !open)}
39
+ />
40
+ </Toolbar.Root>
41
+ <div
42
+ className={mx(
43
+ 'grid bs-full is-full gap-2',
44
+ open && '@3xl:grid-cols-[1fr_320px]',
45
+ role === 'section' && 'aspect-square',
46
+ role === 'section' && open && '@3xl:aspect-auto',
47
+ )}
48
+ >
32
49
  <Chessboard.Content>
33
- <Chessboard.Board orientation={orientation} />
50
+ <Chessboard.Board classNames='m-4 rounded-sm overflow-hidden' orientation={orientation} />
34
51
  </Chessboard.Content>
35
52
  {open && (
36
53
  <div className='hidden @3xl:flex flex-col p-8 justify-center items-center overflow-hidden'>
@@ -44,19 +61,6 @@ export const ChessboardArticle = ({ game }: { game: Chess.Game }) => {
44
61
  />
45
62
  </div>
46
63
  )}
47
- <div className='flex justify-center items-center'>
48
- <Chessboard.Players>
49
- <IconButton
50
- variant='ghost'
51
- icon='ph--info--regular'
52
- iconOnly
53
- label={t('button toggle info')}
54
- size={6}
55
- classNames={mx('invisible', !open && '@3xl:visible')}
56
- onClick={() => setOpen((open) => !open)}
57
- />
58
- </Chessboard.Players>
59
- </div>
60
64
  </div>
61
65
  </Chessboard.Root>
62
66
  </StackItem.Content>
@@ -36,7 +36,7 @@ export const ChessboardContainer = ({ game, role }: ChessboardContainerProps) =>
36
36
  }
37
37
 
38
38
  default: {
39
- return <ChessboardArticle game={game} />;
39
+ return <ChessboardArticle game={game} role={role} />;
40
40
  }
41
41
  }
42
42
  };