@tastic/hud 0.12.0 → 0.13.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 +132 -11
- package/dist/chunk-32U2OIRW.mjs +77 -0
- package/dist/guide/index.d.mts +118 -0
- package/dist/guide/index.d.ts +118 -0
- package/dist/guide/index.js +543 -0
- package/dist/guide/index.mjs +428 -0
- package/dist/index.d.mts +46 -9
- package/dist/index.d.ts +46 -9
- package/dist/index.js +318 -250
- package/dist/index.mjs +283 -286
- package/package.json +32 -5
- package/src/AchievementUnlockList.tsx +98 -0
- package/src/BaseSettingsDialog.tsx +32 -1
- package/src/ConfirmDialog.tsx +4 -43
- package/src/ContentGutter.tsx +12 -5
- package/src/guide/DirectionKeysHint.tsx +96 -0
- package/src/guide/GuideProvider.tsx +87 -0
- package/src/guide/HowToPlayDialog.tsx +224 -0
- package/src/guide/SeatDevicesHint.tsx +52 -0
- package/src/guide/SeatDiagram.tsx +72 -0
- package/src/guide/SwipeHint.tsx +115 -0
- package/src/guide/guideSlice.ts +131 -0
- package/src/guide/index.ts +14 -0
- package/src/guide/types.ts +16 -0
- package/src/index.ts +2 -1
- package/src/overlayCard.ts +51 -4
|
@@ -0,0 +1,428 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getOverlayCardColors,
|
|
3
|
+
overlayActionStyles,
|
|
4
|
+
overlayStyles
|
|
5
|
+
} from "../chunk-32U2OIRW.mjs";
|
|
6
|
+
|
|
7
|
+
// src/guide/DirectionKeysHint.tsx
|
|
8
|
+
import { useAutoPaperTheme } from "@rific/auto-paper";
|
|
9
|
+
import { StyleSheet, View } from "react-native";
|
|
10
|
+
import { Icon, Text } from "react-native-paper";
|
|
11
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
12
|
+
var CAP_SIZE = 34;
|
|
13
|
+
var ARROWS = { up: "arrow-up", left: "arrow-left", down: "arrow-down", right: "arrow-right" };
|
|
14
|
+
function KeyCap({ label, icon, color }) {
|
|
15
|
+
return /* @__PURE__ */ jsx(View, { style: [styles.cap, { borderColor: color }], children: label !== void 0 ? /* @__PURE__ */ jsx(Text, { variant: "titleMedium", style: [styles.capLabel, { color }], children: label }) : /* @__PURE__ */ jsx(Icon, { source: icon, size: 20, color }) });
|
|
16
|
+
}
|
|
17
|
+
function DirectionKeysHint({ labels, axis = "both", color }) {
|
|
18
|
+
const { colors } = useAutoPaperTheme();
|
|
19
|
+
const tint = color ?? colors.primary;
|
|
20
|
+
if (axis === "vertical") {
|
|
21
|
+
const accessibilityLabel2 = labels?.up && labels.down ? `Keys ${labels.up} and ${labels.down}` : "Up and down arrow keys";
|
|
22
|
+
return /* @__PURE__ */ jsxs(View, { accessible: true, accessibilityLabel: accessibilityLabel2, style: styles.cluster, children: [
|
|
23
|
+
/* @__PURE__ */ jsx(KeyCap, { label: labels?.up, icon: ARROWS.up, color: tint }),
|
|
24
|
+
/* @__PURE__ */ jsx(KeyCap, { label: labels?.down, icon: ARROWS.down, color: tint })
|
|
25
|
+
] });
|
|
26
|
+
}
|
|
27
|
+
const accessibilityLabel = labels?.up && labels.left && labels.down && labels.right ? `Keys ${labels.up}, ${labels.left}, ${labels.down}, ${labels.right}` : "Arrow keys";
|
|
28
|
+
return /* @__PURE__ */ jsxs(View, { accessible: true, accessibilityLabel, style: styles.cluster, children: [
|
|
29
|
+
/* @__PURE__ */ jsx(KeyCap, { label: labels?.up, icon: ARROWS.up, color: tint }),
|
|
30
|
+
/* @__PURE__ */ jsxs(View, { style: styles.row, children: [
|
|
31
|
+
/* @__PURE__ */ jsx(KeyCap, { label: labels?.left, icon: ARROWS.left, color: tint }),
|
|
32
|
+
/* @__PURE__ */ jsx(KeyCap, { label: labels?.down, icon: ARROWS.down, color: tint }),
|
|
33
|
+
/* @__PURE__ */ jsx(KeyCap, { label: labels?.right, icon: ARROWS.right, color: tint })
|
|
34
|
+
] })
|
|
35
|
+
] });
|
|
36
|
+
}
|
|
37
|
+
var styles = StyleSheet.create({
|
|
38
|
+
cap: {
|
|
39
|
+
alignItems: "center",
|
|
40
|
+
borderRadius: 8,
|
|
41
|
+
borderWidth: 2,
|
|
42
|
+
height: CAP_SIZE,
|
|
43
|
+
justifyContent: "center",
|
|
44
|
+
width: CAP_SIZE
|
|
45
|
+
},
|
|
46
|
+
capLabel: {
|
|
47
|
+
fontWeight: "bold"
|
|
48
|
+
},
|
|
49
|
+
cluster: {
|
|
50
|
+
alignItems: "center",
|
|
51
|
+
gap: 6
|
|
52
|
+
},
|
|
53
|
+
row: {
|
|
54
|
+
flexDirection: "row",
|
|
55
|
+
gap: 6
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// src/guide/GuideProvider.tsx
|
|
60
|
+
import { createContext, useCallback, useContext, useEffect as useEffect2, useMemo, useRef as useRef2, useState as useState2 } from "react";
|
|
61
|
+
|
|
62
|
+
// src/guide/HowToPlayDialog.tsx
|
|
63
|
+
import { useAutoPaperTheme as useAutoPaperTheme2 } from "@rific/auto-paper";
|
|
64
|
+
import { Button } from "@rific/feedback-press";
|
|
65
|
+
import { useEffect, useRef, useState } from "react";
|
|
66
|
+
import { BackHandler, ScrollView, StyleSheet as StyleSheet2, useWindowDimensions, View as View2 } from "react-native";
|
|
67
|
+
import { Portal, Text as Text2 } from "react-native-paper";
|
|
68
|
+
import { useReducedMotion } from "react-native-reanimated";
|
|
69
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
70
|
+
var OVERLAY_GUTTER = 24;
|
|
71
|
+
var CARD_PADDING = 24;
|
|
72
|
+
var MAX_CARD_WIDTH = 360;
|
|
73
|
+
var MAX_CARD_WIDTH_TURNED = 520;
|
|
74
|
+
var ART_HEIGHT = 132;
|
|
75
|
+
var COMPACT_BELOW = 480;
|
|
76
|
+
var ART_HEIGHT_COMPACT = 88;
|
|
77
|
+
function getGuideCardSize(windowWidth, windowHeight, rotation) {
|
|
78
|
+
const turned = rotation === 90 || rotation === -90;
|
|
79
|
+
const availableWidth = (turned ? windowHeight : windowWidth) - OVERLAY_GUTTER * 2;
|
|
80
|
+
const availableHeight = (turned ? windowWidth : windowHeight) - OVERLAY_GUTTER * 2;
|
|
81
|
+
const width = Math.min(turned ? MAX_CARD_WIDTH_TURNED : MAX_CARD_WIDTH, availableWidth);
|
|
82
|
+
return {
|
|
83
|
+
width,
|
|
84
|
+
pageWidth: width - CARD_PADDING * 2,
|
|
85
|
+
maxHeight: availableHeight,
|
|
86
|
+
artHeight: availableHeight < COMPACT_BELOW ? ART_HEIGHT_COMPACT : ART_HEIGHT
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
function HowToPlayCard({ steps, onFinish, onSkip, rotation = 0 }) {
|
|
90
|
+
const { dark, colors } = useAutoPaperTheme2();
|
|
91
|
+
const { width: windowWidth, height: windowHeight } = useWindowDimensions();
|
|
92
|
+
const reducedMotion = useReducedMotion();
|
|
93
|
+
const [index, setIndex] = useState(0);
|
|
94
|
+
const scrollRef = useRef(null);
|
|
95
|
+
useEffect(() => {
|
|
96
|
+
const subscription = BackHandler.addEventListener("hardwareBackPress", () => {
|
|
97
|
+
onSkip();
|
|
98
|
+
return true;
|
|
99
|
+
});
|
|
100
|
+
return () => subscription.remove();
|
|
101
|
+
}, [onSkip]);
|
|
102
|
+
const { fg, cardBg, cardBorder, fgMuted } = getOverlayCardColors(dark);
|
|
103
|
+
const { width: cardWidth, pageWidth, maxHeight, artHeight } = getGuideCardSize(windowWidth, windowHeight, rotation);
|
|
104
|
+
const rotationStyle = rotation === 0 ? void 0 : { transform: [{ rotate: `${rotation}deg` }] };
|
|
105
|
+
const isFirst = index === 0;
|
|
106
|
+
const isLast = index === steps.length - 1;
|
|
107
|
+
const isOnly = steps.length === 1;
|
|
108
|
+
const artBackground = dark ? "rgba(255,255,255,0.06)" : "rgba(0,0,0,0.05)";
|
|
109
|
+
const targetRef = useRef(null);
|
|
110
|
+
function goTo(next) {
|
|
111
|
+
targetRef.current = next;
|
|
112
|
+
setIndex(next);
|
|
113
|
+
scrollRef.current?.scrollTo({ x: next * pageWidth, animated: !reducedMotion });
|
|
114
|
+
}
|
|
115
|
+
function syncToOffset(offsetX) {
|
|
116
|
+
const page = Math.round(offsetX / pageWidth);
|
|
117
|
+
if (page < 0 || page >= steps.length) return;
|
|
118
|
+
if (targetRef.current !== null) {
|
|
119
|
+
if (page === targetRef.current) targetRef.current = null;
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
setIndex(page);
|
|
123
|
+
}
|
|
124
|
+
function handleScroll(e) {
|
|
125
|
+
syncToOffset(e.nativeEvent.contentOffset.x);
|
|
126
|
+
}
|
|
127
|
+
function handleMomentumEnd(e) {
|
|
128
|
+
targetRef.current = null;
|
|
129
|
+
syncToOffset(e.nativeEvent.contentOffset.x);
|
|
130
|
+
}
|
|
131
|
+
return /* @__PURE__ */ jsx2(Portal, { children: /* @__PURE__ */ jsx2(View2, { style: [overlayStyles.overlay, styles2.overlay], children: /* @__PURE__ */ jsxs2(View2, { accessibilityViewIsModal: true, style: [overlayStyles.card, styles2.card, { width: cardWidth, maxHeight, backgroundColor: cardBg, borderColor: cardBorder }, rotationStyle], children: [
|
|
132
|
+
/* @__PURE__ */ jsx2(ScrollView, { ref: scrollRef, horizontal: true, pagingEnabled: true, showsHorizontalScrollIndicator: false, onScroll: handleScroll, scrollEventThrottle: 16, onMomentumScrollEnd: handleMomentumEnd, style: [styles2.pager, { width: pageWidth }], children: steps.map((step, i) => /* @__PURE__ */ jsxs2(ScrollView, { nestedScrollEnabled: true, showsVerticalScrollIndicator: false, style: { width: pageWidth }, contentContainerStyle: styles2.page, children: [
|
|
133
|
+
step.art !== void 0 && /* @__PURE__ */ jsx2(View2, { style: [styles2.art, { height: artHeight, backgroundColor: artBackground }], children: step.art }),
|
|
134
|
+
/* @__PURE__ */ jsx2(Text2, { variant: "headlineSmall", style: [styles2.title, { color: fg }], children: step.title }),
|
|
135
|
+
/* @__PURE__ */ jsx2(Text2, { variant: "bodyMedium", style: [styles2.body, { color: fg }], children: step.body })
|
|
136
|
+
] }, i)) }),
|
|
137
|
+
steps.length > 1 && /* @__PURE__ */ jsx2(View2, { accessible: true, accessibilityLabel: `Step ${index + 1} of ${steps.length}`, style: styles2.dots, children: steps.map((_, i) => /* @__PURE__ */ jsx2(View2, { style: [styles2.dot, { backgroundColor: i === index ? colors.primary : fgMuted }] }, i)) }),
|
|
138
|
+
/* @__PURE__ */ jsxs2(View2, { style: overlayActionStyles.actions, children: [
|
|
139
|
+
!isOnly && /* @__PURE__ */ jsx2(Button, { mode: "outlined", onPress: isFirst ? onSkip : () => goTo(index - 1), style: overlayActionStyles.actionButton, children: isFirst ? "Skip" : "Back" }),
|
|
140
|
+
/* @__PURE__ */ jsx2(Button, { mode: "contained", onPress: isLast ? onFinish : () => goTo(index + 1), style: isOnly ? overlayActionStyles.actionButtonSingle : overlayActionStyles.actionButton, buttonColor: colors.primary, textColor: colors.onPrimary, children: isLast ? "Ready" : "Next" })
|
|
141
|
+
] })
|
|
142
|
+
] }) }) });
|
|
143
|
+
}
|
|
144
|
+
function HowToPlayDialog({ visible, steps, ...rest }) {
|
|
145
|
+
if (!visible || steps.length === 0) return null;
|
|
146
|
+
return /* @__PURE__ */ jsx2(HowToPlayCard, { steps, ...rest });
|
|
147
|
+
}
|
|
148
|
+
var styles2 = StyleSheet2.create({
|
|
149
|
+
art: {
|
|
150
|
+
alignItems: "center",
|
|
151
|
+
borderRadius: 12,
|
|
152
|
+
justifyContent: "center",
|
|
153
|
+
overflow: "hidden",
|
|
154
|
+
width: "100%"
|
|
155
|
+
},
|
|
156
|
+
body: {
|
|
157
|
+
textAlign: "center"
|
|
158
|
+
},
|
|
159
|
+
// Additive on top of overlayCard's own shared `card` shape — its default 32px padding is tighter
|
|
160
|
+
// here (a paged card wants more width for its art) and the shared 16px gap is right.
|
|
161
|
+
card: {
|
|
162
|
+
padding: CARD_PADDING
|
|
163
|
+
},
|
|
164
|
+
dot: {
|
|
165
|
+
borderRadius: 4,
|
|
166
|
+
height: 8,
|
|
167
|
+
width: 8
|
|
168
|
+
},
|
|
169
|
+
dots: {
|
|
170
|
+
flexDirection: "row",
|
|
171
|
+
gap: 8
|
|
172
|
+
},
|
|
173
|
+
overlay: {
|
|
174
|
+
paddingHorizontal: OVERLAY_GUTTER
|
|
175
|
+
},
|
|
176
|
+
page: {
|
|
177
|
+
alignItems: "center",
|
|
178
|
+
gap: 12
|
|
179
|
+
},
|
|
180
|
+
pager: {
|
|
181
|
+
flexShrink: 1
|
|
182
|
+
},
|
|
183
|
+
title: {
|
|
184
|
+
fontWeight: "bold",
|
|
185
|
+
textAlign: "center"
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
// src/guide/GuideProvider.tsx
|
|
190
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
191
|
+
var noop = () => {
|
|
192
|
+
};
|
|
193
|
+
var GuideContext = createContext({ isOpen: false, open: noop, close: noop, requestAutoShow: noop });
|
|
194
|
+
function GuideProvider({ steps, currentVersion, seenVersion, onSeen, rotation, children }) {
|
|
195
|
+
const [isOpen, setIsOpen] = useState2(false);
|
|
196
|
+
const autoShownRef = useRef2(false);
|
|
197
|
+
const unseen = seenVersion < currentVersion;
|
|
198
|
+
const open = useCallback(() => setIsOpen(true), []);
|
|
199
|
+
const close = useCallback(() => {
|
|
200
|
+
setIsOpen(false);
|
|
201
|
+
if (unseen) onSeen(currentVersion);
|
|
202
|
+
}, [unseen, onSeen, currentVersion]);
|
|
203
|
+
const requestAutoShow = useCallback(() => {
|
|
204
|
+
if (!unseen || autoShownRef.current) return;
|
|
205
|
+
autoShownRef.current = true;
|
|
206
|
+
setIsOpen(true);
|
|
207
|
+
}, [unseen]);
|
|
208
|
+
const value = useMemo(() => ({ isOpen, open, close, requestAutoShow }), [isOpen, open, close, requestAutoShow]);
|
|
209
|
+
return /* @__PURE__ */ jsxs3(GuideContext.Provider, { value, children: [
|
|
210
|
+
children,
|
|
211
|
+
/* @__PURE__ */ jsx3(HowToPlayDialog, { visible: isOpen, steps, onFinish: close, onSkip: close, rotation })
|
|
212
|
+
] });
|
|
213
|
+
}
|
|
214
|
+
function useGuide() {
|
|
215
|
+
return useContext(GuideContext);
|
|
216
|
+
}
|
|
217
|
+
function useAutoShowGuide(enabled = true) {
|
|
218
|
+
const { requestAutoShow } = useGuide();
|
|
219
|
+
useEffect2(() => {
|
|
220
|
+
if (enabled) requestAutoShow();
|
|
221
|
+
}, [enabled, requestAutoShow]);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// src/guide/guideSlice.ts
|
|
225
|
+
var REHYDRATE = "persist/REHYDRATE";
|
|
226
|
+
function createGuideSlice({ currentVersion, mountKey = "guide", persistKey = "root" }) {
|
|
227
|
+
const MARK_SEEN = `${mountKey}/markSeen`;
|
|
228
|
+
const initialState = { versionSeen: 0 };
|
|
229
|
+
function markSeen(version) {
|
|
230
|
+
return { type: MARK_SEEN, payload: version };
|
|
231
|
+
}
|
|
232
|
+
function reducer(state = initialState, action) {
|
|
233
|
+
if (action.type === REHYDRATE) {
|
|
234
|
+
if (action.key !== void 0 && action.key !== persistKey) return state;
|
|
235
|
+
const payload = action.payload;
|
|
236
|
+
if (!payload) return state;
|
|
237
|
+
const persisted = payload[mountKey];
|
|
238
|
+
if (typeof persisted?.versionSeen === "number") return { versionSeen: persisted.versionSeen };
|
|
239
|
+
return { versionSeen: currentVersion };
|
|
240
|
+
}
|
|
241
|
+
if (action.type === MARK_SEEN && typeof action.payload === "number") {
|
|
242
|
+
return { versionSeen: Math.max(state.versionSeen, action.payload) };
|
|
243
|
+
}
|
|
244
|
+
return state;
|
|
245
|
+
}
|
|
246
|
+
function selectVersionSeen(rootState) {
|
|
247
|
+
return rootState[mountKey]?.versionSeen ?? 0;
|
|
248
|
+
}
|
|
249
|
+
return { actions: { markSeen }, reducer, selectVersionSeen };
|
|
250
|
+
}
|
|
251
|
+
function createReturningPlayerMigrate(storage, legacyKeys) {
|
|
252
|
+
return async (state, version) => {
|
|
253
|
+
if (state !== void 0 || legacyKeys.length === 0) return state;
|
|
254
|
+
try {
|
|
255
|
+
const values = await Promise.all(legacyKeys.map((key) => storage.getItem(key)));
|
|
256
|
+
return values.some((value) => value !== null) ? { _persist: { version, rehydrated: false } } : void 0;
|
|
257
|
+
} catch {
|
|
258
|
+
return void 0;
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// src/guide/SeatDevicesHint.tsx
|
|
264
|
+
import { useAutoPaperTheme as useAutoPaperTheme3 } from "@rific/auto-paper";
|
|
265
|
+
import { StyleSheet as StyleSheet3, View as View3 } from "react-native";
|
|
266
|
+
import { Icon as Icon2 } from "react-native-paper";
|
|
267
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
268
|
+
var ICON = {
|
|
269
|
+
keyboard: { source: "keyboard-outline", size: 56 },
|
|
270
|
+
mouse: { source: "mouse-outline", size: 44 }
|
|
271
|
+
};
|
|
272
|
+
var ORDER = ["keyboard", "mouse"];
|
|
273
|
+
function SeatDevicesHint({ devices, seatColors }) {
|
|
274
|
+
const { colors } = useAutoPaperTheme3();
|
|
275
|
+
const tints = seatColors ?? [colors.primary, colors.secondary];
|
|
276
|
+
const accessibilityLabel = devices.map((device, i) => `Player ${i + 1} uses the ${device}`).join(", ");
|
|
277
|
+
return /* @__PURE__ */ jsx4(View3, { accessible: true, accessibilityLabel, style: styles3.row, children: ORDER.map((device) => {
|
|
278
|
+
const seats = devices.flatMap((d, i) => d === device ? [i] : []);
|
|
279
|
+
if (seats.length === 0) return null;
|
|
280
|
+
const color = seats.length === 1 ? tints[seats[0]] ?? colors.onSurface : colors.onSurface;
|
|
281
|
+
return /* @__PURE__ */ jsx4(Icon2, { source: ICON[device].source, size: ICON[device].size, color }, device);
|
|
282
|
+
}) });
|
|
283
|
+
}
|
|
284
|
+
var styles3 = StyleSheet3.create({
|
|
285
|
+
row: {
|
|
286
|
+
alignItems: "center",
|
|
287
|
+
flexDirection: "row",
|
|
288
|
+
gap: 20
|
|
289
|
+
}
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
// src/guide/SeatDiagram.tsx
|
|
293
|
+
import { useAutoPaperTheme as useAutoPaperTheme4 } from "@rific/auto-paper";
|
|
294
|
+
import { StyleSheet as StyleSheet4, View as View4 } from "react-native";
|
|
295
|
+
import { Text as Text3 } from "react-native-paper";
|
|
296
|
+
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
297
|
+
var DEVICE_WIDTH = 88;
|
|
298
|
+
var DEVICE_HEIGHT = 120;
|
|
299
|
+
function SeatDiagram({ topColor, bottomColor, topLabel = "P2", bottomLabel = "P1" }) {
|
|
300
|
+
const { colors } = useAutoPaperTheme4();
|
|
301
|
+
const top = topColor ?? colors.secondary;
|
|
302
|
+
const bottom = bottomColor ?? colors.primary;
|
|
303
|
+
return /* @__PURE__ */ jsxs4(View4, { accessible: true, accessibilityLabel: `${bottomLabel} plays the bottom half, ${topLabel} plays the top half`, style: [styles4.device, { borderColor: colors.onSurface }], children: [
|
|
304
|
+
/* @__PURE__ */ jsxs4(View4, { style: [styles4.half, { borderColor: top }], children: [
|
|
305
|
+
/* @__PURE__ */ jsx5(View4, { style: [StyleSheet4.absoluteFill, styles4.tint, { backgroundColor: top }] }),
|
|
306
|
+
/* @__PURE__ */ jsx5(Text3, { variant: "titleMedium", style: [styles4.label, styles4.flipped, { color: top }], children: topLabel })
|
|
307
|
+
] }),
|
|
308
|
+
/* @__PURE__ */ jsxs4(View4, { style: [styles4.half, styles4.bottomHalf, { borderColor: bottom }], children: [
|
|
309
|
+
/* @__PURE__ */ jsx5(View4, { style: [StyleSheet4.absoluteFill, styles4.tint, { backgroundColor: bottom }] }),
|
|
310
|
+
/* @__PURE__ */ jsx5(Text3, { variant: "titleMedium", style: [styles4.label, { color: bottom }], children: bottomLabel })
|
|
311
|
+
] })
|
|
312
|
+
] });
|
|
313
|
+
}
|
|
314
|
+
var styles4 = StyleSheet4.create({
|
|
315
|
+
bottomHalf: {
|
|
316
|
+
borderTopWidth: 0
|
|
317
|
+
},
|
|
318
|
+
device: {
|
|
319
|
+
borderRadius: 16,
|
|
320
|
+
borderWidth: 2,
|
|
321
|
+
height: DEVICE_HEIGHT,
|
|
322
|
+
overflow: "hidden",
|
|
323
|
+
width: DEVICE_WIDTH
|
|
324
|
+
},
|
|
325
|
+
flipped: {
|
|
326
|
+
transform: [{ rotate: "180deg" }]
|
|
327
|
+
},
|
|
328
|
+
half: {
|
|
329
|
+
alignItems: "center",
|
|
330
|
+
borderWidth: 2,
|
|
331
|
+
flex: 1,
|
|
332
|
+
justifyContent: "center"
|
|
333
|
+
},
|
|
334
|
+
label: {
|
|
335
|
+
fontWeight: "bold"
|
|
336
|
+
},
|
|
337
|
+
// A wash of the seat color behind its own label rather than an rgba() fill — the theme's colors
|
|
338
|
+
// aren't guaranteed to be 6-digit hex, so an opacity layer is the only alpha that always works.
|
|
339
|
+
tint: {
|
|
340
|
+
opacity: 0.2
|
|
341
|
+
}
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
// src/guide/SwipeHint.tsx
|
|
345
|
+
import { useAutoPaperTheme as useAutoPaperTheme5 } from "@rific/auto-paper";
|
|
346
|
+
import { useEffect as useEffect3 } from "react";
|
|
347
|
+
import { StyleSheet as StyleSheet5, View as View5 } from "react-native";
|
|
348
|
+
import { Icon as Icon3 } from "react-native-paper";
|
|
349
|
+
import Animated, { Easing, useAnimatedStyle, useReducedMotion as useReducedMotion2, useSharedValue, withRepeat, withSequence, withTiming } from "react-native-reanimated";
|
|
350
|
+
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
351
|
+
var DOT_COUNT = 7;
|
|
352
|
+
var FINGER_SIZE = 28;
|
|
353
|
+
var MOUSE_SIZE = 30;
|
|
354
|
+
var SWEEP_MS = 900;
|
|
355
|
+
var PAUSE_MS = 500;
|
|
356
|
+
var ARROW_ICON = { up: "arrow-up", down: "arrow-down", left: "arrow-left", right: "arrow-right" };
|
|
357
|
+
function SwipeHint({ direction = "right", pointer = "finger", color, length = 96 }) {
|
|
358
|
+
const { colors } = useAutoPaperTheme5();
|
|
359
|
+
const tint = color ?? colors.primary;
|
|
360
|
+
const reducedMotion = useReducedMotion2();
|
|
361
|
+
const progress = useSharedValue(0.5);
|
|
362
|
+
const horizontal = direction === "left" || direction === "right";
|
|
363
|
+
const sign = direction === "right" || direction === "down" ? 1 : -1;
|
|
364
|
+
useEffect3(() => {
|
|
365
|
+
if (reducedMotion) {
|
|
366
|
+
progress.value = 0.5;
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
progress.value = 0;
|
|
370
|
+
progress.value = withRepeat(withSequence(withTiming(1, { duration: SWEEP_MS, easing: Easing.out(Easing.cubic) }), withTiming(1, { duration: PAUSE_MS }), withTiming(0, { duration: 0 })), -1);
|
|
371
|
+
}, [reducedMotion]);
|
|
372
|
+
const fingerStyle = useAnimatedStyle(() => {
|
|
373
|
+
const travel = (progress.value - 0.5) * length * sign;
|
|
374
|
+
return {
|
|
375
|
+
opacity: reducedMotion ? 1 : Math.min(1, progress.value * 6, (1 - progress.value) * 6 + 1e-3),
|
|
376
|
+
transform: horizontal ? [{ translateX: travel }] : [{ translateY: travel }]
|
|
377
|
+
};
|
|
378
|
+
});
|
|
379
|
+
const axis = horizontal ? sign > 0 ? "row" : "row-reverse" : sign > 0 ? "column" : "column-reverse";
|
|
380
|
+
return /* @__PURE__ */ jsxs5(View5, { accessibilityLabel: `${pointer === "mouse" ? "Drag" : "Swipe"} ${direction}`, accessible: true, style: [styles5.path, { flexDirection: axis }], children: [
|
|
381
|
+
/* @__PURE__ */ jsx6(View5, { style: [styles5.dots, { flexDirection: axis, [horizontal ? "width" : "height"]: length }], children: Array.from({ length: DOT_COUNT }, (_, i) => /* @__PURE__ */ jsx6(View5, { style: [styles5.dot, { backgroundColor: tint, opacity: 0.35 + 0.65 * i / (DOT_COUNT - 1) }] }, i)) }),
|
|
382
|
+
/* @__PURE__ */ jsx6(Icon3, { source: ARROW_ICON[direction], size: 28, color: tint }),
|
|
383
|
+
pointer === "mouse" ? /* @__PURE__ */ jsx6(Animated.View, { style: [styles5.mouse, fingerStyle], children: /* @__PURE__ */ jsx6(Icon3, { source: "mouse", size: MOUSE_SIZE, color: tint }) }) : /* @__PURE__ */ jsx6(Animated.View, { style: [styles5.finger, { borderColor: tint }, fingerStyle] })
|
|
384
|
+
] });
|
|
385
|
+
}
|
|
386
|
+
var styles5 = StyleSheet5.create({
|
|
387
|
+
dot: {
|
|
388
|
+
borderRadius: 3,
|
|
389
|
+
height: 6,
|
|
390
|
+
width: 6
|
|
391
|
+
},
|
|
392
|
+
dots: {
|
|
393
|
+
alignItems: "center",
|
|
394
|
+
justifyContent: "space-between"
|
|
395
|
+
},
|
|
396
|
+
// Centered on the whole path (not on the dots row alone) by the container's own alignItems/
|
|
397
|
+
// justifyContent, then pushed along the axis by its own animated translate — absolute so it never
|
|
398
|
+
// takes space from the dots and arrowhead it's drawn over.
|
|
399
|
+
finger: {
|
|
400
|
+
borderRadius: FINGER_SIZE / 2,
|
|
401
|
+
borderWidth: 3,
|
|
402
|
+
height: FINGER_SIZE,
|
|
403
|
+
position: "absolute",
|
|
404
|
+
width: FINGER_SIZE
|
|
405
|
+
},
|
|
406
|
+
// Positioned exactly like `finger` (absolute, centered by the container, moved by the same animated
|
|
407
|
+
// translate); only what's drawn differs.
|
|
408
|
+
mouse: {
|
|
409
|
+
position: "absolute"
|
|
410
|
+
},
|
|
411
|
+
path: {
|
|
412
|
+
alignItems: "center",
|
|
413
|
+
justifyContent: "center"
|
|
414
|
+
}
|
|
415
|
+
});
|
|
416
|
+
export {
|
|
417
|
+
DirectionKeysHint,
|
|
418
|
+
GuideProvider,
|
|
419
|
+
HowToPlayDialog,
|
|
420
|
+
SeatDevicesHint,
|
|
421
|
+
SeatDiagram,
|
|
422
|
+
SwipeHint,
|
|
423
|
+
createGuideSlice,
|
|
424
|
+
createReturningPlayerMigrate,
|
|
425
|
+
getGuideCardSize,
|
|
426
|
+
useAutoShowGuide,
|
|
427
|
+
useGuide
|
|
428
|
+
};
|
package/dist/index.d.mts
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode, RefObject } from 'react';
|
|
3
|
-
import { AchievementCatalogRow } from '@tastic/achievements';
|
|
3
|
+
import { AchievementCatalogRow, AchievementTier } from '@tastic/achievements';
|
|
4
|
+
import { Profile } from '@tastic/profile';
|
|
5
|
+
import { ViewStyle, StyleProp, View, TextStyle, LayoutChangeEvent } from 'react-native';
|
|
4
6
|
import { ViewRotation } from '@tastic/core';
|
|
5
|
-
import { StyleProp, ViewStyle, View, TextStyle, LayoutChangeEvent } from 'react-native';
|
|
6
7
|
import { SeedColor } from '@rific/auto-paper';
|
|
7
|
-
import { Profile } from '@tastic/profile';
|
|
8
8
|
export { SkiaGate, SkiaGateProps } from './SkiaGate.mjs';
|
|
9
9
|
|
|
10
|
-
interface Props$
|
|
10
|
+
interface Props$f {
|
|
11
11
|
rows: AchievementCatalogRow[];
|
|
12
12
|
label?: string;
|
|
13
13
|
fg?: string;
|
|
14
14
|
fgMuted?: string;
|
|
15
15
|
}
|
|
16
|
-
declare function AchievementCatalogSection({ rows, label, fg, fgMuted: fgMutedOverride }: Props$
|
|
16
|
+
declare function AchievementCatalogSection({ rows, label, fg, fgMuted: fgMutedOverride }: Props$f): react.JSX.Element;
|
|
17
17
|
|
|
18
18
|
declare const LOCKED_BADGE_COLOR = "rgba(128,128,128,0.3)";
|
|
19
|
-
interface Props$
|
|
19
|
+
interface Props$e {
|
|
20
20
|
icon: string;
|
|
21
21
|
title: string;
|
|
22
22
|
description: string;
|
|
@@ -29,7 +29,27 @@ interface Props$d {
|
|
|
29
29
|
fgMuted?: string;
|
|
30
30
|
sectionBg?: string;
|
|
31
31
|
}
|
|
32
|
-
declare function AchievementRow({ icon, title, description, badgeColor, unlockedLabel, checkColor, progress, deviceMarker, fg: fgOverride, fgMuted: fgMutedOverride, sectionBg: sectionBgOverride }: Props$
|
|
32
|
+
declare function AchievementRow({ icon, title, description, badgeColor, unlockedLabel, checkColor, progress, deviceMarker, fg: fgOverride, fgMuted: fgMutedOverride, sectionBg: sectionBgOverride }: Props$e): react.JSX.Element;
|
|
33
|
+
|
|
34
|
+
interface UnlockedAchievement {
|
|
35
|
+
id: string;
|
|
36
|
+
icon: string;
|
|
37
|
+
title: string;
|
|
38
|
+
tier: AchievementTier;
|
|
39
|
+
}
|
|
40
|
+
interface AchievementUnlockOwner {
|
|
41
|
+
profile?: Profile | null;
|
|
42
|
+
color: string;
|
|
43
|
+
}
|
|
44
|
+
interface Props$d<Seat extends number> {
|
|
45
|
+
unlocks: Partial<Record<Seat, UnlockedAchievement[]>>;
|
|
46
|
+
seats: readonly Seat[];
|
|
47
|
+
owners: Record<Seat, AchievementUnlockOwner>;
|
|
48
|
+
tierColors: Record<AchievementTier, string>;
|
|
49
|
+
fg?: string;
|
|
50
|
+
style?: ViewStyle;
|
|
51
|
+
}
|
|
52
|
+
declare function AchievementUnlockList<Seat extends number>({ unlocks, seats, owners, tierColors, fg: fgOverride, style }: Props$d<Seat>): react.JSX.Element | null;
|
|
33
53
|
|
|
34
54
|
interface ActivityStats {
|
|
35
55
|
distinctDaysPlayed: number;
|
|
@@ -55,9 +75,10 @@ interface BaseSettingsDialogProps {
|
|
|
55
75
|
hideAppearance?: boolean;
|
|
56
76
|
hideUpdateCheck?: boolean;
|
|
57
77
|
onUpdateError?: (message: string) => void;
|
|
78
|
+
onShowHowToPlay?: () => void;
|
|
58
79
|
children?: ReactNode;
|
|
59
80
|
}
|
|
60
|
-
declare function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, version, lockOrientation, onLockOrientationChange, deferBottomEdgeGestures, onDeferBottomEdgeGestures, hideSound, hideHaptics, hideAppearance, hideUpdateCheck, onUpdateError, children }: BaseSettingsDialogProps): react.JSX.Element;
|
|
81
|
+
declare function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, version, lockOrientation, onLockOrientationChange, deferBottomEdgeGestures, onDeferBottomEdgeGestures, hideSound, hideHaptics, hideAppearance, hideUpdateCheck, onUpdateError, onShowHowToPlay, children }: BaseSettingsDialogProps): react.JSX.Element;
|
|
61
82
|
|
|
62
83
|
type MD3TextVariant = 'displayLarge' | 'displayMedium' | 'displaySmall' | 'headlineLarge' | 'headlineMedium' | 'headlineSmall' | 'titleLarge' | 'titleMedium' | 'titleSmall' | 'labelLarge' | 'labelMedium' | 'labelSmall' | 'bodyLarge' | 'bodyMedium' | 'bodySmall';
|
|
63
84
|
interface Props$b {
|
|
@@ -296,6 +317,22 @@ declare const overlayStyles: {
|
|
|
296
317
|
top: number;
|
|
297
318
|
};
|
|
298
319
|
};
|
|
320
|
+
declare const overlayActionStyles: {
|
|
321
|
+
actionButton: {
|
|
322
|
+
flexGrow: number;
|
|
323
|
+
minWidth: number;
|
|
324
|
+
};
|
|
325
|
+
actionButtonSingle: {
|
|
326
|
+
minWidth: number;
|
|
327
|
+
};
|
|
328
|
+
actions: {
|
|
329
|
+
flexDirection: "row";
|
|
330
|
+
flexWrap: "wrap";
|
|
331
|
+
gap: number;
|
|
332
|
+
justifyContent: "center";
|
|
333
|
+
width: "100%";
|
|
334
|
+
};
|
|
335
|
+
};
|
|
299
336
|
|
|
300
337
|
declare function getColorPopoverId(idPrefix: string): string;
|
|
301
338
|
declare function getCpuDifficultyPopoverId(idPrefix: string): string;
|
|
@@ -437,4 +474,4 @@ declare function useQuitConfirmation(hasProgress: () => boolean, onConfirmedBack
|
|
|
437
474
|
|
|
438
475
|
declare function useZoneClampedAlign(open: boolean, contentWidth: number, contentHeight: number, rotation?: PopoverRotation): ReturnType<typeof useAutoAlign>;
|
|
439
476
|
|
|
440
|
-
export { AchievementCatalogSection, AchievementRow, ActivityStatSection, type AlignResult, BaseSettingsDialog, type BaseSettingsDialogProps, BaseStatsScreen, ConfirmDialog, type ConfirmDialogProps, ContentGutter, ControlSchemePicker, type ControlSchemePickerProps, CornerActionButtons, type CornerStatusBadgeSeat, CornerStatusBadges, type CornerStatusBadgesProps, InlineColorPicker, LABELED_DROPDOWN_POPOVER_WIDTH, LOCKED_BADGE_COLOR, LabeledDropdown, type LabeledDropdownOption, MONO_FONT, type MenuOption, type MenuSection, type MultiSelectSection, type OrientationMode, type OverlayCardColors, PlayerSetupPanel, type PlayerSetupPanelProps, type PopoverAlign, PopoverBody, type PopoverHost, type PopoverRotation, type PopoverVerticalAlign, PressAwayOverlay, type QuitConfirmation, ReadyButton, SectionedDropdown, SharedActionBand, type SingleSelectSection, StaggeredWord, type StaggeredWordProps, StatRow, StatSection, TriggerGaugeHost, type TriggerGaugeProps, UpdateDialog, type UpdateDialogProps, getColorPopoverId, getCpuDifficultyPopoverId, getInlineColorPickerContentSize, getLabeledDropdownContentHeight, getOverlayCardColors, getStaggeredWordDuration, loadSkiaWeb, overlayStyles, useAutoAlign, usePopoverHost, useQuitConfirmation, useZoneClampedAlign };
|
|
477
|
+
export { AchievementCatalogSection, AchievementRow, AchievementUnlockList, type AchievementUnlockOwner, ActivityStatSection, type AlignResult, BaseSettingsDialog, type BaseSettingsDialogProps, BaseStatsScreen, ConfirmDialog, type ConfirmDialogProps, ContentGutter, ControlSchemePicker, type ControlSchemePickerProps, CornerActionButtons, type CornerStatusBadgeSeat, CornerStatusBadges, type CornerStatusBadgesProps, InlineColorPicker, LABELED_DROPDOWN_POPOVER_WIDTH, LOCKED_BADGE_COLOR, LabeledDropdown, type LabeledDropdownOption, MONO_FONT, type MenuOption, type MenuSection, type MultiSelectSection, type OrientationMode, type OverlayCardColors, PlayerSetupPanel, type PlayerSetupPanelProps, type PopoverAlign, PopoverBody, type PopoverHost, type PopoverRotation, type PopoverVerticalAlign, PressAwayOverlay, type QuitConfirmation, ReadyButton, SectionedDropdown, SharedActionBand, type SingleSelectSection, StaggeredWord, type StaggeredWordProps, StatRow, StatSection, TriggerGaugeHost, type TriggerGaugeProps, type UnlockedAchievement, UpdateDialog, type UpdateDialogProps, getColorPopoverId, getCpuDifficultyPopoverId, getInlineColorPickerContentSize, getLabeledDropdownContentHeight, getOverlayCardColors, getStaggeredWordDuration, loadSkiaWeb, overlayActionStyles, overlayStyles, useAutoAlign, usePopoverHost, useQuitConfirmation, useZoneClampedAlign };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode, RefObject } from 'react';
|
|
3
|
-
import { AchievementCatalogRow } from '@tastic/achievements';
|
|
3
|
+
import { AchievementCatalogRow, AchievementTier } from '@tastic/achievements';
|
|
4
|
+
import { Profile } from '@tastic/profile';
|
|
5
|
+
import { ViewStyle, StyleProp, View, TextStyle, LayoutChangeEvent } from 'react-native';
|
|
4
6
|
import { ViewRotation } from '@tastic/core';
|
|
5
|
-
import { StyleProp, ViewStyle, View, TextStyle, LayoutChangeEvent } from 'react-native';
|
|
6
7
|
import { SeedColor } from '@rific/auto-paper';
|
|
7
|
-
import { Profile } from '@tastic/profile';
|
|
8
8
|
export { SkiaGate, SkiaGateProps } from './SkiaGate.js';
|
|
9
9
|
|
|
10
|
-
interface Props$
|
|
10
|
+
interface Props$f {
|
|
11
11
|
rows: AchievementCatalogRow[];
|
|
12
12
|
label?: string;
|
|
13
13
|
fg?: string;
|
|
14
14
|
fgMuted?: string;
|
|
15
15
|
}
|
|
16
|
-
declare function AchievementCatalogSection({ rows, label, fg, fgMuted: fgMutedOverride }: Props$
|
|
16
|
+
declare function AchievementCatalogSection({ rows, label, fg, fgMuted: fgMutedOverride }: Props$f): react.JSX.Element;
|
|
17
17
|
|
|
18
18
|
declare const LOCKED_BADGE_COLOR = "rgba(128,128,128,0.3)";
|
|
19
|
-
interface Props$
|
|
19
|
+
interface Props$e {
|
|
20
20
|
icon: string;
|
|
21
21
|
title: string;
|
|
22
22
|
description: string;
|
|
@@ -29,7 +29,27 @@ interface Props$d {
|
|
|
29
29
|
fgMuted?: string;
|
|
30
30
|
sectionBg?: string;
|
|
31
31
|
}
|
|
32
|
-
declare function AchievementRow({ icon, title, description, badgeColor, unlockedLabel, checkColor, progress, deviceMarker, fg: fgOverride, fgMuted: fgMutedOverride, sectionBg: sectionBgOverride }: Props$
|
|
32
|
+
declare function AchievementRow({ icon, title, description, badgeColor, unlockedLabel, checkColor, progress, deviceMarker, fg: fgOverride, fgMuted: fgMutedOverride, sectionBg: sectionBgOverride }: Props$e): react.JSX.Element;
|
|
33
|
+
|
|
34
|
+
interface UnlockedAchievement {
|
|
35
|
+
id: string;
|
|
36
|
+
icon: string;
|
|
37
|
+
title: string;
|
|
38
|
+
tier: AchievementTier;
|
|
39
|
+
}
|
|
40
|
+
interface AchievementUnlockOwner {
|
|
41
|
+
profile?: Profile | null;
|
|
42
|
+
color: string;
|
|
43
|
+
}
|
|
44
|
+
interface Props$d<Seat extends number> {
|
|
45
|
+
unlocks: Partial<Record<Seat, UnlockedAchievement[]>>;
|
|
46
|
+
seats: readonly Seat[];
|
|
47
|
+
owners: Record<Seat, AchievementUnlockOwner>;
|
|
48
|
+
tierColors: Record<AchievementTier, string>;
|
|
49
|
+
fg?: string;
|
|
50
|
+
style?: ViewStyle;
|
|
51
|
+
}
|
|
52
|
+
declare function AchievementUnlockList<Seat extends number>({ unlocks, seats, owners, tierColors, fg: fgOverride, style }: Props$d<Seat>): react.JSX.Element | null;
|
|
33
53
|
|
|
34
54
|
interface ActivityStats {
|
|
35
55
|
distinctDaysPlayed: number;
|
|
@@ -55,9 +75,10 @@ interface BaseSettingsDialogProps {
|
|
|
55
75
|
hideAppearance?: boolean;
|
|
56
76
|
hideUpdateCheck?: boolean;
|
|
57
77
|
onUpdateError?: (message: string) => void;
|
|
78
|
+
onShowHowToPlay?: () => void;
|
|
58
79
|
children?: ReactNode;
|
|
59
80
|
}
|
|
60
|
-
declare function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, version, lockOrientation, onLockOrientationChange, deferBottomEdgeGestures, onDeferBottomEdgeGestures, hideSound, hideHaptics, hideAppearance, hideUpdateCheck, onUpdateError, children }: BaseSettingsDialogProps): react.JSX.Element;
|
|
81
|
+
declare function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, version, lockOrientation, onLockOrientationChange, deferBottomEdgeGestures, onDeferBottomEdgeGestures, hideSound, hideHaptics, hideAppearance, hideUpdateCheck, onUpdateError, onShowHowToPlay, children }: BaseSettingsDialogProps): react.JSX.Element;
|
|
61
82
|
|
|
62
83
|
type MD3TextVariant = 'displayLarge' | 'displayMedium' | 'displaySmall' | 'headlineLarge' | 'headlineMedium' | 'headlineSmall' | 'titleLarge' | 'titleMedium' | 'titleSmall' | 'labelLarge' | 'labelMedium' | 'labelSmall' | 'bodyLarge' | 'bodyMedium' | 'bodySmall';
|
|
63
84
|
interface Props$b {
|
|
@@ -296,6 +317,22 @@ declare const overlayStyles: {
|
|
|
296
317
|
top: number;
|
|
297
318
|
};
|
|
298
319
|
};
|
|
320
|
+
declare const overlayActionStyles: {
|
|
321
|
+
actionButton: {
|
|
322
|
+
flexGrow: number;
|
|
323
|
+
minWidth: number;
|
|
324
|
+
};
|
|
325
|
+
actionButtonSingle: {
|
|
326
|
+
minWidth: number;
|
|
327
|
+
};
|
|
328
|
+
actions: {
|
|
329
|
+
flexDirection: "row";
|
|
330
|
+
flexWrap: "wrap";
|
|
331
|
+
gap: number;
|
|
332
|
+
justifyContent: "center";
|
|
333
|
+
width: "100%";
|
|
334
|
+
};
|
|
335
|
+
};
|
|
299
336
|
|
|
300
337
|
declare function getColorPopoverId(idPrefix: string): string;
|
|
301
338
|
declare function getCpuDifficultyPopoverId(idPrefix: string): string;
|
|
@@ -437,4 +474,4 @@ declare function useQuitConfirmation(hasProgress: () => boolean, onConfirmedBack
|
|
|
437
474
|
|
|
438
475
|
declare function useZoneClampedAlign(open: boolean, contentWidth: number, contentHeight: number, rotation?: PopoverRotation): ReturnType<typeof useAutoAlign>;
|
|
439
476
|
|
|
440
|
-
export { AchievementCatalogSection, AchievementRow, ActivityStatSection, type AlignResult, BaseSettingsDialog, type BaseSettingsDialogProps, BaseStatsScreen, ConfirmDialog, type ConfirmDialogProps, ContentGutter, ControlSchemePicker, type ControlSchemePickerProps, CornerActionButtons, type CornerStatusBadgeSeat, CornerStatusBadges, type CornerStatusBadgesProps, InlineColorPicker, LABELED_DROPDOWN_POPOVER_WIDTH, LOCKED_BADGE_COLOR, LabeledDropdown, type LabeledDropdownOption, MONO_FONT, type MenuOption, type MenuSection, type MultiSelectSection, type OrientationMode, type OverlayCardColors, PlayerSetupPanel, type PlayerSetupPanelProps, type PopoverAlign, PopoverBody, type PopoverHost, type PopoverRotation, type PopoverVerticalAlign, PressAwayOverlay, type QuitConfirmation, ReadyButton, SectionedDropdown, SharedActionBand, type SingleSelectSection, StaggeredWord, type StaggeredWordProps, StatRow, StatSection, TriggerGaugeHost, type TriggerGaugeProps, UpdateDialog, type UpdateDialogProps, getColorPopoverId, getCpuDifficultyPopoverId, getInlineColorPickerContentSize, getLabeledDropdownContentHeight, getOverlayCardColors, getStaggeredWordDuration, loadSkiaWeb, overlayStyles, useAutoAlign, usePopoverHost, useQuitConfirmation, useZoneClampedAlign };
|
|
477
|
+
export { AchievementCatalogSection, AchievementRow, AchievementUnlockList, type AchievementUnlockOwner, ActivityStatSection, type AlignResult, BaseSettingsDialog, type BaseSettingsDialogProps, BaseStatsScreen, ConfirmDialog, type ConfirmDialogProps, ContentGutter, ControlSchemePicker, type ControlSchemePickerProps, CornerActionButtons, type CornerStatusBadgeSeat, CornerStatusBadges, type CornerStatusBadgesProps, InlineColorPicker, LABELED_DROPDOWN_POPOVER_WIDTH, LOCKED_BADGE_COLOR, LabeledDropdown, type LabeledDropdownOption, MONO_FONT, type MenuOption, type MenuSection, type MultiSelectSection, type OrientationMode, type OverlayCardColors, PlayerSetupPanel, type PlayerSetupPanelProps, type PopoverAlign, PopoverBody, type PopoverHost, type PopoverRotation, type PopoverVerticalAlign, PressAwayOverlay, type QuitConfirmation, ReadyButton, SectionedDropdown, SharedActionBand, type SingleSelectSection, StaggeredWord, type StaggeredWordProps, StatRow, StatSection, TriggerGaugeHost, type TriggerGaugeProps, type UnlockedAchievement, UpdateDialog, type UpdateDialogProps, getColorPopoverId, getCpuDifficultyPopoverId, getInlineColorPickerContentSize, getLabeledDropdownContentHeight, getOverlayCardColors, getStaggeredWordDuration, loadSkiaWeb, overlayActionStyles, overlayStyles, useAutoAlign, usePopoverHost, useQuitConfirmation, useZoneClampedAlign };
|