@tastic/shell 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -111,7 +111,7 @@ PuckTastic and DuelTastic draw what they always did:
111
111
 
112
112
  | Field | |
113
113
  | --- | --- |
114
- | `Backdrop?` | A table drawn once behind the whole stack (Solitaire's felt). The stack's two layers go transparent (the screens' `contentStyle` and the navigation theme's `colors.background`, which React Navigation paints around every screen), the root window stays dark so light mode doesn't flash white on a push, Android's push and pop crossfade (its default holds the outgoing screen opaque), and Home, each loadout, the stats screen and Profiles draw transparent, with their buttons and tabs on the theme's surface. |
114
+ | `Backdrop?` | A table drawn once behind the whole stack (Solitaire's felt). The stack's two layers go transparent (the screens' `contentStyle` and the navigation theme's `colors.background`, which React Navigation paints around every screen), the root window stays dark so light mode doesn't flash white on a push, Android's push and pop crossfade (its default holds the outgoing screen opaque), and Home, each loadout, the stats screen and Profiles draw transparent, with their buttons and tabs on the theme's surface (a loadout's Ready buttons too, filled with the seat's color once ready). |
115
115
  | `foreground?` | The color of what those screens draw straight on the background (the hero, the corner buttons, headers), and at half strength a loadout's muted options. Unset is black or white with the theme. |
116
116
  | `Provider?` | Mounted once around How to Play and the stack, inside the store, the theme, profiles and every game's `Provider` (one stats context across the pack's games). |
117
117
  | `useScreenOptions?` | A hook returning stack screen options (`StackScreenOptions`), merged after the shell's own (a status bar style of the pack's own, Reduce Motion's crossfade). The shell's already follow the app's theme, and stay dark over a `Backdrop`. |
@@ -135,8 +135,8 @@ PuckTastic and DuelTastic draw what they always did:
135
135
 
136
136
  Each game is one object: its `id`, `title`, `blurb` and `icon` (a component drawn in the seats'
137
137
  colors, or `imageGameIcon({ light, dark })` for a light and dark pair of pictures), its seat 2
138
- choices (`seatTwo`: `'cpu'`, `'person'`, `'nobody'`) and whether 2 Player seats its players side by
139
- side in a wide window (`sideBySideWhenWide`), the store `reducers` it mounts, its root `Provider`, its `useLoadout(mode)`, its
138
+ choices (`seatTwo`: `'cpu'`, `'person'`, `'nobody'`), whether 2 Player seats its players side by side
139
+ at a computer (`sideBySideAtComputer`) and in a wide window (`sideBySideWhenWide`), the store `reducers` it mounts, its root `Provider`, its `useLoadout(mode)`, its
140
140
  `PlayScreen`, its `StatsSections` and `AchievementList`, `resetStats`, and its How to Play `guide`.
141
141
  See `src/types.ts` for every field.
142
142
 
@@ -144,9 +144,9 @@ What a game can leave out or add, each optional, so a two-seat game sets none of
144
144
 
145
145
  | Field | |
146
146
  | --- | --- |
147
- | no `seatTwo` (nor `sideBySideWhenWide`) | A game for one player: its loadout has no seat 2 button, every round is solo (`useActiveRound` falls back to `'solo'`), and its How to Play describes a solo round. |
147
+ | no `seatTwo` (nor `sideBySideWhenWide`) | A game for one player: its loadout has no opponent button, every round is solo (`useActiveRound` falls back to `'solo'`), and its How to Play describes a solo round. |
148
148
  | no `useLoadout` | Nothing to set up first: Home opens its play screen straight away, after its How to Play the first time, and a link to its loadout plays it. Its rule variants go in its play screen's Settings: `<SettingsDialog>` takes `children`. |
149
- | no `cpuDifficulty` (in `GameLoadout`) | A CPU with no levels: seat 2's menu offers one plain CPU. |
149
+ | no `cpuDifficulty` (in `GameLoadout`) | A CPU with no levels: player 1's opponent menu offers one plain CPU. |
150
150
  | `resumable` | A cold launch drops the player back into its play screen if they left the app there rather than backing out of it. The shell remembers only which game (`lastActiveGame`); the game saves and restores its own board. |
151
151
  | `Preview` | Drawn on Home in place of the icon (`GamePreviewProps`: `width`, `height`, the seats' colors, `dark`), in a box of `PREVIEW_ASPECT` (360:200), a frame after Home first paints. While any game has one, Home shows tiles: rows upright, and on a wide screen a grid beside the hero and seat 1's button. A game without one keeps its icon. |
152
152
  | no `icon` | Only with a `Preview`, which Home draws in its place. |
@@ -196,6 +196,21 @@ longer reads the accelerometer, draws a turn or offers Lock Orientation. A pack
196
196
  - takes `"@tastic/core"` out of `app.json`'s plugins, sets `UIViewControllerBasedStatusBarAppearance: true`
197
197
  in `ios.infoPlist` (the stack sets the status bar per screen), and makes a new native build.
198
198
 
199
+ ### The chips over a match (0.6.0)
200
+
201
+ `MatchChips` is every game's back and settings chips during a match, so they sit and show the same
202
+ way in every game of every pack. A play screen renders it with `playing` (true while play is on: a
203
+ live puck, a shot in flight, a round being ridden), `faceToFace` (two players at opposite ends of the
204
+ screen right now) and `onBack`/`onSettings`, plus `centerLineY` when the line between the players isn't
205
+ the window's middle.
206
+
207
+ - **Where:** the window's top corners; 2 Player face to face, the side edges at the line between the
208
+ players (the top corners are the far player's end); at a computer (`useAtComputer`: the web without
209
+ a touch-first screen), the page's top corners always.
210
+ - **When:** faded out over `MATCH_CHIPS_FADE_MS` (150) and not pressable while `playing`, back the moment
211
+ it stops; up all match at a computer.
212
+ - **Look:** a 24 icon in the theme's full contrast on a translucent chip of the page's color.
213
+
199
214
  ## Peer dependencies
200
215
 
201
216
  None are bundled. The floors are the versions PuckTastic and DuelTastic ran the shell on when it
package/dist/index.d.mts CHANGED
@@ -207,6 +207,7 @@ interface GameDefinition {
207
207
  Preview?: ComponentType<GamePreviewProps>;
208
208
  seatTwo?: readonly SeatTwo[];
209
209
  sideBySideWhenWide?: boolean;
210
+ sideBySideAtComputer?: boolean;
210
211
  reducers: Record<string, Reducer>;
211
212
  Provider?: ComponentType<{
212
213
  children: ReactNode;
@@ -399,6 +400,30 @@ declare function imageGameIcon(images: {
399
400
  dark: ImageSourcePropType;
400
401
  }): ComponentType<GameIconProps>;
401
402
 
403
+ declare const MATCH_CHIPS_FADE_MS = 150;
404
+ interface MatchChipsProps {
405
+ /** Whether play is on right now (a live puck, a shot in flight, a round being ridden). While it is,
406
+ * the chips fade out and can't be pressed, so they never cover play; they come back the moment it
407
+ * stops (between points, a round's card, Game Over). Ignored at a computer, where they stay up. */
408
+ playing: boolean;
409
+ /** Two players at opposite ends of one screen right now (2 Player face to face). The chips then sit
410
+ * on the side edges at the line between the players, rather than in the top corners, which are the
411
+ * far player's end. False for one human (vs CPU, solo) and for side by side. Ignored at a
412
+ * computer: both players share one upright screen there. */
413
+ faceToFace: boolean;
414
+ /** Where that line between the players is, as a y in the window. Defaults to the window's middle;
415
+ * pass it when the board isn't centered (a band of score above it, say). */
416
+ centerLineY?: number;
417
+ onBack: () => void;
418
+ onSettings: () => void;
419
+ }
420
+ /** The back and settings chips over a match, in every game of every pack: one rule for where they sit
421
+ * and when they show. The window's top corners (the same spot as hud's CornerActionButtons on every
422
+ * other screen), except 2 Player face to face, which puts them on the side edges at the line between
423
+ * the players; faded out while play is on, except at a computer (useAtComputer: the web without a
424
+ * touch-first screen), where they stay up in the page's corners. */
425
+ declare function MatchChips({ playing, faceToFace, centerLineY, onBack, onSettings }: MatchChipsProps): react.JSX.Element;
426
+
402
427
  interface SettingsDialogProps {
403
428
  visible: boolean;
404
429
  onDismiss: () => void;
@@ -417,6 +442,8 @@ declare function useAppSettings(): {
417
442
  setSettings: (patch: Partial<AppSettings>) => void;
418
443
  };
419
444
 
445
+ declare function useAtComputer(): boolean;
446
+
420
447
  declare function useOpponent(): {
421
448
  seatTwo: SeatTwo;
422
449
  setSeatTwo: (seatTwo: SeatTwo) => void;
@@ -551,5 +578,5 @@ declare function createPlayerSettings<S extends WithControls<C>, C>({ id, defaul
551
578
  };
552
579
  };
553
580
 
554
- export { DEFAULT_APP_SETTINGS, DEFAULT_OPPONENT, GUEST_PLAYER_ID, HomeScreen, LoadoutRoute, PREVIEW_ASPECT, PackProvider, PlayRoute, ProfilesProvider, ProfilesRoute, RootLayout, SettingsDialog, StatsScreen, appSettingsActions, reducer$1 as appSettingsReducer, createGameGuideSlice, createGameStats, createPackStore, createPlayerSettings, createSeatColorsReducer, createShellReducers, defaultProfileSelectionState, defaultSeatColorsState, forgetProfileAchievements, humanSeatsFor, imageGameIcon, liveplayActions, reducer$3 as liveplayReducer, onProfileRemoved, opponentActions, reducer$2 as opponentReducer, profileSelectionActions, reducer as profileSelectionReducer, roundModeFor, seatColorsActions, seatPlayerKey, seatTwoFor, useActiveRound, useAppSettings, useGameGuide, useOpponent, usePack, usePackGame, useProfiles, useSeatColors };
555
- export type { ActiveRound, AppSettings, FeedbackSounds, GameDefinition, GameGuide, GameGuideState, GameIconProps, GameLoadout, GamePreviewProps, GameRulesProps, GuidelessGameDefinition, HeroTitleProps, HomeTab, LiveplaySliceState, LoadoutOptionsProps, OpponentState, PackDefinition, PackGameDefinition, PackGuide, PackStatsReset, PackStatsSectionsProps, PackStatsTab, PackStore, PackStoreConfig, PackStoreSource, PickerAlign, PlayerControlsState, PlayerSettingsState, ProfileSelectionState, RecordResult, RoundMode, Seat, SeatColorsState, SeatControlLook, SeatTwo, SettingsDialogProps, ShellState, StackScreenOptions };
581
+ export { DEFAULT_APP_SETTINGS, DEFAULT_OPPONENT, GUEST_PLAYER_ID, HomeScreen, LoadoutRoute, MATCH_CHIPS_FADE_MS, MatchChips, PREVIEW_ASPECT, PackProvider, PlayRoute, ProfilesProvider, ProfilesRoute, RootLayout, SettingsDialog, StatsScreen, appSettingsActions, reducer$1 as appSettingsReducer, createGameGuideSlice, createGameStats, createPackStore, createPlayerSettings, createSeatColorsReducer, createShellReducers, defaultProfileSelectionState, defaultSeatColorsState, forgetProfileAchievements, humanSeatsFor, imageGameIcon, liveplayActions, reducer$3 as liveplayReducer, onProfileRemoved, opponentActions, reducer$2 as opponentReducer, profileSelectionActions, reducer as profileSelectionReducer, roundModeFor, seatColorsActions, seatPlayerKey, seatTwoFor, useActiveRound, useAppSettings, useAtComputer, useGameGuide, useOpponent, usePack, usePackGame, useProfiles, useSeatColors };
582
+ export type { ActiveRound, AppSettings, FeedbackSounds, GameDefinition, GameGuide, GameGuideState, GameIconProps, GameLoadout, GamePreviewProps, GameRulesProps, GuidelessGameDefinition, HeroTitleProps, HomeTab, LiveplaySliceState, LoadoutOptionsProps, MatchChipsProps, OpponentState, PackDefinition, PackGameDefinition, PackGuide, PackStatsReset, PackStatsSectionsProps, PackStatsTab, PackStore, PackStoreConfig, PackStoreSource, PickerAlign, PlayerControlsState, PlayerSettingsState, ProfileSelectionState, RecordResult, RoundMode, Seat, SeatColorsState, SeatControlLook, SeatTwo, SettingsDialogProps, ShellState, StackScreenOptions };
package/dist/index.d.ts CHANGED
@@ -207,6 +207,7 @@ interface GameDefinition {
207
207
  Preview?: ComponentType<GamePreviewProps>;
208
208
  seatTwo?: readonly SeatTwo[];
209
209
  sideBySideWhenWide?: boolean;
210
+ sideBySideAtComputer?: boolean;
210
211
  reducers: Record<string, Reducer>;
211
212
  Provider?: ComponentType<{
212
213
  children: ReactNode;
@@ -399,6 +400,30 @@ declare function imageGameIcon(images: {
399
400
  dark: ImageSourcePropType;
400
401
  }): ComponentType<GameIconProps>;
401
402
 
403
+ declare const MATCH_CHIPS_FADE_MS = 150;
404
+ interface MatchChipsProps {
405
+ /** Whether play is on right now (a live puck, a shot in flight, a round being ridden). While it is,
406
+ * the chips fade out and can't be pressed, so they never cover play; they come back the moment it
407
+ * stops (between points, a round's card, Game Over). Ignored at a computer, where they stay up. */
408
+ playing: boolean;
409
+ /** Two players at opposite ends of one screen right now (2 Player face to face). The chips then sit
410
+ * on the side edges at the line between the players, rather than in the top corners, which are the
411
+ * far player's end. False for one human (vs CPU, solo) and for side by side. Ignored at a
412
+ * computer: both players share one upright screen there. */
413
+ faceToFace: boolean;
414
+ /** Where that line between the players is, as a y in the window. Defaults to the window's middle;
415
+ * pass it when the board isn't centered (a band of score above it, say). */
416
+ centerLineY?: number;
417
+ onBack: () => void;
418
+ onSettings: () => void;
419
+ }
420
+ /** The back and settings chips over a match, in every game of every pack: one rule for where they sit
421
+ * and when they show. The window's top corners (the same spot as hud's CornerActionButtons on every
422
+ * other screen), except 2 Player face to face, which puts them on the side edges at the line between
423
+ * the players; faded out while play is on, except at a computer (useAtComputer: the web without a
424
+ * touch-first screen), where they stay up in the page's corners. */
425
+ declare function MatchChips({ playing, faceToFace, centerLineY, onBack, onSettings }: MatchChipsProps): react.JSX.Element;
426
+
402
427
  interface SettingsDialogProps {
403
428
  visible: boolean;
404
429
  onDismiss: () => void;
@@ -417,6 +442,8 @@ declare function useAppSettings(): {
417
442
  setSettings: (patch: Partial<AppSettings>) => void;
418
443
  };
419
444
 
445
+ declare function useAtComputer(): boolean;
446
+
420
447
  declare function useOpponent(): {
421
448
  seatTwo: SeatTwo;
422
449
  setSeatTwo: (seatTwo: SeatTwo) => void;
@@ -551,5 +578,5 @@ declare function createPlayerSettings<S extends WithControls<C>, C>({ id, defaul
551
578
  };
552
579
  };
553
580
 
554
- export { DEFAULT_APP_SETTINGS, DEFAULT_OPPONENT, GUEST_PLAYER_ID, HomeScreen, LoadoutRoute, PREVIEW_ASPECT, PackProvider, PlayRoute, ProfilesProvider, ProfilesRoute, RootLayout, SettingsDialog, StatsScreen, appSettingsActions, reducer$1 as appSettingsReducer, createGameGuideSlice, createGameStats, createPackStore, createPlayerSettings, createSeatColorsReducer, createShellReducers, defaultProfileSelectionState, defaultSeatColorsState, forgetProfileAchievements, humanSeatsFor, imageGameIcon, liveplayActions, reducer$3 as liveplayReducer, onProfileRemoved, opponentActions, reducer$2 as opponentReducer, profileSelectionActions, reducer as profileSelectionReducer, roundModeFor, seatColorsActions, seatPlayerKey, seatTwoFor, useActiveRound, useAppSettings, useGameGuide, useOpponent, usePack, usePackGame, useProfiles, useSeatColors };
555
- export type { ActiveRound, AppSettings, FeedbackSounds, GameDefinition, GameGuide, GameGuideState, GameIconProps, GameLoadout, GamePreviewProps, GameRulesProps, GuidelessGameDefinition, HeroTitleProps, HomeTab, LiveplaySliceState, LoadoutOptionsProps, OpponentState, PackDefinition, PackGameDefinition, PackGuide, PackStatsReset, PackStatsSectionsProps, PackStatsTab, PackStore, PackStoreConfig, PackStoreSource, PickerAlign, PlayerControlsState, PlayerSettingsState, ProfileSelectionState, RecordResult, RoundMode, Seat, SeatColorsState, SeatControlLook, SeatTwo, SettingsDialogProps, ShellState, StackScreenOptions };
581
+ export { DEFAULT_APP_SETTINGS, DEFAULT_OPPONENT, GUEST_PLAYER_ID, HomeScreen, LoadoutRoute, MATCH_CHIPS_FADE_MS, MatchChips, PREVIEW_ASPECT, PackProvider, PlayRoute, ProfilesProvider, ProfilesRoute, RootLayout, SettingsDialog, StatsScreen, appSettingsActions, reducer$1 as appSettingsReducer, createGameGuideSlice, createGameStats, createPackStore, createPlayerSettings, createSeatColorsReducer, createShellReducers, defaultProfileSelectionState, defaultSeatColorsState, forgetProfileAchievements, humanSeatsFor, imageGameIcon, liveplayActions, reducer$3 as liveplayReducer, onProfileRemoved, opponentActions, reducer$2 as opponentReducer, profileSelectionActions, reducer as profileSelectionReducer, roundModeFor, seatColorsActions, seatPlayerKey, seatTwoFor, useActiveRound, useAppSettings, useAtComputer, useGameGuide, useOpponent, usePack, usePackGame, useProfiles, useSeatColors };
582
+ export type { ActiveRound, AppSettings, FeedbackSounds, GameDefinition, GameGuide, GameGuideState, GameIconProps, GameLoadout, GamePreviewProps, GameRulesProps, GuidelessGameDefinition, HeroTitleProps, HomeTab, LiveplaySliceState, LoadoutOptionsProps, MatchChipsProps, OpponentState, PackDefinition, PackGameDefinition, PackGuide, PackStatsReset, PackStatsSectionsProps, PackStatsTab, PackStore, PackStoreConfig, PackStoreSource, PickerAlign, PlayerControlsState, PlayerSettingsState, ProfileSelectionState, RecordResult, RoundMode, Seat, SeatColorsState, SeatControlLook, SeatTwo, SettingsDialogProps, ShellState, StackScreenOptions };