@tastic/hud 0.14.0 → 0.14.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +5 -2
- package/dist/index.mjs +5 -2
- package/package.json +1 -1
- package/src/BaseSettingsDialog.tsx +15 -4
package/dist/index.d.mts
CHANGED
|
@@ -78,7 +78,7 @@ interface BaseSettingsDialogProps {
|
|
|
78
78
|
onShowHowToPlay?: () => void;
|
|
79
79
|
children?: ReactNode;
|
|
80
80
|
}
|
|
81
|
-
declare function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, version, lockOrientation, onLockOrientationChange, deferBottomEdgeGestures, onDeferBottomEdgeGestures, hideSound, hideHaptics, hideAppearance, hideUpdateCheck, onUpdateError, onShowHowToPlay, 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 | null;
|
|
82
82
|
|
|
83
83
|
type MD3TextVariant = 'displayLarge' | 'displayMedium' | 'displaySmall' | 'headlineLarge' | 'headlineMedium' | 'headlineSmall' | 'titleLarge' | 'titleMedium' | 'titleSmall' | 'labelLarge' | 'labelMedium' | 'labelSmall' | 'bodyLarge' | 'bodyMedium' | 'bodySmall';
|
|
84
84
|
interface Props$b {
|
package/dist/index.d.ts
CHANGED
|
@@ -78,7 +78,7 @@ interface BaseSettingsDialogProps {
|
|
|
78
78
|
onShowHowToPlay?: () => void;
|
|
79
79
|
children?: ReactNode;
|
|
80
80
|
}
|
|
81
|
-
declare function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, version, lockOrientation, onLockOrientationChange, deferBottomEdgeGestures, onDeferBottomEdgeGestures, hideSound, hideHaptics, hideAppearance, hideUpdateCheck, onUpdateError, onShowHowToPlay, 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 | null;
|
|
82
82
|
|
|
83
83
|
type MD3TextVariant = 'displayLarge' | 'displayMedium' | 'displaySmall' | 'headlineLarge' | 'headlineMedium' | 'headlineSmall' | 'titleLarge' | 'titleMedium' | 'titleSmall' | 'labelLarge' | 'labelMedium' | 'labelSmall' | 'bodyLarge' | 'bodyMedium' | 'bodySmall';
|
|
84
84
|
interface Props$b {
|
package/dist/index.js
CHANGED
|
@@ -625,26 +625,29 @@ function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, ve
|
|
|
625
625
|
onInfo: (title, message) => setInfoMessage({ title, message })
|
|
626
626
|
});
|
|
627
627
|
const updateManifestDate = updateManifest ? new Date(updateManifest.createdAt) : null;
|
|
628
|
+
const [opened, setOpened] = (0, import_react4.useState)(visible);
|
|
629
|
+
if (visible && !opened) setOpened(true);
|
|
628
630
|
const showLockOrientation = isTouchPrimary && lockOrientation !== void 0 && onLockOrientationChange !== void 0;
|
|
629
631
|
const showEdgeGuard = import_react_native10.Platform.OS === "ios" && deferBottomEdgeGestures !== void 0 && onDeferBottomEdgeGestures !== void 0;
|
|
630
632
|
const showHaptics = import_react_native10.Platform.OS !== "web" && !hideHaptics;
|
|
631
633
|
const showSound = !hideSound;
|
|
632
634
|
const showAppearance = !hideAppearance;
|
|
633
635
|
const showUpdateCheck = import_react_native10.Platform.OS !== "web" && !hideUpdateCheck;
|
|
636
|
+
if (!opened) return null;
|
|
634
637
|
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_paper8.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(RotatedFrame, { rotation, rotatedSafeArea: true, portalHost: true, passThrough: true, children: [
|
|
635
638
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_auto_paper7.Dialog, { visible, onDismiss, style: styles8.dialog, children: [
|
|
636
639
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_auto_paper7.Dialog.Title, { children: "Settings" }),
|
|
637
640
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_auto_paper7.Dialog.ScrollArea, { style: styles8.scrollArea, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native10.ScrollView, { contentContainerStyle: styles8.content, showsVerticalScrollIndicator: false, children: [
|
|
638
641
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native10.View, { style: styles8.toggleGroup, children: [
|
|
639
642
|
showLockOrientation && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_feedback_press2.TouchableRipple, { onPress: () => onLockOrientationChange(!lockOrientation), style: styles8.toggleButton, accessibilityLabel: `Lock orientation ${lockOrientation ? "on" : "off"}`, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native10.View, { style: styles8.toggleContent, children: [
|
|
640
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SettingIcon, { source: lockOrientation ? "lock" : "lock-open-variant-outline", color: lockOrientation ? colors.
|
|
643
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SettingIcon, { source: lockOrientation ? "lock" : "lock-open-variant-outline", color: lockOrientation ? colors.tertiary : colors.onSurfaceVariant, containerColor: lockOrientation ? colors.tertiaryContainer : colors.surfaceVariant }),
|
|
641
644
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native10.View, { style: styles8.flexShrink, children: [
|
|
642
645
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_paper8.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Lock Orientation" }),
|
|
643
646
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_paper8.Text, { variant: "bodySmall", numberOfLines: 1, style: { color: colors.onSurfaceVariant }, children: "Pins the current layout" })
|
|
644
647
|
] })
|
|
645
648
|
] }) }),
|
|
646
649
|
showEdgeGuard && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_feedback_press2.TouchableRipple, { onPress: () => onDeferBottomEdgeGestures(!deferBottomEdgeGestures), style: styles8.toggleButton, accessibilityLabel: `Edge guard ${deferBottomEdgeGestures ? "on" : "off"}`, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native10.View, { style: styles8.toggleContent, children: [
|
|
647
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SettingIcon, { source: deferBottomEdgeGestures ? "shield-check-outline" : "shield-off-outline", color: deferBottomEdgeGestures ? colors.
|
|
650
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SettingIcon, { source: deferBottomEdgeGestures ? "shield-check-outline" : "shield-off-outline", color: deferBottomEdgeGestures ? colors.tertiary : colors.onSurfaceVariant, containerColor: deferBottomEdgeGestures ? colors.tertiaryContainer : colors.surfaceVariant }),
|
|
648
651
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native10.View, { style: styles8.flexShrink, children: [
|
|
649
652
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_paper8.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Edge Guard" }),
|
|
650
653
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_paper8.Text, { variant: "bodySmall", numberOfLines: 1, style: { color: colors.onSurfaceVariant }, children: "Requires a second swipe" })
|
package/dist/index.mjs
CHANGED
|
@@ -346,26 +346,29 @@ function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, ve
|
|
|
346
346
|
onInfo: (title, message) => setInfoMessage({ title, message })
|
|
347
347
|
});
|
|
348
348
|
const updateManifestDate = updateManifest ? new Date(updateManifest.createdAt) : null;
|
|
349
|
+
const [opened, setOpened] = useState2(visible);
|
|
350
|
+
if (visible && !opened) setOpened(true);
|
|
349
351
|
const showLockOrientation = isTouchPrimary && lockOrientation !== void 0 && onLockOrientationChange !== void 0;
|
|
350
352
|
const showEdgeGuard = Platform2.OS === "ios" && deferBottomEdgeGestures !== void 0 && onDeferBottomEdgeGestures !== void 0;
|
|
351
353
|
const showHaptics = Platform2.OS !== "web" && !hideHaptics;
|
|
352
354
|
const showSound = !hideSound;
|
|
353
355
|
const showAppearance = !hideAppearance;
|
|
354
356
|
const showUpdateCheck = Platform2.OS !== "web" && !hideUpdateCheck;
|
|
357
|
+
if (!opened) return null;
|
|
355
358
|
return /* @__PURE__ */ jsx9(Portal3, { children: /* @__PURE__ */ jsxs8(RotatedFrame, { rotation, rotatedSafeArea: true, portalHost: true, passThrough: true, children: [
|
|
356
359
|
/* @__PURE__ */ jsxs8(Dialog, { visible, onDismiss, style: styles8.dialog, children: [
|
|
357
360
|
/* @__PURE__ */ jsx9(Dialog.Title, { children: "Settings" }),
|
|
358
361
|
/* @__PURE__ */ jsx9(Dialog.ScrollArea, { style: styles8.scrollArea, children: /* @__PURE__ */ jsxs8(ScrollView, { contentContainerStyle: styles8.content, showsVerticalScrollIndicator: false, children: [
|
|
359
362
|
/* @__PURE__ */ jsxs8(View7, { style: styles8.toggleGroup, children: [
|
|
360
363
|
showLockOrientation && /* @__PURE__ */ jsx9(TouchableRipple, { onPress: () => onLockOrientationChange(!lockOrientation), style: styles8.toggleButton, accessibilityLabel: `Lock orientation ${lockOrientation ? "on" : "off"}`, children: /* @__PURE__ */ jsxs8(View7, { style: styles8.toggleContent, children: [
|
|
361
|
-
/* @__PURE__ */ jsx9(SettingIcon, { source: lockOrientation ? "lock" : "lock-open-variant-outline", color: lockOrientation ? colors.
|
|
364
|
+
/* @__PURE__ */ jsx9(SettingIcon, { source: lockOrientation ? "lock" : "lock-open-variant-outline", color: lockOrientation ? colors.tertiary : colors.onSurfaceVariant, containerColor: lockOrientation ? colors.tertiaryContainer : colors.surfaceVariant }),
|
|
362
365
|
/* @__PURE__ */ jsxs8(View7, { style: styles8.flexShrink, children: [
|
|
363
366
|
/* @__PURE__ */ jsx9(Text7, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Lock Orientation" }),
|
|
364
367
|
/* @__PURE__ */ jsx9(Text7, { variant: "bodySmall", numberOfLines: 1, style: { color: colors.onSurfaceVariant }, children: "Pins the current layout" })
|
|
365
368
|
] })
|
|
366
369
|
] }) }),
|
|
367
370
|
showEdgeGuard && /* @__PURE__ */ jsx9(TouchableRipple, { onPress: () => onDeferBottomEdgeGestures(!deferBottomEdgeGestures), style: styles8.toggleButton, accessibilityLabel: `Edge guard ${deferBottomEdgeGestures ? "on" : "off"}`, children: /* @__PURE__ */ jsxs8(View7, { style: styles8.toggleContent, children: [
|
|
368
|
-
/* @__PURE__ */ jsx9(SettingIcon, { source: deferBottomEdgeGestures ? "shield-check-outline" : "shield-off-outline", color: deferBottomEdgeGestures ? colors.
|
|
371
|
+
/* @__PURE__ */ jsx9(SettingIcon, { source: deferBottomEdgeGestures ? "shield-check-outline" : "shield-off-outline", color: deferBottomEdgeGestures ? colors.tertiary : colors.onSurfaceVariant, containerColor: deferBottomEdgeGestures ? colors.tertiaryContainer : colors.surfaceVariant }),
|
|
369
372
|
/* @__PURE__ */ jsxs8(View7, { style: styles8.flexShrink, children: [
|
|
370
373
|
/* @__PURE__ */ jsx9(Text7, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Edge Guard" }),
|
|
371
374
|
/* @__PURE__ */ jsx9(Text7, { variant: "bodySmall", numberOfLines: 1, style: { color: colors.onSurfaceVariant }, children: "Requires a second swipe" })
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tastic/hud",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.2",
|
|
4
4
|
"description": "Visual component kit for local-multiplayer React Native games: inline (non-modal) popovers, dropdowns, color pickers, gauges, ready buttons, and dialogs, built to stay scoped to one player's own zone on a shared screen",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react-native",
|
|
@@ -18,7 +18,9 @@ interface SettingIconProps {
|
|
|
18
18
|
|
|
19
19
|
// Small colored badge per row (icon tinted on its own MD3 container color) — echoes the
|
|
20
20
|
// primary/secondary/tertiary triad that's already each consuming app's own identity, so the
|
|
21
|
-
// settings list picks up that same palette instead of introducing new colors of its own.
|
|
21
|
+
// settings list picks up that same palette instead of introducing new colors of its own. Every
|
|
22
|
+
// on/off row (Lock Orientation, Edge Guard, Sound, Haptics) is tertiary while on, and an app adding
|
|
23
|
+
// its own toggle rows should match; secondary is for the always-on action row (How to Play).
|
|
22
24
|
function SettingIcon({ source, color, containerColor }: SettingIconProps) {
|
|
23
25
|
return (
|
|
24
26
|
<View style={[styles.iconBadge, { backgroundColor: containerColor }]}>
|
|
@@ -123,6 +125,14 @@ export function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverr
|
|
|
123
125
|
onInfo: (title, message) => setInfoMessage({ title, message })
|
|
124
126
|
})
|
|
125
127
|
const updateManifestDate = updateManifest ? new Date(updateManifest.createdAt) : null
|
|
128
|
+
// The frame below is mounted from the first open on and then kept, so the Dialog's close fade
|
|
129
|
+
// still plays after `visible` turns false. Never mounting it before that keeps a screen that never
|
|
130
|
+
// opens Settings free of the extra (pass-through) layer, mounts the Portal at open time like the
|
|
131
|
+
// Dialog's own Portal always was (so it lands above portals mounted earlier), and means nothing
|
|
132
|
+
// here needs a Paper Portal.Host until the sheet is actually opened. The update and info cards are
|
|
133
|
+
// only reachable from inside the sheet, so they never need it earlier either.
|
|
134
|
+
const [opened, setOpened] = useState(visible)
|
|
135
|
+
if (visible && !opened) setOpened(true)
|
|
126
136
|
|
|
127
137
|
const showLockOrientation = isTouchPrimary && lockOrientation !== undefined && onLockOrientationChange !== undefined
|
|
128
138
|
const showEdgeGuard = Platform.OS === 'ios' && deferBottomEdgeGestures !== undefined && onDeferBottomEdgeGestures !== undefined
|
|
@@ -139,8 +149,9 @@ export function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverr
|
|
|
139
149
|
// to the turned footprint, with rotated safe-area insets and its own Portal.Host. The Dialog and the
|
|
140
150
|
// two ConfirmDialogs below portal into THAT host, so they lay out against the turned window with no
|
|
141
151
|
// transform of their own (hence rotation={0} on the ConfirmDialogs). The frame is pass-through at
|
|
142
|
-
// every level and stays mounted
|
|
152
|
+
// every level and stays mounted once the sheet has opened, which keeps the Dialog's close fade; at
|
|
143
153
|
// rotation 0 it is an identity frame.
|
|
154
|
+
if (!opened) return null
|
|
144
155
|
return (
|
|
145
156
|
<Portal>
|
|
146
157
|
<RotatedFrame rotation={rotation} rotatedSafeArea portalHost passThrough>
|
|
@@ -164,7 +175,7 @@ export function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverr
|
|
|
164
175
|
{showLockOrientation && (
|
|
165
176
|
<TouchableRipple onPress={() => onLockOrientationChange!(!lockOrientation)} style={styles.toggleButton} accessibilityLabel={`Lock orientation ${lockOrientation ? 'on' : 'off'}`}>
|
|
166
177
|
<View style={styles.toggleContent}>
|
|
167
|
-
<SettingIcon source={lockOrientation ? 'lock' : 'lock-open-variant-outline'} color={lockOrientation ? colors.
|
|
178
|
+
<SettingIcon source={lockOrientation ? 'lock' : 'lock-open-variant-outline'} color={lockOrientation ? colors.tertiary : colors.onSurfaceVariant} containerColor={lockOrientation ? colors.tertiaryContainer : colors.surfaceVariant} />
|
|
168
179
|
<View style={styles.flexShrink}>
|
|
169
180
|
<Text variant='bodyLarge' style={{ color: colors.onSurface }}>
|
|
170
181
|
Lock Orientation
|
|
@@ -186,7 +197,7 @@ export function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverr
|
|
|
186
197
|
{showEdgeGuard && (
|
|
187
198
|
<TouchableRipple onPress={() => onDeferBottomEdgeGestures!(!deferBottomEdgeGestures)} style={styles.toggleButton} accessibilityLabel={`Edge guard ${deferBottomEdgeGestures ? 'on' : 'off'}`}>
|
|
188
199
|
<View style={styles.toggleContent}>
|
|
189
|
-
<SettingIcon source={deferBottomEdgeGestures ? 'shield-check-outline' : 'shield-off-outline'} color={deferBottomEdgeGestures ? colors.
|
|
200
|
+
<SettingIcon source={deferBottomEdgeGestures ? 'shield-check-outline' : 'shield-off-outline'} color={deferBottomEdgeGestures ? colors.tertiary : colors.onSurfaceVariant} containerColor={deferBottomEdgeGestures ? colors.tertiaryContainer : colors.surfaceVariant} />
|
|
190
201
|
<View style={styles.flexShrink}>
|
|
191
202
|
<Text variant='bodyLarge' style={{ color: colors.onSurface }}>
|
|
192
203
|
Edge Guard
|