@tastic/shell 0.4.0 → 0.6.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
@@ -17,7 +17,7 @@ package ecosystem, on [`@tastic/hud`](https://github.com/jayrdeaton/react-native
17
17
  ## What's in here
18
18
 
19
19
  - **`RootLayout`**: the root of the app (gesture root, safe area, fonts, Redux and its persist gate,
20
- the theme, profiles, every game's own provider, the splash gates, the shared orientation reading,
20
+ the theme, profiles, every game's own provider, the splash gates,
21
21
  toasts, How to Play, the OTA update dialog) around expo-router's stack. The stack follows the app's
22
22
  own theme, not the phone's light or dark appearance: the status bar's text, the root window and the
23
23
  navigation theme's background (what shows in a sliding screen's corners during a push or pop).
@@ -116,8 +116,7 @@ PuckTastic and DuelTastic draw what they always did:
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`. |
118
118
  | `useFeedbackSounds?` | A hook returning the two sounds every button plays (`FeedbackSounds`: `selection`, `notification`), in place of the shell's two wavs. |
119
- | `Toaster?` | The pack's own toaster, drawn in a frame turned with the phone (with the safe-area insets turned onto its edges) in place of the shell's. The toast provider is given no Paper, so nothing portals it out of the frame. |
120
- | `portraitWhileKeyboard?` | Every screen reads upright while the software keyboard is up (`@tastic/core`'s `OrientationProvider`), for naming a profile sideways. |
119
+ | `Toaster?` | The pack's own toaster, drawn in a frame over the whole app (inside the safe area) in place of the shell's. The toast provider is given no Paper, so nothing portals it out of the frame. |
121
120
  | `edgeGuard?` | `false` leaves Edge Guard out of Settings (no edge controls, no Edge Guard plugin). |
122
121
  | `seatTheme?` | `(colors, dark) => ({ color, harmony })`: the theme the seats' colors make (a muted seed from seat 1's color), applied whenever they or dark mode change and as a fresh install's theme, in place of a triad of the raw colors. With it, `useSeatColors` reads each seat's color from where it's remembered (`seatColors`) rather than from the theme. |
123
122
  | `previewColor?` | `(hex, dark) => string`: how every profile color is drawn (the seat buttons and their swatches on Home and in the loadouts, a loadout's Ready button and seat controls, each `ProfileChip`), mounted as `@tastic/profile`'s `ProfileColorProvider`. Saved colors stay as picked. |
@@ -129,15 +128,15 @@ PuckTastic and DuelTastic draw what they always did:
129
128
  | `resetStats?` | The stats screen's Reset where the pack resets stats itself (`PackStatsReset`: a `useReset` hook returning `(profileId) => void`, and the `labels` for a player's name, Guest, or `null` for Everyone). It follows the player picker, not the game picker. |
130
129
  | `statsGameTitles?` | `false` leaves each game's name off its sections on All Games, where the sections name it. |
131
130
  | `newProfileColor?` | A new profile's starting color on Profiles. Unset is auto-paper's first swatch. |
132
- | `usePickerAlign?` | `(open, contentWidth, contentHeight, options?) => AlignResult` (`PickerAlign`), a hook: where seat 1's menu on Home, both seat buttons' menus in a loadout's one-human row (2 Player keeps each menu in its own player's half), the stats screen's two pickers and a profile's color swatch open. hud's own placement measures a turned button against the upright window, so with the phone held sideways it can run a menu off the screen (seen on the iOS simulator, 2026-10-29); a pack whose screens turn hands in a frame-aware one (Solitaire's `useFrameAutoAlign`). Profiles passes `{ maxContentWidth: 640 }`, its roster's column. Unset is hud's placement. |
133
- | `homeTabs?` | Tabs splitting Home's games (`HomeTab`: a `label`, and `includes(game)`, which of the pack's games it shows, in the pack's order): a switch under seat 1's button, or over the grid on a wide screen, on the theme's surface over a `Backdrop`, showing one tab's games at a time. It opens on the first tab and keeps the one picked while Home is covered or turns. The other tabs' games stay mounted, hidden, so a switch draws nothing new. A game no tab includes isn't on Home. Unset, or a single tab, shows every game with no switch. Solitaire's: Solitaire (no `seatTwo`) and Two Player. |
131
+ | `usePickerAlign?` | `(open, contentWidth, contentHeight, options?) => AlignResult` (`PickerAlign`), a hook: where seat 1's menu on Home, both seat buttons' menus in a loadout's one-human row (2 Player keeps each menu in its own player's half), the stats screen's two pickers and a profile's color swatch open. It was added because hud's own placement measured a button in a frame turned by `@tastic/core`'s drawn rotation against the upright window (Solitaire's `useFrameAutoAlign`); nothing turns since core 0.15, so a pack may no longer need one. Profiles passes `{ maxContentWidth: 640 }`, its roster's column. Unset is hud's placement. |
132
+ | `homeTabs?` | Tabs splitting Home's games (`HomeTab`: a `label`, and `includes(game)`, which of the pack's games it shows, in the pack's order): a switch under seat 1's button, or over the grid on a wide screen, on the theme's surface over a `Backdrop`, showing one tab's games at a time. It opens on the first tab and keeps the one picked while Home is covered or the window changes. The other tabs' games stay mounted, hidden, so a switch draws nothing new. A game no tab includes isn't on Home. Unset, or a single tab, shows every game with no switch. Solitaire's: Solitaire (no `seatTwo`) and Two Player. |
134
133
 
135
134
  ### `GameDefinition`
136
135
 
137
136
  Each game is one object: its `id`, `title`, `blurb` and `icon` (a component drawn in the seats'
138
137
  colors, or `imageGameIcon({ light, dark })` for a light and dark pair of pictures), its seat 2
139
- choices (`seatTwo`: `'cpu'`, `'person'`, `'nobody'`) and how 2 Player seats its players
140
- (`twoPlayerSeats`), the store `reducers` it mounts, its root `Provider`, its `useLoadout(mode)`, its
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
141
140
  `PlayScreen`, its `StatsSections` and `AchievementList`, `resetStats`, and its How to Play `guide`.
142
141
  See `src/types.ts` for every field.
143
142
 
@@ -145,7 +144,7 @@ What a game can leave out or add, each optional, so a two-seat game sets none of
145
144
 
146
145
  | Field | |
147
146
  | --- | --- |
148
- | no `seatTwo` (nor `twoPlayerSeats`) | 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 seat 2 button, every round is solo (`useActiveRound` falls back to `'solo'`), and its How to Play describes a solo round. |
149
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`. |
150
149
  | no `cpuDifficulty` (in `GameLoadout`) | A CPU with no levels: seat 2's menu offers one plain CPU. |
151
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. |
@@ -154,8 +153,8 @@ What a game can leave out or add, each optional, so a two-seat game sets none of
154
153
  | no `Provider` | A game whose stats live in the pack's own `Provider`. |
155
154
  | no `AchievementList`, no `resetStats` | A game whose achievements are in the pack's one list, and whose stats the pack resets (`PackDefinition.AchievementList`, `resetStats`). |
156
155
  | no `guide` (`GuidelessGameDefinition`) | A game the pack's own `guide` teaches: its tile opens without cards the first time. A `GameDefinition` keeps `guide` required, so a pack's code that reads its games' cards keeps compiling; `PackDefinition.games` takes either (`PackGameDefinition`). |
157
- | `Rules` | Its tile's rules button opens this sheet (`GameRulesProps`: `visible`, `onDismiss`) in place of its How to Play. It portals into a host inside Home's turned frame, so it's laid out against the frame and turned with it. |
158
- | `keepStatusBar` | Its play screen keeps the status bar while the phone is held upright. Unset, every play screen hides it for the whole round. |
156
+ | `Rules` | Its tile's rules button opens this sheet (`GameRulesProps`: `visible`, `onDismiss`) in place of its How to Play. It portals into a host inside Home's frame, so it's laid out against Home's safe area. |
157
+ | `keepStatusBar` | Its play screen keeps the status bar. Unset, every play screen hides it for the whole round. |
159
158
 
160
159
  A game never imports another game, and the shell never imports a game: games reach the shell only
161
160
  through the pack (`usePack()`).
@@ -176,15 +175,42 @@ through the pack (`usePack()`).
176
175
 
177
176
  Six fixes CardTastic's move brought to every pack's screens: Home's press-away overlay sits in the
178
177
  scroller beside seat 1's button in the upright layout (as the frame's first child it was under the whole
179
- scroller, so a press on a row played the game), seat 1's menu closes on every turn of the phone, both of
178
+ scroller, so a press on a row played the game), seat 1's menu closes on every change of window, both of
180
179
  Home's scrollers fade out at an edge with more past it (auto-paper's `FadingScrollView`), a press
181
180
  anywhere on the stats screen (its header and margins too) closes a picker's menu, the stats screen's
182
- column is capped at 640pt in the wide layout, and Profiles turns with the phone (hud's `RotatedFrame`,
183
- its roster capped at 640pt in the wide layout). Every hud import goes through `@tastic/hud/chrome`,
181
+ column is capped at 640pt in the wide layout, and Profiles' roster is capped at 640pt in the wide
182
+ layout (hud's `RotatedFrame`, which nothing turns any more). Every hud import goes through `@tastic/hud/chrome`,
184
183
  `/guide` or `/lobby`, so an app with no Skia can install the shell; a pack's own imports don't change.
185
184
  The shell's routes are handed to expo-router as plain `Href`s, so an app with typed routes type-checks
186
185
  the shell before its own routes match.
187
186
 
187
+ ### The OS turns (0.5.0)
188
+
189
+ Needs `@tastic/core` 0.15, where the seat mode is the window's shape on every platform. The shell no
190
+ longer reads the accelerometer, draws a turn or offers Lock Orientation. A pack bumping to it:
191
+
192
+ - replaces `twoPlayerSeats` with `sideBySideWhenWide: true` on the games whose 2 Player seats go side by
193
+ side in a wide window (where `faceToFaceOnWeb` was false), and drops it elsewhere;
194
+ - drops `portraitWhileKeyboard`, and any `rotation` it read from the loadout's props or passed to
195
+ `SettingsDialog`;
196
+ - takes `"@tastic/core"` out of `app.json`'s plugins, sets `UIViewControllerBasedStatusBarAppearance: true`
197
+ in `ios.infoPlist` (the stack sets the status bar per screen), and makes a new native build.
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); desktop web (a browser window at least
209
+ `MATCH_CHIPS_DESKTOP_MIN_WIDTH`, 768, wide), 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 on desktop web.
212
+ - **Look:** a 24 icon in the theme's full contrast on a translucent chip of the page's color.
213
+
188
214
  ## Peer dependencies
189
215
 
190
216
  None are bundled. The floors are the versions PuckTastic and DuelTastic ran the shell on when it
@@ -198,7 +224,7 @@ became a package (the lower of the two where they differ).
198
224
  | `expo-splash-screen`, `@rific/splash-gate` | >=58.0.10, >=0.2.3 | holding the splash screen until the theme, fonts and profiles are ready |
199
225
  | `expo-constants` | >=58.0.12 | the web tab title |
200
226
  | `expo-blur`, `@react-native-masked-view/masked-view` | >=58.0.4, >=0.3.2 | auto-paper's blur and its scroll fade, Home's fading scrollers |
201
- | `expo-haptics`, `expo-keep-awake`, `expo-sensors` | >=58.0.7, >=58.0.3, >=58.0.4 | the toaster's haptics, Keep Awake, the orientation reading |
227
+ | `expo-haptics`, `expo-keep-awake` | >=58.0.7, >=58.0.3 | the toaster's haptics, Keep Awake |
202
228
  | `react-native-gesture-handler`, `react-native-reanimated`, `react-native-safe-area-context` | >=3.3.0, >=4.7.1, >=5.10.1 | the gesture root, auto-paper's dialogs and the loadout's fades, insets |
203
229
  | `react-native-paper` | >=5.15.3 | text, icons, the toaster and feedback-press |
204
230
  | `@reduxjs/toolkit`, `redux`, `react-redux`, `redux-persist`, `@react-native-async-storage/async-storage` | >=2.13.0, >=5.0.1, >=9.3.0, >=6.0.0, >=2.2.0 | the store and where it's saved |
@@ -206,7 +232,7 @@ became a package (the lower of the two where they differ).
206
232
  | `@rific/core` | >=0.5.0 | settings slices, Keep Awake, `safeBack` |
207
233
  | `@rific/feedback-press` | >=0.13.1 | haptic and sound settings, the UI sounds |
208
234
  | `@rific/toaster` | >=0.10.1 | toasts (DuelTastic runs 0.12, PuckTastic 0.10) |
209
- | `@tastic/core` | >=0.14.0 | orientation, rotation, the status bar and root background |
235
+ | `@tastic/core` | >=0.15.0 | the seat mode from the window's shape, the root background |
210
236
  | `@tastic/hud` | >=0.27.1 | Settings, the stats screen, the loadout's panels (its Skia-free `/lobby` entry, new in 0.26.0; 0.27.1's options for a pack drawn on its own backdrop), How to Play |
211
237
  | `@tastic/profile` | >=0.16.2 | profiles, the seat buttons, seat colors |
212
238
  | `@tastic/achievements` | >=0.6.0 | `createGameStats`, `forgetProfileAchievements` |
package/dist/index.d.mts CHANGED
@@ -2,7 +2,6 @@ import * as react from 'react';
2
2
  import { ComponentType, ReactNode, ComponentProps } from 'react';
3
3
  import * as _rific_auto_paper from '@rific/auto-paper';
4
4
  import { ThemeAppearance, ThemeSettings } from '@rific/auto-paper';
5
- import { ViewRotation } from '@tastic/core';
6
5
  import { PopoverHost, AlignResult } from '@tastic/hud/chrome';
7
6
  import { GuideStep } from '@tastic/hud/guide';
8
7
  import { MenuOption } from '@tastic/hud/lobby';
@@ -85,8 +84,6 @@ declare const opponentActions: {
85
84
  };
86
85
 
87
86
  interface AppSettings {
88
- lockOrientation: boolean;
89
- lockedRotation?: ViewRotation;
90
87
  deferBottomEdgeGestures: boolean;
91
88
  }
92
89
  declare const DEFAULT_APP_SETTINGS: AppSettings;
@@ -140,7 +137,6 @@ declare function seatTwoFor(saved: SeatTwo, choices: readonly SeatTwo[] | undefi
140
137
  declare function humanSeatsFor(mode: RoundMode): Seat[];
141
138
  interface LoadoutOptionsProps {
142
139
  host: PopoverHost;
143
- rotation: ViewRotation;
144
140
  accentColor: string;
145
141
  mutedColor: string;
146
142
  onAccentColor: string;
@@ -153,7 +149,6 @@ interface SeatControlLook {
153
149
  seatColor: string;
154
150
  mutedColor: string;
155
151
  dark: boolean;
156
- rotation: ViewRotation;
157
152
  }
158
153
  interface GameLoadout {
159
154
  roundSettings: object;
@@ -211,10 +206,7 @@ interface GameDefinition {
211
206
  icon?: ComponentType<GameIconProps>;
212
207
  Preview?: ComponentType<GamePreviewProps>;
213
208
  seatTwo?: readonly SeatTwo[];
214
- twoPlayerSeats?: {
215
- faceToFaceOnWeb: boolean;
216
- followUpsideDown: boolean;
217
- };
209
+ sideBySideWhenWide?: boolean;
218
210
  reducers: Record<string, Reducer>;
219
211
  Provider?: ComponentType<{
220
212
  children: ReactNode;
@@ -297,7 +289,6 @@ interface PackDefinition {
297
289
  useScreenOptions?: () => StackScreenOptions;
298
290
  useFeedbackSounds?: () => FeedbackSounds;
299
291
  Toaster?: ComponentType;
300
- portraitWhileKeyboard?: boolean;
301
292
  edgeGuard?: boolean;
302
293
  seatTheme?: (colors: Record<Seat, string>, dark: boolean) => Pick<ThemeSettings, 'color' | 'harmony'>;
303
294
  previewColor?: (hex: string, dark: boolean) => string;
@@ -349,7 +340,6 @@ declare function createPackStore(pack: PackStoreSource, { keyPrefix, migrate, bl
349
340
  liveplay: LiveplaySliceState;
350
341
  } & redux_persist_es_persistReducer.PersistPartial, {
351
342
  type: string;
352
- payload?: unknown;
353
343
  } | {
354
344
  type: string;
355
345
  payload?: unknown;
@@ -359,6 +349,7 @@ declare function createPackStore(pack: PackStoreSource, { keyPrefix, migrate, bl
359
349
  type: string;
360
350
  } | {
361
351
  type: string;
352
+ payload?: unknown;
362
353
  }, _reduxjs_toolkit.Tuple<[redux.StoreEnhancer<{
363
354
  dispatch: redux_thunk.ThunkDispatch<{
364
355
  theme: _rific_auto_paper.ThemeState;
@@ -408,14 +399,37 @@ declare function imageGameIcon(images: {
408
399
  dark: ImageSourcePropType;
409
400
  }): ComponentType<GameIconProps>;
410
401
 
402
+ declare const MATCH_CHIPS_DESKTOP_MIN_WIDTH = 768;
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 on desktop web, 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 on desktop
412
+ * web: 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 on desktop web. */
424
+ declare function MatchChips({ playing, faceToFace, centerLineY, onBack, onSettings }: MatchChipsProps): react.JSX.Element;
425
+
411
426
  interface SettingsDialogProps {
412
427
  visible: boolean;
413
428
  onDismiss: () => void;
414
- rotation?: ViewRotation;
415
429
  onShowHowToPlay?: () => void;
416
430
  children?: ReactNode;
417
431
  }
418
- declare function SettingsDialog({ visible, onDismiss, rotation, onShowHowToPlay, children }: SettingsDialogProps): react.JSX.Element;
432
+ declare function SettingsDialog({ visible, onDismiss, onShowHowToPlay, children }: SettingsDialogProps): react.JSX.Element;
419
433
 
420
434
  declare function useActiveRound<S extends object>(game: string, defaults: S): {
421
435
  mode: RoundMode;
@@ -561,4 +575,5 @@ declare function createPlayerSettings<S extends WithControls<C>, C>({ id, defaul
561
575
  };
562
576
  };
563
577
 
564
- export { type ActiveRound, type AppSettings, DEFAULT_APP_SETTINGS, DEFAULT_OPPONENT, type FeedbackSounds, GUEST_PLAYER_ID, type GameDefinition, type GameGuide, type GameGuideState, type GameIconProps, type GameLoadout, type GamePreviewProps, type GameRulesProps, type GuidelessGameDefinition, type HeroTitleProps, HomeScreen, type HomeTab, type LiveplaySliceState, type LoadoutOptionsProps, LoadoutRoute, type OpponentState, PREVIEW_ASPECT, type PackDefinition, type PackGameDefinition, type PackGuide, PackProvider, type PackStatsReset, type PackStatsSectionsProps, type PackStatsTab, type PackStore, type PackStoreConfig, type PackStoreSource, type PickerAlign, PlayRoute, type PlayerControlsState, type PlayerSettingsState, type ProfileSelectionState, ProfilesProvider, ProfilesRoute, type RecordResult, RootLayout, type RoundMode, type Seat, type SeatColorsState, type SeatControlLook, type SeatTwo, SettingsDialog, type SettingsDialogProps, type ShellState, type StackScreenOptions, 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 };
578
+ export { DEFAULT_APP_SETTINGS, DEFAULT_OPPONENT, GUEST_PLAYER_ID, HomeScreen, LoadoutRoute, MATCH_CHIPS_DESKTOP_MIN_WIDTH, 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, useGameGuide, useOpponent, usePack, usePackGame, useProfiles, useSeatColors };
579
+ 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
@@ -2,7 +2,6 @@ import * as react from 'react';
2
2
  import { ComponentType, ReactNode, ComponentProps } from 'react';
3
3
  import * as _rific_auto_paper from '@rific/auto-paper';
4
4
  import { ThemeAppearance, ThemeSettings } from '@rific/auto-paper';
5
- import { ViewRotation } from '@tastic/core';
6
5
  import { PopoverHost, AlignResult } from '@tastic/hud/chrome';
7
6
  import { GuideStep } from '@tastic/hud/guide';
8
7
  import { MenuOption } from '@tastic/hud/lobby';
@@ -85,8 +84,6 @@ declare const opponentActions: {
85
84
  };
86
85
 
87
86
  interface AppSettings {
88
- lockOrientation: boolean;
89
- lockedRotation?: ViewRotation;
90
87
  deferBottomEdgeGestures: boolean;
91
88
  }
92
89
  declare const DEFAULT_APP_SETTINGS: AppSettings;
@@ -140,7 +137,6 @@ declare function seatTwoFor(saved: SeatTwo, choices: readonly SeatTwo[] | undefi
140
137
  declare function humanSeatsFor(mode: RoundMode): Seat[];
141
138
  interface LoadoutOptionsProps {
142
139
  host: PopoverHost;
143
- rotation: ViewRotation;
144
140
  accentColor: string;
145
141
  mutedColor: string;
146
142
  onAccentColor: string;
@@ -153,7 +149,6 @@ interface SeatControlLook {
153
149
  seatColor: string;
154
150
  mutedColor: string;
155
151
  dark: boolean;
156
- rotation: ViewRotation;
157
152
  }
158
153
  interface GameLoadout {
159
154
  roundSettings: object;
@@ -211,10 +206,7 @@ interface GameDefinition {
211
206
  icon?: ComponentType<GameIconProps>;
212
207
  Preview?: ComponentType<GamePreviewProps>;
213
208
  seatTwo?: readonly SeatTwo[];
214
- twoPlayerSeats?: {
215
- faceToFaceOnWeb: boolean;
216
- followUpsideDown: boolean;
217
- };
209
+ sideBySideWhenWide?: boolean;
218
210
  reducers: Record<string, Reducer>;
219
211
  Provider?: ComponentType<{
220
212
  children: ReactNode;
@@ -297,7 +289,6 @@ interface PackDefinition {
297
289
  useScreenOptions?: () => StackScreenOptions;
298
290
  useFeedbackSounds?: () => FeedbackSounds;
299
291
  Toaster?: ComponentType;
300
- portraitWhileKeyboard?: boolean;
301
292
  edgeGuard?: boolean;
302
293
  seatTheme?: (colors: Record<Seat, string>, dark: boolean) => Pick<ThemeSettings, 'color' | 'harmony'>;
303
294
  previewColor?: (hex: string, dark: boolean) => string;
@@ -349,7 +340,6 @@ declare function createPackStore(pack: PackStoreSource, { keyPrefix, migrate, bl
349
340
  liveplay: LiveplaySliceState;
350
341
  } & redux_persist_es_persistReducer.PersistPartial, {
351
342
  type: string;
352
- payload?: unknown;
353
343
  } | {
354
344
  type: string;
355
345
  payload?: unknown;
@@ -359,6 +349,7 @@ declare function createPackStore(pack: PackStoreSource, { keyPrefix, migrate, bl
359
349
  type: string;
360
350
  } | {
361
351
  type: string;
352
+ payload?: unknown;
362
353
  }, _reduxjs_toolkit.Tuple<[redux.StoreEnhancer<{
363
354
  dispatch: redux_thunk.ThunkDispatch<{
364
355
  theme: _rific_auto_paper.ThemeState;
@@ -408,14 +399,37 @@ declare function imageGameIcon(images: {
408
399
  dark: ImageSourcePropType;
409
400
  }): ComponentType<GameIconProps>;
410
401
 
402
+ declare const MATCH_CHIPS_DESKTOP_MIN_WIDTH = 768;
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 on desktop web, 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 on desktop
412
+ * web: 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 on desktop web. */
424
+ declare function MatchChips({ playing, faceToFace, centerLineY, onBack, onSettings }: MatchChipsProps): react.JSX.Element;
425
+
411
426
  interface SettingsDialogProps {
412
427
  visible: boolean;
413
428
  onDismiss: () => void;
414
- rotation?: ViewRotation;
415
429
  onShowHowToPlay?: () => void;
416
430
  children?: ReactNode;
417
431
  }
418
- declare function SettingsDialog({ visible, onDismiss, rotation, onShowHowToPlay, children }: SettingsDialogProps): react.JSX.Element;
432
+ declare function SettingsDialog({ visible, onDismiss, onShowHowToPlay, children }: SettingsDialogProps): react.JSX.Element;
419
433
 
420
434
  declare function useActiveRound<S extends object>(game: string, defaults: S): {
421
435
  mode: RoundMode;
@@ -561,4 +575,5 @@ declare function createPlayerSettings<S extends WithControls<C>, C>({ id, defaul
561
575
  };
562
576
  };
563
577
 
564
- export { type ActiveRound, type AppSettings, DEFAULT_APP_SETTINGS, DEFAULT_OPPONENT, type FeedbackSounds, GUEST_PLAYER_ID, type GameDefinition, type GameGuide, type GameGuideState, type GameIconProps, type GameLoadout, type GamePreviewProps, type GameRulesProps, type GuidelessGameDefinition, type HeroTitleProps, HomeScreen, type HomeTab, type LiveplaySliceState, type LoadoutOptionsProps, LoadoutRoute, type OpponentState, PREVIEW_ASPECT, type PackDefinition, type PackGameDefinition, type PackGuide, PackProvider, type PackStatsReset, type PackStatsSectionsProps, type PackStatsTab, type PackStore, type PackStoreConfig, type PackStoreSource, type PickerAlign, PlayRoute, type PlayerControlsState, type PlayerSettingsState, type ProfileSelectionState, ProfilesProvider, ProfilesRoute, type RecordResult, RootLayout, type RoundMode, type Seat, type SeatColorsState, type SeatControlLook, type SeatTwo, SettingsDialog, type SettingsDialogProps, type ShellState, type StackScreenOptions, 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 };
578
+ export { DEFAULT_APP_SETTINGS, DEFAULT_OPPONENT, GUEST_PLAYER_ID, HomeScreen, LoadoutRoute, MATCH_CHIPS_DESKTOP_MIN_WIDTH, 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, useGameGuide, useOpponent, usePack, usePackGame, useProfiles, useSeatColors };
579
+ 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 };