@scriptonita/chess-football-ui 0.3.0 → 0.4.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/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode } from 'react';
3
- import { Side, Piece } from '@scriptonita/chess-football-engine';
3
+ import { Side, Piece, PieceShortKey, PieceLongKey } from '@scriptonita/chess-football-engine';
4
4
  import { ClassValue } from 'clsx';
5
5
 
6
6
  interface GameBoardProps {
@@ -78,7 +78,7 @@ declare function StaticGameBoard(): react.JSX.Element;
78
78
 
79
79
  interface TurnBannerProps {
80
80
  isMyTurn: boolean;
81
- /** Override for the "not my turn" label (e.g. "IA pensando…" in training mode). */
81
+ /** Override for the "not my turn" label (e.g. "Bot pensando…" in training mode). */
82
82
  waitingLabel?: string;
83
83
  className?: string;
84
84
  }
@@ -87,7 +87,7 @@ interface TurnBannerProps {
87
87
  * - My turn: accent-green background + "TU TURNO" + AP counter
88
88
  * - Opponent: neutral background + waiting label
89
89
  *
90
- * Absorbs the floating "IA pensando…" toast in training mode when waitingLabel is set.
90
+ * Absorbs the floating "Bot pensando…" toast in training mode when waitingLabel is set.
91
91
  */
92
92
  declare function TurnBanner({ isMyTurn, waitingLabel, className }: TurnBannerProps): react.JSX.Element | null;
93
93
 
@@ -147,12 +147,33 @@ interface ConfirmDialogProps {
147
147
  declare function ConfirmDialog({ open, title, description, confirmLabel, cancelLabel, onConfirm, onCancel }: ConfirmDialogProps): react.JSX.Element | null;
148
148
 
149
149
  /**
150
- * A translator scoped to the `game` namespace: `t('turn')`, `t('whiteToMove')`, …
150
+ * A translator scoped to the `game` namespace: `t('yourTurn')`, `t('move')`, …
151
151
  * Each host app supplies one bound to its own i18n library:
152
152
  * - Next.js (next-intl): const t = useTranslations('game')
153
153
  * - Vite (react-i18next): (key) => t(`game.${key}`)
154
154
  */
155
155
  type GameTranslator = (key: string, values?: Record<string, unknown>) => string;
156
+ /**
157
+ * Static leaf keys the package's components read via `useGameT` with a literal `t('…')` call.
158
+ * Keep in sync with those call sites — recipe:
159
+ * grep -rhoE "t\('[a-zA-Z0-9_.]+'" src/components | sed -E "s/t\('//;s/'//" | sort -u
160
+ * (the dynamic `pieces.*` / `eventToast.*` families are derived separately below).
161
+ */
162
+ declare const STATIC_I18N_KEYS: readonly ["actionPointsAriaLabel", "actionPointsShort", "endTurn", "endTurnConfirm", "endTurnConfirmDescription", "endTurnConfirmYes", "endTurnKeepPlaying", "history.empty", "history.goal", "history.interception", "history.move", "history.offside", "history.pass", "history.tackle", "history.title", "history.turn", "history.viewAll", "move", "offsideWarning", "pass", "selectedPiece.alreadyMoved", "selectedPiece.atSquare", "selectedPiece.empty", "selectedPiece.hasBall", "teamBlack", "teamWhite", "waitingRival", "yourTurn"];
163
+ /** `pieces.*` — one key per short and long piece label the engine exposes (move-history, selected-piece-detail). */
164
+ type PieceI18nKey = `pieces.${PieceShortKey | PieceLongKey}`;
165
+ /** `eventToast.*` — one key per toastable event (see `ToastEvent` in `event-toast.tsx`). */
166
+ type EventToastI18nKey = `eventToast.${'interception' | 'offside' | 'tackle'}`;
167
+ /** Union of every `game`-namespace key the package reads. */
168
+ type GameI18nKey = (typeof STATIC_I18N_KEYS)[number] | PieceI18nKey | EventToastI18nKey;
169
+ /**
170
+ * Manifest of every `game`-namespace key the package's components read via `useGameT`.
171
+ * Host apps use it to assert their translation catalogs cover the package (AD-4).
172
+ * The `pieces.*` family is derived from the engine's `SHORT_KEY`/`LONG_KEY` so it can't
173
+ * drift when a piece is added; static keys and `eventToast.*` are listed above.
174
+ * No key names an automated-opponent brand — the roster owns opponent identity.
175
+ */
176
+ declare const GAME_I18N_KEYS: readonly GameI18nKey[];
156
177
  declare function GameI18nProvider({ t, children }: {
157
178
  t: GameTranslator;
158
179
  children: ReactNode;
@@ -162,4 +183,4 @@ declare function useGameT(): GameTranslator;
162
183
 
163
184
  declare function cn(...inputs: ClassValue[]): string;
164
185
 
165
- export { ActionPoints, Avatar, AvatarFallback, AvatarImage, Button, type ButtonProps, ConfirmDialog, EventToast, Football, GameBoard, GameControls, GameI18nProvider, GamePiece, type GameTranslator, MiniScoreboard, MobileHistory, MoveHistory, Scoreboard, SelectedPieceDetail, StaticGameBoard, TurnBanner, cn, useGameT };
186
+ export { ActionPoints, Avatar, AvatarFallback, AvatarImage, Button, type ButtonProps, ConfirmDialog, EventToast, Football, GAME_I18N_KEYS, GameBoard, GameControls, type GameI18nKey, GameI18nProvider, GamePiece, type GameTranslator, MiniScoreboard, MobileHistory, MoveHistory, Scoreboard, SelectedPieceDetail, StaticGameBoard, TurnBanner, cn, useGameT };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode } from 'react';
3
- import { Side, Piece } from '@scriptonita/chess-football-engine';
3
+ import { Side, Piece, PieceShortKey, PieceLongKey } from '@scriptonita/chess-football-engine';
4
4
  import { ClassValue } from 'clsx';
5
5
 
6
6
  interface GameBoardProps {
@@ -78,7 +78,7 @@ declare function StaticGameBoard(): react.JSX.Element;
78
78
 
79
79
  interface TurnBannerProps {
80
80
  isMyTurn: boolean;
81
- /** Override for the "not my turn" label (e.g. "IA pensando…" in training mode). */
81
+ /** Override for the "not my turn" label (e.g. "Bot pensando…" in training mode). */
82
82
  waitingLabel?: string;
83
83
  className?: string;
84
84
  }
@@ -87,7 +87,7 @@ interface TurnBannerProps {
87
87
  * - My turn: accent-green background + "TU TURNO" + AP counter
88
88
  * - Opponent: neutral background + waiting label
89
89
  *
90
- * Absorbs the floating "IA pensando…" toast in training mode when waitingLabel is set.
90
+ * Absorbs the floating "Bot pensando…" toast in training mode when waitingLabel is set.
91
91
  */
92
92
  declare function TurnBanner({ isMyTurn, waitingLabel, className }: TurnBannerProps): react.JSX.Element | null;
93
93
 
@@ -147,12 +147,33 @@ interface ConfirmDialogProps {
147
147
  declare function ConfirmDialog({ open, title, description, confirmLabel, cancelLabel, onConfirm, onCancel }: ConfirmDialogProps): react.JSX.Element | null;
148
148
 
149
149
  /**
150
- * A translator scoped to the `game` namespace: `t('turn')`, `t('whiteToMove')`, …
150
+ * A translator scoped to the `game` namespace: `t('yourTurn')`, `t('move')`, …
151
151
  * Each host app supplies one bound to its own i18n library:
152
152
  * - Next.js (next-intl): const t = useTranslations('game')
153
153
  * - Vite (react-i18next): (key) => t(`game.${key}`)
154
154
  */
155
155
  type GameTranslator = (key: string, values?: Record<string, unknown>) => string;
156
+ /**
157
+ * Static leaf keys the package's components read via `useGameT` with a literal `t('…')` call.
158
+ * Keep in sync with those call sites — recipe:
159
+ * grep -rhoE "t\('[a-zA-Z0-9_.]+'" src/components | sed -E "s/t\('//;s/'//" | sort -u
160
+ * (the dynamic `pieces.*` / `eventToast.*` families are derived separately below).
161
+ */
162
+ declare const STATIC_I18N_KEYS: readonly ["actionPointsAriaLabel", "actionPointsShort", "endTurn", "endTurnConfirm", "endTurnConfirmDescription", "endTurnConfirmYes", "endTurnKeepPlaying", "history.empty", "history.goal", "history.interception", "history.move", "history.offside", "history.pass", "history.tackle", "history.title", "history.turn", "history.viewAll", "move", "offsideWarning", "pass", "selectedPiece.alreadyMoved", "selectedPiece.atSquare", "selectedPiece.empty", "selectedPiece.hasBall", "teamBlack", "teamWhite", "waitingRival", "yourTurn"];
163
+ /** `pieces.*` — one key per short and long piece label the engine exposes (move-history, selected-piece-detail). */
164
+ type PieceI18nKey = `pieces.${PieceShortKey | PieceLongKey}`;
165
+ /** `eventToast.*` — one key per toastable event (see `ToastEvent` in `event-toast.tsx`). */
166
+ type EventToastI18nKey = `eventToast.${'interception' | 'offside' | 'tackle'}`;
167
+ /** Union of every `game`-namespace key the package reads. */
168
+ type GameI18nKey = (typeof STATIC_I18N_KEYS)[number] | PieceI18nKey | EventToastI18nKey;
169
+ /**
170
+ * Manifest of every `game`-namespace key the package's components read via `useGameT`.
171
+ * Host apps use it to assert their translation catalogs cover the package (AD-4).
172
+ * The `pieces.*` family is derived from the engine's `SHORT_KEY`/`LONG_KEY` so it can't
173
+ * drift when a piece is added; static keys and `eventToast.*` are listed above.
174
+ * No key names an automated-opponent brand — the roster owns opponent identity.
175
+ */
176
+ declare const GAME_I18N_KEYS: readonly GameI18nKey[];
156
177
  declare function GameI18nProvider({ t, children }: {
157
178
  t: GameTranslator;
158
179
  children: ReactNode;
@@ -162,4 +183,4 @@ declare function useGameT(): GameTranslator;
162
183
 
163
184
  declare function cn(...inputs: ClassValue[]): string;
164
185
 
165
- export { ActionPoints, Avatar, AvatarFallback, AvatarImage, Button, type ButtonProps, ConfirmDialog, EventToast, Football, GameBoard, GameControls, GameI18nProvider, GamePiece, type GameTranslator, MiniScoreboard, MobileHistory, MoveHistory, Scoreboard, SelectedPieceDetail, StaticGameBoard, TurnBanner, cn, useGameT };
186
+ export { ActionPoints, Avatar, AvatarFallback, AvatarImage, Button, type ButtonProps, ConfirmDialog, EventToast, Football, GAME_I18N_KEYS, GameBoard, GameControls, type GameI18nKey, GameI18nProvider, GamePiece, type GameTranslator, MiniScoreboard, MobileHistory, MoveHistory, Scoreboard, SelectedPieceDetail, StaticGameBoard, TurnBanner, cn, useGameT };
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { useGameStore, getInitialBoardState } from './chunk-N24LGLLO.js';
2
- import { getValidMoves, getValidPasses, isInEnemyArea, RANK_LABELS, FILE_LABELS, LONG_KEY, squareName, SHORT_KEY } from '@scriptonita/chess-football-engine';
2
+ import { SHORT_KEY, LONG_KEY, getValidMoves, getValidPasses, isInEnemyArea, RANK_LABELS, FILE_LABELS, squareName } from '@scriptonita/chess-football-engine';
3
3
  import { clsx } from 'clsx';
4
4
  import { twMerge } from 'tailwind-merge';
5
5
  import { MotionConfig, AnimatePresence, motion } from 'framer-motion';
@@ -125,6 +125,49 @@ var Football = ({ className }) => {
125
125
  }
126
126
  );
127
127
  };
128
+ var STATIC_I18N_KEYS = [
129
+ "actionPointsAriaLabel",
130
+ "actionPointsShort",
131
+ "endTurn",
132
+ "endTurnConfirm",
133
+ "endTurnConfirmDescription",
134
+ "endTurnConfirmYes",
135
+ "endTurnKeepPlaying",
136
+ "history.empty",
137
+ "history.goal",
138
+ "history.interception",
139
+ "history.move",
140
+ "history.offside",
141
+ "history.pass",
142
+ "history.tackle",
143
+ "history.title",
144
+ "history.turn",
145
+ "history.viewAll",
146
+ "move",
147
+ "offsideWarning",
148
+ "pass",
149
+ "selectedPiece.alreadyMoved",
150
+ "selectedPiece.atSquare",
151
+ "selectedPiece.empty",
152
+ "selectedPiece.hasBall",
153
+ "teamBlack",
154
+ "teamWhite",
155
+ "waitingRival",
156
+ "yourTurn"
157
+ ];
158
+ var PIECE_I18N_KEYS = [...Object.values(SHORT_KEY), ...Object.values(LONG_KEY)].map(
159
+ (label) => `pieces.${label}`
160
+ );
161
+ var EVENT_TOAST_I18N_KEYS = [
162
+ "eventToast.interception",
163
+ "eventToast.offside",
164
+ "eventToast.tackle"
165
+ ];
166
+ var GAME_I18N_KEYS = [
167
+ ...STATIC_I18N_KEYS,
168
+ ...PIECE_I18N_KEYS,
169
+ ...EVENT_TOAST_I18N_KEYS
170
+ ];
128
171
  var fallback = (key) => key;
129
172
  var GameI18nContext = createContext(fallback);
130
173
  function GameI18nProvider({ t, children }) {
@@ -335,7 +378,14 @@ function GameBoard({ userSide, showCoordinates = false, keyboardNav = true }) {
335
378
  isDisambiguateTarget && selectedPieceId && /* @__PURE__ */ jsxs(
336
379
  "div",
337
380
  {
338
- className: "absolute z-50 bottom-full mb-1 left-1/2 -translate-x-1/2 flex gap-1 bg-bg-secondary border border-border-subtle rounded-md p-1 shadow-xl pointer-events-auto whitespace-nowrap",
381
+ className: cn(
382
+ "absolute z-50 flex gap-1 bg-bg-secondary border border-border-subtle rounded-md p-1 shadow-xl pointer-events-auto whitespace-nowrap",
383
+ // The board container is `overflow-hidden` (for its rounded
384
+ // corners), so a popover that spills past an edge gets clipped.
385
+ // Anchor it inside the board on edge columns / the top row.
386
+ y === ROWS - 1 ? "top-full mt-1" : "bottom-full mb-1",
387
+ x === 0 ? "left-0" : x === COLS - 1 ? "right-0" : "left-1/2 -translate-x-1/2"
388
+ ),
339
389
  onClick: (e) => e.stopPropagation(),
340
390
  children: [
341
391
  /* @__PURE__ */ jsxs(
@@ -1277,6 +1327,6 @@ function HistoryChip({ lastMove, onClick, className }) {
1277
1327
  );
1278
1328
  }
1279
1329
 
1280
- export { ActionPoints, Avatar, AvatarFallback, AvatarImage, Button, ConfirmDialog, EventToast, Football, GameBoard, GameControls, GameI18nProvider, GamePiece, MiniScoreboard, MobileHistory, MoveHistory, Scoreboard, SelectedPieceDetail, StaticGameBoard, TurnBanner, cn, useGameT };
1330
+ export { ActionPoints, Avatar, AvatarFallback, AvatarImage, Button, ConfirmDialog, EventToast, Football, GAME_I18N_KEYS, GameBoard, GameControls, GameI18nProvider, GamePiece, MiniScoreboard, MobileHistory, MoveHistory, Scoreboard, SelectedPieceDetail, StaticGameBoard, TurnBanner, cn, useGameT };
1281
1331
  //# sourceMappingURL=index.js.map
1282
1332
  //# sourceMappingURL=index.js.map