@tastic/hud 0.17.0 → 0.18.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 +24 -13
- package/dist/{TriggerGauge-2OJOOF6I.mjs → TriggerGauge-GIHKGAZE.mjs} +5 -5
- package/dist/chrome/index.d.mts +20 -16
- package/dist/chrome/index.d.ts +20 -16
- package/dist/chrome/index.js +289 -210
- package/dist/chrome/index.mjs +11 -5
- package/dist/{chunk-AX4GC5KU.mjs → chunk-PUF6TABL.mjs} +60 -24
- package/dist/{chunk-27FIA26F.mjs → chunk-Z2WUUYTE.mjs} +156 -113
- package/dist/guide/index.d.mts +3 -0
- package/dist/guide/index.d.ts +3 -0
- package/dist/guide/index.js +122 -74
- package/dist/guide/index.mjs +16 -8
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +462 -383
- package/dist/index.mjs +12 -6
- package/package.json +10 -10
- package/src/BaseSettingsDialog.tsx +195 -142
- package/src/ConfirmDialog.tsx +8 -15
- package/src/DialogHeader.tsx +72 -0
- package/src/OverlaySurface.tsx +21 -13
- package/src/TriggerGauge.tsx +9 -9
- package/src/chrome/index.ts +3 -1
- package/src/guide/HowToPlayDialog.tsx +23 -9
- package/src/index.ts +3 -1
- package/src/overlayCard.ts +11 -34
- package/src/useCompactDialog.ts +23 -0
package/README.md
CHANGED
|
@@ -79,6 +79,8 @@ corner of the screen.
|
|
|
79
79
|
- **`OverlayCard`** / **`OverlayBackdrop`** / **`useOverlayCardColors`** - the card and dim behind
|
|
80
80
|
`ConfirmDialog` and the how-to-play guide, in the app's own theme colors and blurred when the
|
|
81
81
|
player's Blur setting allows it. See Overlay cards below.
|
|
82
|
+
- **`DialogHeader`** / **`useCompactDialog`** - the one header every dialog opens with (an icon over
|
|
83
|
+
a bold title in the theme's primary), and the rule for its compact form. See Overlay cards below.
|
|
82
84
|
|
|
83
85
|
## Rotation
|
|
84
86
|
|
|
@@ -244,14 +246,15 @@ export function SettingsDialog({ visible, onDismiss, rotation = 0, settings, set
|
|
|
244
246
|
own overlay (a result banner, a game-over card) should too, so every card in the fleet looks the same:
|
|
245
247
|
|
|
246
248
|
```tsx
|
|
247
|
-
import { OverlayBackdrop, OverlayCard, overlayActionStyles, useOverlayCardColors } from '@tastic/hud'
|
|
249
|
+
import { DialogHeader, OverlayBackdrop, OverlayCard, overlayActionStyles, useCompactDialog, useOverlayCardColors } from '@tastic/hud'
|
|
248
250
|
|
|
249
251
|
function GameOverCard({ onRestart }: { onRestart: () => void }) {
|
|
250
|
-
const {
|
|
252
|
+
const { fgMuted } = useOverlayCardColors()
|
|
253
|
+
const { compact, onLayout } = useCompactDialog()
|
|
251
254
|
return (
|
|
252
|
-
<OverlayBackdrop>
|
|
255
|
+
<OverlayBackdrop onLayout={onLayout}>
|
|
253
256
|
<OverlayCard accessibilityViewIsModal>
|
|
254
|
-
<
|
|
257
|
+
<DialogHeader icon='flag-checkered' title='Game Over' compact={compact} />
|
|
255
258
|
<Text style={{ color: fgMuted }}>Score 42</Text>
|
|
256
259
|
<View style={overlayActionStyles.actions}>...</View>
|
|
257
260
|
</OverlayCard>
|
|
@@ -261,9 +264,18 @@ function GameOverCard({ onRestart }: { onRestart: () => void }) {
|
|
|
261
264
|
```
|
|
262
265
|
|
|
263
266
|
- **Colors come from the app's theme.** Text is `onSurface` (`fg`) and `onSurfaceVariant` (`fgMuted`),
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
wash of
|
|
267
|
+
and the dim is the theme's `backdrop`, the same scrim auto-paper's own `Dialog` uses. The card is the
|
|
268
|
+
Settings sheet's surface: auto-paper's `BlurView` with no elevation (the theme's plain surface, no
|
|
269
|
+
wash of the primary), no border, and the `Dialog`'s corner radius. So every card and the Settings
|
|
270
|
+
sheet look like one family, in each game's palette and light/dark mode.
|
|
271
|
+
- **Every dialog opens with `DialogHeader`.** A 64pt icon over a large bold title, both in the theme's
|
|
272
|
+
primary (pass `color` for another role, as `ConfirmDialog` does with danger when `destructive`).
|
|
273
|
+
`ConfirmDialog`, the how-to-play guide (titled "How to Play") and `BaseSettingsDialog` all use it;
|
|
274
|
+
an app's own cards should too. With `compact` the icon shrinks to 32pt and sits beside a smaller
|
|
275
|
+
title. `useCompactDialog(rotation?)` decides it: put its `onLayout` on the `OverlayBackdrop`, and it
|
|
276
|
+
is compact when the space the dialog lays out in is under `COMPACT_DIALOG_HEIGHT` (528pt) along the
|
|
277
|
+
card's own vertical axis, so a phone held sideways. One-button dialogs end in a single contained
|
|
278
|
+
primary button (`overlayActionStyles.actionButtonSingle`), the Settings sheet's Done included.
|
|
267
279
|
- **Blur is automatic.** The card blurs what's behind it when the player's Blur setting is on and the
|
|
268
280
|
app hands `expo-blur` to auto-paper's `Provider` (`expoBlur={ExpoBlur}`). Otherwise it paints that
|
|
269
281
|
raised surface color instead: on Android (`BlurView` needs a blur target there, which a card has
|
|
@@ -273,9 +285,8 @@ function GameOverCard({ onRestart }: { onRestart: () => void }) {
|
|
|
273
285
|
appearance picker that flips auto-paper's own `blur` theme setting, which the settings sheet, Paper
|
|
274
286
|
menus and these cards all follow. The row only shows where blur can actually happen: not on
|
|
275
287
|
Android, not in an app that never passed `expoBlur`, and not with `hideAppearance`.
|
|
276
|
-
- **`getOverlayCardColors
|
|
277
|
-
|
|
278
|
-
its own cards onto `OverlayCard`.
|
|
288
|
+
- **`getOverlayCardColors` is gone.** It returned the old fixed black/white card (`#F2F2F2`/`#111111`),
|
|
289
|
+
which ignored the theme and never blurred. Use `useOverlayCardColors` for a card's text and edges.
|
|
279
290
|
|
|
280
291
|
## Zone-aware popovers (`useZoneClampedAlign`)
|
|
281
292
|
|
|
@@ -607,8 +618,8 @@ touches the main barrel. It's for an app that has `@tastic/core` and `@rific/upd
|
|
|
607
618
|
- Stats: `BaseStatsScreen`, `StatSection`, `StatRow`, `AchievementRow`, `LOCKED_BADGE_COLOR`,
|
|
608
619
|
`AchievementCatalogSection`, `ActivityStatSection`
|
|
609
620
|
- Chrome: `CornerActionButtons`, `ContentGutter`, `StaggeredWord`, `getStaggeredWordDuration`
|
|
610
|
-
- Overlay cards: `OverlayCard`, `OverlayBackdrop`, `useOverlayCardColors`
|
|
611
|
-
- Style tokens: `overlayStyles`, `overlayActionStyles`, `MONO_FONT
|
|
621
|
+
- Overlay cards: `OverlayCard`, `OverlayBackdrop`, `useOverlayCardColors`, `DialogHeader`, `useCompactDialog`, `isCompactDialogHeight`, `COMPACT_DIALOG_HEIGHT`
|
|
622
|
+
- Style tokens: `overlayStyles`, `overlayActionStyles`, `MONO_FONT`
|
|
612
623
|
|
|
613
624
|
Each is the same component the main entry exports and is documented above. Only the import path changes:
|
|
614
625
|
|
|
@@ -669,5 +680,5 @@ resolve module".
|
|
|
669
680
|
| `@rific/updater` | >=0.4.0, optional | main entry and `./chrome`: `BaseSettingsDialog`, `UpdateDialog` |
|
|
670
681
|
| `@tastic/profile` | >=0.4.0, optional | main entry: `PlayerSetupPanel`, `AchievementUnlockList` (`ProfileChip`) |
|
|
671
682
|
| `@tastic/split-screen` | >=0.5.0, optional | main entry: `useZoneClampedAlign` |
|
|
672
|
-
| `@shopify/react-native-skia` | >=
|
|
683
|
+
| `@shopify/react-native-skia` | >=2.6.0, optional | `TriggerGaugeHost`'s gauge (lazy-loaded behind `SkiaGate`) and `./skia-gate` |
|
|
673
684
|
| `@tastic/achievements` | >=0.2.0, optional | `AchievementCatalogSection`, `AchievementUnlockList`, type-only (`AchievementCatalogRow`, first exported in 0.2.0; `AchievementTier`); `./chrome` needs it installed only to type-check |
|
|
@@ -54,7 +54,7 @@ function TriggerGauge({ segments, litIndices, size, accentColor, mutedColor, das
|
|
|
54
54
|
const canvasSize = diameter + LIT_THICKNESS;
|
|
55
55
|
const oval = Skia.XYWHRect(LIT_THICKNESS / 2, LIT_THICKNESS / 2, diameter, diameter);
|
|
56
56
|
const unlitPath = useDerivedValue(() => {
|
|
57
|
-
const path = Skia.
|
|
57
|
+
const path = Skia.PathBuilder.Make();
|
|
58
58
|
for (let i = 0; i < segments; i++) {
|
|
59
59
|
if (litIndices.includes(i)) continue;
|
|
60
60
|
let local = 1;
|
|
@@ -68,13 +68,13 @@ function TriggerGauge({ segments, litIndices, size, accentColor, mutedColor, das
|
|
|
68
68
|
const dashCenterDeg = startDeg + (i + 0.5) * step;
|
|
69
69
|
path.addArc(oval, dashCenterDeg - 90 - sweep / 2, sweep);
|
|
70
70
|
}
|
|
71
|
-
return path;
|
|
71
|
+
return path.detach();
|
|
72
72
|
}, [segments, litIndicesKey, step, startDeg, dashAngleDeg, totalDurationMs, oval.x, oval.y, oval.width, oval.height]);
|
|
73
73
|
const litPath = useDerivedValue(() => {
|
|
74
|
-
const path = Skia.
|
|
74
|
+
const path = Skia.PathBuilder.Make();
|
|
75
75
|
if (mountProgress.value >= 1 && singleSelect) {
|
|
76
76
|
path.addArc(oval, angleDeg.value - 90 - dashAngleDeg / 2, dashAngleDeg);
|
|
77
|
-
return path;
|
|
77
|
+
return path.detach();
|
|
78
78
|
}
|
|
79
79
|
for (let i = 0; i < segments; i++) {
|
|
80
80
|
const isLitNow = litIndices.includes(i);
|
|
@@ -98,7 +98,7 @@ function TriggerGauge({ segments, litIndices, size, accentColor, mutedColor, das
|
|
|
98
98
|
const dashCenterDeg = startDeg + (i + 0.5) * step;
|
|
99
99
|
path.addArc(oval, dashCenterDeg - 90 - sweep / 2, sweep);
|
|
100
100
|
}
|
|
101
|
-
return path;
|
|
101
|
+
return path.detach();
|
|
102
102
|
}, [segments, litIndicesKey, transitionFromKey, singleSelect, step, startDeg, dashAngleDeg, totalDurationMs, oval.x, oval.y, oval.width, oval.height]);
|
|
103
103
|
if (segments < 2) return null;
|
|
104
104
|
const gaugeSizeStyle = {
|
package/dist/chrome/index.d.mts
CHANGED
|
@@ -2,7 +2,7 @@ import * as react from 'react';
|
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
3
|
import { AchievementCatalogRow } from '@tastic/achievements';
|
|
4
4
|
import { ViewRotation } from '@tastic/core';
|
|
5
|
-
import { StyleProp, ViewStyle, Insets,
|
|
5
|
+
import { StyleProp, ViewStyle, Insets, LayoutChangeEvent, TextStyle } from 'react-native';
|
|
6
6
|
|
|
7
7
|
interface Props$7 {
|
|
8
8
|
rows: AchievementCatalogRow[];
|
|
@@ -117,25 +117,23 @@ interface Props$2 {
|
|
|
117
117
|
}
|
|
118
118
|
declare function CornerActionButtons({ onBack, onSettings, fg, insets, backIcon, backLabel, hitSlop }: Props$2): react.JSX.Element;
|
|
119
119
|
|
|
120
|
+
declare const COMPACT_DIALOG_HEIGHT = 528;
|
|
121
|
+
declare function isCompactDialogHeight(height: number): boolean;
|
|
122
|
+
interface DialogHeaderProps {
|
|
123
|
+
icon: string;
|
|
124
|
+
title: string;
|
|
125
|
+
color?: string;
|
|
126
|
+
compact?: boolean;
|
|
127
|
+
style?: StyleProp<ViewStyle>;
|
|
128
|
+
}
|
|
129
|
+
declare function DialogHeader({ icon, title, color, compact, style }: DialogHeaderProps): react.JSX.Element;
|
|
130
|
+
|
|
120
131
|
declare const MONO_FONT: string;
|
|
121
132
|
|
|
122
|
-
interface OverlayCardColors {
|
|
123
|
-
fg: string;
|
|
124
|
-
fgMuted: string;
|
|
125
|
-
cardBg: string;
|
|
126
|
-
cardBorder: string;
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* @deprecated The literal black/white card colors. hud's own cards moved to the theme-driven, blur-aware
|
|
130
|
-
* OverlayCard / OverlayBackdrop / useOverlayCardColors (OverlaySurface.tsx) on 2026-10-15; this stays
|
|
131
|
-
* only until every app's own result cards have moved over too.
|
|
132
|
-
*/
|
|
133
|
-
declare function getOverlayCardColors(dark: boolean): OverlayCardColors;
|
|
134
133
|
declare const overlayStyles: {
|
|
135
134
|
card: {
|
|
136
135
|
alignItems: "center";
|
|
137
136
|
borderRadius: number;
|
|
138
|
-
borderWidth: number;
|
|
139
137
|
gap: number;
|
|
140
138
|
maxWidth: number;
|
|
141
139
|
padding: number;
|
|
@@ -178,8 +176,9 @@ declare function useOverlayCardColors(): OverlayCardThemeColors;
|
|
|
178
176
|
interface OverlayBackdropProps {
|
|
179
177
|
children?: ReactNode;
|
|
180
178
|
style?: StyleProp<ViewStyle>;
|
|
179
|
+
onLayout?: (e: LayoutChangeEvent) => void;
|
|
181
180
|
}
|
|
182
|
-
declare function OverlayBackdrop({ children, style }: OverlayBackdropProps): react.JSX.Element;
|
|
181
|
+
declare function OverlayBackdrop({ children, style, onLayout }: OverlayBackdropProps): react.JSX.Element;
|
|
183
182
|
interface OverlayCardProps {
|
|
184
183
|
children?: ReactNode;
|
|
185
184
|
style?: StyleProp<ViewStyle>;
|
|
@@ -262,4 +261,9 @@ interface UpdateDialogProps {
|
|
|
262
261
|
}
|
|
263
262
|
declare function UpdateDialog({ rotation, autoCheck, autoPrompt, onError }: UpdateDialogProps): react.JSX.Element;
|
|
264
263
|
|
|
265
|
-
|
|
264
|
+
declare function useCompactDialog(rotation?: ViewRotation): {
|
|
265
|
+
compact: boolean;
|
|
266
|
+
onLayout: (e: LayoutChangeEvent) => void;
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
export { AchievementCatalogSection, AchievementRow, ActivityStatSection, BaseSettingsDialog, type BaseSettingsDialogProps, BaseStatsScreen, COMPACT_DIALOG_HEIGHT, ConfirmDialog, type ConfirmDialogProps, ContentGutter, CornerActionButtons, DialogHeader, type DialogHeaderProps, LOCKED_BADGE_COLOR, MONO_FONT, OverlayBackdrop, type OverlayBackdropProps, OverlayCard, type OverlayCardProps, type OverlayCardThemeColors, RotatedFrame, type RotatedFrameProps, StaggeredWord, type StaggeredWordProps, StatRow, StatSection, UpdateDialog, type UpdateDialogProps, getStaggeredWordDuration, isCompactDialogHeight, overlayActionStyles, overlayStyles, useCompactDialog, useOverlayCardColors };
|
package/dist/chrome/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import * as react from 'react';
|
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
3
|
import { AchievementCatalogRow } from '@tastic/achievements';
|
|
4
4
|
import { ViewRotation } from '@tastic/core';
|
|
5
|
-
import { StyleProp, ViewStyle, Insets,
|
|
5
|
+
import { StyleProp, ViewStyle, Insets, LayoutChangeEvent, TextStyle } from 'react-native';
|
|
6
6
|
|
|
7
7
|
interface Props$7 {
|
|
8
8
|
rows: AchievementCatalogRow[];
|
|
@@ -117,25 +117,23 @@ interface Props$2 {
|
|
|
117
117
|
}
|
|
118
118
|
declare function CornerActionButtons({ onBack, onSettings, fg, insets, backIcon, backLabel, hitSlop }: Props$2): react.JSX.Element;
|
|
119
119
|
|
|
120
|
+
declare const COMPACT_DIALOG_HEIGHT = 528;
|
|
121
|
+
declare function isCompactDialogHeight(height: number): boolean;
|
|
122
|
+
interface DialogHeaderProps {
|
|
123
|
+
icon: string;
|
|
124
|
+
title: string;
|
|
125
|
+
color?: string;
|
|
126
|
+
compact?: boolean;
|
|
127
|
+
style?: StyleProp<ViewStyle>;
|
|
128
|
+
}
|
|
129
|
+
declare function DialogHeader({ icon, title, color, compact, style }: DialogHeaderProps): react.JSX.Element;
|
|
130
|
+
|
|
120
131
|
declare const MONO_FONT: string;
|
|
121
132
|
|
|
122
|
-
interface OverlayCardColors {
|
|
123
|
-
fg: string;
|
|
124
|
-
fgMuted: string;
|
|
125
|
-
cardBg: string;
|
|
126
|
-
cardBorder: string;
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* @deprecated The literal black/white card colors. hud's own cards moved to the theme-driven, blur-aware
|
|
130
|
-
* OverlayCard / OverlayBackdrop / useOverlayCardColors (OverlaySurface.tsx) on 2026-10-15; this stays
|
|
131
|
-
* only until every app's own result cards have moved over too.
|
|
132
|
-
*/
|
|
133
|
-
declare function getOverlayCardColors(dark: boolean): OverlayCardColors;
|
|
134
133
|
declare const overlayStyles: {
|
|
135
134
|
card: {
|
|
136
135
|
alignItems: "center";
|
|
137
136
|
borderRadius: number;
|
|
138
|
-
borderWidth: number;
|
|
139
137
|
gap: number;
|
|
140
138
|
maxWidth: number;
|
|
141
139
|
padding: number;
|
|
@@ -178,8 +176,9 @@ declare function useOverlayCardColors(): OverlayCardThemeColors;
|
|
|
178
176
|
interface OverlayBackdropProps {
|
|
179
177
|
children?: ReactNode;
|
|
180
178
|
style?: StyleProp<ViewStyle>;
|
|
179
|
+
onLayout?: (e: LayoutChangeEvent) => void;
|
|
181
180
|
}
|
|
182
|
-
declare function OverlayBackdrop({ children, style }: OverlayBackdropProps): react.JSX.Element;
|
|
181
|
+
declare function OverlayBackdrop({ children, style, onLayout }: OverlayBackdropProps): react.JSX.Element;
|
|
183
182
|
interface OverlayCardProps {
|
|
184
183
|
children?: ReactNode;
|
|
185
184
|
style?: StyleProp<ViewStyle>;
|
|
@@ -262,4 +261,9 @@ interface UpdateDialogProps {
|
|
|
262
261
|
}
|
|
263
262
|
declare function UpdateDialog({ rotation, autoCheck, autoPrompt, onError }: UpdateDialogProps): react.JSX.Element;
|
|
264
263
|
|
|
265
|
-
|
|
264
|
+
declare function useCompactDialog(rotation?: ViewRotation): {
|
|
265
|
+
compact: boolean;
|
|
266
|
+
onLayout: (e: LayoutChangeEvent) => void;
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
export { AchievementCatalogSection, AchievementRow, ActivityStatSection, BaseSettingsDialog, type BaseSettingsDialogProps, BaseStatsScreen, COMPACT_DIALOG_HEIGHT, ConfirmDialog, type ConfirmDialogProps, ContentGutter, CornerActionButtons, DialogHeader, type DialogHeaderProps, LOCKED_BADGE_COLOR, MONO_FONT, OverlayBackdrop, type OverlayBackdropProps, OverlayCard, type OverlayCardProps, type OverlayCardThemeColors, RotatedFrame, type RotatedFrameProps, StaggeredWord, type StaggeredWordProps, StatRow, StatSection, UpdateDialog, type UpdateDialogProps, getStaggeredWordDuration, isCompactDialogHeight, overlayActionStyles, overlayStyles, useCompactDialog, useOverlayCardColors };
|