@tastic/hud 0.6.0 → 0.8.1
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 +48 -8
- package/dist/SkiaGate.d.mts +13 -0
- package/dist/SkiaGate.d.ts +13 -0
- package/dist/SkiaGate.js +45 -0
- package/dist/SkiaGate.mjs +6 -0
- package/dist/chunk-XEOFR236.mjs +21 -0
- package/dist/index.d.mts +124 -75
- package/dist/index.d.ts +124 -75
- package/dist/index.js +476 -328
- package/dist/index.mjs +440 -310
- package/package.json +13 -6
- package/src/BaseSettingsDialog.tsx +9 -6
- package/src/BaseStatsScreen.tsx +10 -7
- package/src/ConfirmDialog.tsx +104 -0
- package/src/ControlSchemePicker.tsx +53 -0
- package/src/CornerActionButtons.tsx +10 -2
- package/src/CornerStatusBadges.tsx +87 -0
- package/src/InlineColorPicker.tsx +10 -4
- package/src/SectionedDropdown.tsx +17 -3
- package/src/SkiaGate.tsx +45 -0
- package/src/SkiaGate.web.tsx +9 -0
- package/src/TriggerGaugeHost.tsx +12 -20
- package/src/index.ts +11 -7
- package/src/useAutoAlign.ts +58 -16
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SkiaGate
|
|
3
|
+
} from "./chunk-XEOFR236.mjs";
|
|
4
|
+
|
|
1
5
|
// src/AchievementRow.tsx
|
|
2
6
|
import { useAutoPaperTheme } from "@rific/auto-paper";
|
|
3
7
|
import { StyleSheet, View } from "react-native";
|
|
@@ -70,7 +74,7 @@ var styles = StyleSheet.create({
|
|
|
70
74
|
import { AutoAppearancePicker, Dialog, useAutoPaperTheme as useAutoPaperTheme2 } from "@rific/auto-paper";
|
|
71
75
|
import { Button, SoundContext, TouchableRipple, useHapticSettings, useSoundSettings, useVibration } from "@rific/feedback-press";
|
|
72
76
|
import { useUpdater } from "@rific/updater";
|
|
73
|
-
import { useIsTouchPrimaryDevice } from "@tastic/core";
|
|
77
|
+
import { useIsTouchPrimaryDevice, useRotation } from "@tastic/core";
|
|
74
78
|
import { useContext, useState } from "react";
|
|
75
79
|
import { Platform, ScrollView, StyleSheet as StyleSheet2, View as View2 } from "react-native";
|
|
76
80
|
import { Icon as Icon2, Portal, Text as Text2 } from "react-native-paper";
|
|
@@ -78,8 +82,10 @@ import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
|
78
82
|
function SettingIcon({ source, color, containerColor }) {
|
|
79
83
|
return /* @__PURE__ */ jsx2(View2, { style: [styles2.iconBadge, { backgroundColor: containerColor }], children: /* @__PURE__ */ jsx2(Icon2, { source, size: 18, color }) });
|
|
80
84
|
}
|
|
81
|
-
function BaseSettingsDialog({ visible, onDismiss, rotation
|
|
85
|
+
function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, version, lockOrientation, onLockOrientationChange, deferBottomEdgeGestures, onDeferBottomEdgeGestures, hideSound = false, hideHaptics = false, hideAppearance = false, hideUpdateCheck = false, onUpdateError, children }) {
|
|
82
86
|
const { dark, colors } = useAutoPaperTheme2();
|
|
87
|
+
const ambientRotation = useRotation();
|
|
88
|
+
const rotation = rotationOverride ?? ambientRotation;
|
|
83
89
|
const isTouchPrimary = useIsTouchPrimaryDevice();
|
|
84
90
|
const { settings: hapticSettings, set: setHapticSettings } = useHapticSettings();
|
|
85
91
|
const { settings: soundSettings, set: setSoundSettings } = useSoundSettings();
|
|
@@ -271,12 +277,15 @@ var styles2 = StyleSheet2.create({
|
|
|
271
277
|
// src/BaseStatsScreen.tsx
|
|
272
278
|
import { useAutoPaperTheme as useAutoPaperTheme3 } from "@rific/auto-paper";
|
|
273
279
|
import { Button as Button2, IconButton } from "@rific/feedback-press";
|
|
280
|
+
import { useRotation as useRotation2 } from "@tastic/core";
|
|
274
281
|
import { useState as useState2 } from "react";
|
|
275
282
|
import { ScrollView as ScrollView2, StyleSheet as StyleSheet3, View as View3 } from "react-native";
|
|
276
283
|
import { Icon as Icon3, Portal as Portal2, Text as Text3 } from "react-native-paper";
|
|
277
284
|
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
278
|
-
function BaseStatsScreen({ rotation
|
|
285
|
+
function BaseStatsScreen({ rotation: rotationOverride, title = "Achievements", titleVariant = "headlineSmall", onBack, insets, onReset, resetLabel = "Reset All Stats", resetConfirmTitle = "Reset Everything?", resetConfirmBody = "This permanently erases all stats and achievements. This cannot be undone.", fg: fgOverride, bg: bgOverride, cardBg: cardBgOverride, accentColor: accentColorOverride, children }) {
|
|
279
286
|
const { dark, colors } = useAutoPaperTheme3();
|
|
287
|
+
const ambientRotation = useRotation2();
|
|
288
|
+
const rotation = rotationOverride ?? ambientRotation;
|
|
280
289
|
const [confirmResetVisible, setConfirmResetVisible] = useState2(false);
|
|
281
290
|
const showReset = !!onReset;
|
|
282
291
|
const fg = fgOverride ?? (dark ? "#FFFFFF" : "#000000");
|
|
@@ -369,20 +378,79 @@ var styles3 = StyleSheet3.create({
|
|
|
369
378
|
}
|
|
370
379
|
});
|
|
371
380
|
|
|
381
|
+
// src/ConfirmDialog.tsx
|
|
382
|
+
import { useAutoPaperTheme as useAutoPaperTheme4 } from "@rific/auto-paper";
|
|
383
|
+
import { Button as Button3 } from "@rific/feedback-press";
|
|
384
|
+
import { StyleSheet as StyleSheet4, View as View4 } from "react-native";
|
|
385
|
+
import { Icon as Icon4, Portal as Portal3, Text as Text4 } from "react-native-paper";
|
|
386
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
387
|
+
function ConfirmDialog({ visible, title, message, confirmLabel, cancelLabel, onConfirm, onCancel, rotation = 0, icon = "help-circle-outline", destructive = false }) {
|
|
388
|
+
const { dark, colors } = useAutoPaperTheme4();
|
|
389
|
+
if (!visible) return null;
|
|
390
|
+
const fg = dark ? "#FFFFFF" : "#000000";
|
|
391
|
+
const cardBg = dark ? "#111111" : "#F2F2F2";
|
|
392
|
+
const cardBorder = dark ? "rgba(255,255,255,0.2)" : "rgba(0,0,0,0.2)";
|
|
393
|
+
const accent = destructive ? colors.danger : colors.primary;
|
|
394
|
+
const onAccent = destructive ? colors.onDanger : colors.onPrimary;
|
|
395
|
+
return /* @__PURE__ */ jsx4(Portal3, { children: /* @__PURE__ */ jsx4(View4, { style: styles4.overlay, children: /* @__PURE__ */ jsxs4(View4, { style: [styles4.card, { backgroundColor: cardBg, borderColor: cardBorder }, rotation % 360 !== 0 && { transform: [{ rotate: `${rotation}deg` }] }], children: [
|
|
396
|
+
/* @__PURE__ */ jsx4(Icon4, { source: icon, size: 64, color: accent }),
|
|
397
|
+
/* @__PURE__ */ jsx4(Text4, { variant: "headlineLarge", style: [styles4.title, { color: accent }], children: title }),
|
|
398
|
+
/* @__PURE__ */ jsx4(Text4, { variant: "bodyLarge", style: [styles4.body, { color: fg }], children: message }),
|
|
399
|
+
/* @__PURE__ */ jsxs4(View4, { style: styles4.actions, children: [
|
|
400
|
+
/* @__PURE__ */ jsx4(Button3, { mode: "outlined", onPress: onCancel, style: styles4.actionButton, children: cancelLabel }),
|
|
401
|
+
/* @__PURE__ */ jsx4(Button3, { mode: "contained", onPress: onConfirm, style: styles4.actionButton, buttonColor: accent, textColor: onAccent, children: confirmLabel })
|
|
402
|
+
] })
|
|
403
|
+
] }) }) });
|
|
404
|
+
}
|
|
405
|
+
var styles4 = StyleSheet4.create({
|
|
406
|
+
actionButton: {
|
|
407
|
+
flex: 1
|
|
408
|
+
},
|
|
409
|
+
actions: {
|
|
410
|
+
flexDirection: "row",
|
|
411
|
+
gap: 12,
|
|
412
|
+
width: "100%"
|
|
413
|
+
},
|
|
414
|
+
body: {
|
|
415
|
+
textAlign: "center"
|
|
416
|
+
},
|
|
417
|
+
card: {
|
|
418
|
+
alignItems: "center",
|
|
419
|
+
borderRadius: 20,
|
|
420
|
+
borderWidth: 1,
|
|
421
|
+
gap: 16,
|
|
422
|
+
maxWidth: 360,
|
|
423
|
+
padding: 32
|
|
424
|
+
},
|
|
425
|
+
overlay: {
|
|
426
|
+
alignItems: "center",
|
|
427
|
+
backgroundColor: "rgba(0,0,0,0.72)",
|
|
428
|
+
bottom: 0,
|
|
429
|
+
justifyContent: "center",
|
|
430
|
+
left: 0,
|
|
431
|
+
position: "absolute",
|
|
432
|
+
right: 0,
|
|
433
|
+
top: 0
|
|
434
|
+
},
|
|
435
|
+
title: {
|
|
436
|
+
fontWeight: "bold"
|
|
437
|
+
}
|
|
438
|
+
});
|
|
439
|
+
|
|
372
440
|
// src/ContentGutter.tsx
|
|
373
441
|
import { computeContentBounds } from "@tastic/core";
|
|
374
|
-
import { StyleSheet as
|
|
375
|
-
import { jsx as
|
|
442
|
+
import { StyleSheet as StyleSheet5, useWindowDimensions, View as View5 } from "react-native";
|
|
443
|
+
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
376
444
|
function ContentGutter({ maxContentWidth, leftGutter, rightGutter, style, children }) {
|
|
377
445
|
const { width: windowWidth } = useWindowDimensions();
|
|
378
446
|
const { contentWidth, gutterWidth } = computeContentBounds(windowWidth, maxContentWidth ?? Infinity);
|
|
379
|
-
return /* @__PURE__ */
|
|
380
|
-
/* @__PURE__ */
|
|
381
|
-
/* @__PURE__ */
|
|
382
|
-
/* @__PURE__ */
|
|
447
|
+
return /* @__PURE__ */ jsxs5(View5, { style: [styles5.row, style], children: [
|
|
448
|
+
/* @__PURE__ */ jsx5(View5, { style: [styles5.gutter, { width: gutterWidth }], children: leftGutter }),
|
|
449
|
+
/* @__PURE__ */ jsx5(View5, { style: { width: contentWidth }, children }),
|
|
450
|
+
/* @__PURE__ */ jsx5(View5, { style: [styles5.gutter, { width: gutterWidth }], children: rightGutter })
|
|
383
451
|
] });
|
|
384
452
|
}
|
|
385
|
-
var
|
|
453
|
+
var styles5 = StyleSheet5.create({
|
|
386
454
|
// overflow:'hidden' keeps an oversized leftGutter/rightGutter from bleeding into the content
|
|
387
455
|
// column instead of clipping cleanly at its own real width.
|
|
388
456
|
gutter: {
|
|
@@ -393,39 +461,24 @@ var styles4 = StyleSheet4.create({
|
|
|
393
461
|
}
|
|
394
462
|
});
|
|
395
463
|
|
|
396
|
-
// src/
|
|
397
|
-
import {
|
|
398
|
-
import {
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
}
|
|
406
|
-
var styles5 = StyleSheet5.create({
|
|
407
|
-
back: {
|
|
408
|
-
position: "absolute"
|
|
409
|
-
},
|
|
410
|
-
topRight: {
|
|
411
|
-
position: "absolute"
|
|
412
|
-
}
|
|
413
|
-
});
|
|
464
|
+
// src/ControlSchemePicker.tsx
|
|
465
|
+
import { useIsTouchPrimaryDevice as useIsTouchPrimaryDevice2 } from "@tastic/core";
|
|
466
|
+
import { Platform as Platform3 } from "react-native";
|
|
467
|
+
|
|
468
|
+
// src/SectionedDropdown.tsx
|
|
469
|
+
import { getBlendedColor, getColorRoles } from "@rific/auto-paper";
|
|
470
|
+
import { IconButton as IconButton2, TouchableRipple as TouchableRipple2 } from "@rific/feedback-press";
|
|
471
|
+
import { useRotation as useRotation3 } from "@tastic/core";
|
|
472
|
+
import { ScrollView as ScrollView3, StyleSheet as StyleSheet7, View as View8 } from "react-native";
|
|
473
|
+
import { Icon as Icon5, Text as Text5 } from "react-native-paper";
|
|
414
474
|
|
|
415
475
|
// src/fonts.ts
|
|
416
476
|
import { Platform as Platform2 } from "react-native";
|
|
417
477
|
var MONO_FONT = Platform2.select({ ios: "Menlo", android: "monospace", default: "monospace" });
|
|
418
478
|
|
|
419
|
-
// src/InlineColorPicker.tsx
|
|
420
|
-
import { defaultColors, getContrastColor } from "@rific/auto-paper";
|
|
421
|
-
import { TouchableRipple as TouchableRipple2 } from "@rific/feedback-press";
|
|
422
|
-
import { clamp } from "@tastic/core";
|
|
423
|
-
import { ScrollView as ScrollView3, StyleSheet as StyleSheet7, useWindowDimensions as useWindowDimensions3, View as View7 } from "react-native";
|
|
424
|
-
import { Icon as Icon4, Text as Text4 } from "react-native-paper";
|
|
425
|
-
|
|
426
479
|
// src/PopoverBody.tsx
|
|
427
|
-
import { StyleSheet as StyleSheet6, View as
|
|
428
|
-
import { Fragment as
|
|
480
|
+
import { StyleSheet as StyleSheet6, View as View6 } from "react-native";
|
|
481
|
+
import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
429
482
|
var CARET_SIZE = 7;
|
|
430
483
|
var CARET_RING_OFFSET = 2;
|
|
431
484
|
var CARET_DIP = 1;
|
|
@@ -439,11 +492,11 @@ function PopoverBody({ visible, children, align = "center", verticalAlign = "bel
|
|
|
439
492
|
const caretFill = above ? "borderTopColor" : "borderBottomColor";
|
|
440
493
|
const caretWidthProp = above ? "borderTopWidth" : "borderBottomWidth";
|
|
441
494
|
const caretEdge = (size) => above ? { bottom: -size + CARET_DIP } : { top: -size + CARET_DIP };
|
|
442
|
-
return /* @__PURE__ */ jsxs6(
|
|
495
|
+
return /* @__PURE__ */ jsxs6(View6, { style: [styles6.content, alignStyle, verticalStyle], children: [
|
|
443
496
|
children,
|
|
444
|
-
caretColor && /* @__PURE__ */ jsxs6(
|
|
445
|
-
/* @__PURE__ */ jsx6(
|
|
446
|
-
/* @__PURE__ */ jsx6(
|
|
497
|
+
caretColor && /* @__PURE__ */ jsxs6(Fragment2, { children: [
|
|
498
|
+
/* @__PURE__ */ jsx6(View6, { style: [styles6.caret, caretOffset(ringSize), caretEdge(ringSize), { [caretFill]: caretBorderColor ?? caretColor, [caretWidthProp]: ringSize, borderLeftWidth: ringSize, borderRightWidth: ringSize }] }),
|
|
499
|
+
/* @__PURE__ */ jsx6(View6, { style: [styles6.caret, caretOffset(CARET_SIZE), caretEdge(CARET_SIZE - CARET_RING_OFFSET), { [caretFill]: caretColor, [caretWidthProp]: CARET_SIZE, borderLeftWidth: CARET_SIZE, borderRightWidth: CARET_SIZE }] })
|
|
447
500
|
] })
|
|
448
501
|
] });
|
|
449
502
|
}
|
|
@@ -489,11 +542,27 @@ var styles6 = StyleSheet6.create({
|
|
|
489
542
|
}
|
|
490
543
|
});
|
|
491
544
|
|
|
545
|
+
// src/TriggerGaugeHost.tsx
|
|
546
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
547
|
+
var getTriggerGauge = () => import("./TriggerGauge-2OJOOF6I.mjs").then((mod) => ({ default: mod.TriggerGauge }));
|
|
548
|
+
function TriggerGaugeHost(props) {
|
|
549
|
+
return /* @__PURE__ */ jsx7(SkiaGate, { getComponent: getTriggerGauge, componentProps: props });
|
|
550
|
+
}
|
|
551
|
+
|
|
492
552
|
// src/useAutoAlign.ts
|
|
493
553
|
import { useCallback, useEffect, useRef, useState as useState3 } from "react";
|
|
494
554
|
import { useWindowDimensions as useWindowDimensions2 } from "react-native";
|
|
495
555
|
var EDGE_MARGIN = 12;
|
|
496
|
-
function
|
|
556
|
+
function rotateRect(x, y, width, height, rotation, windowWidth, windowHeight) {
|
|
557
|
+
if (rotation === 0) return { x, y, width, height };
|
|
558
|
+
const cx = windowWidth / 2;
|
|
559
|
+
const cy = windowHeight / 2;
|
|
560
|
+
const dx = x + width / 2 - cx;
|
|
561
|
+
const dy = y + height / 2 - cy;
|
|
562
|
+
const [newDx, newDy, newWidth, newHeight] = rotation === 180 ? [-dx, -dy, width, height] : rotation === 90 ? [-dy, dx, height, width] : [dy, -dx, height, width];
|
|
563
|
+
return { x: cx + newDx - newWidth / 2, y: cy + newDy - newHeight / 2, width: newWidth, height: newHeight };
|
|
564
|
+
}
|
|
565
|
+
function useAutoAlign(open, contentWidth, contentHeight, rotation = 0) {
|
|
497
566
|
const triggerRef = useRef(null);
|
|
498
567
|
const { width: windowWidth, height: windowHeight } = useWindowDimensions2();
|
|
499
568
|
const [align, setAlign] = useState3("center");
|
|
@@ -506,7 +575,8 @@ function useAutoAlign(open, contentWidth, contentHeight) {
|
|
|
506
575
|
if (open) setMeasured(false);
|
|
507
576
|
}
|
|
508
577
|
const measure = useCallback(() => {
|
|
509
|
-
triggerRef.current?.measureInWindow((
|
|
578
|
+
triggerRef.current?.measureInWindow((rawX, rawY, rawWidth, rawHeight) => {
|
|
579
|
+
const { x, y, width: triggerWidth, height: triggerHeight } = rotateRect(rawX, rawY, rawWidth, rawHeight, rotation, windowWidth, windowHeight);
|
|
510
580
|
const centerX = x + triggerWidth / 2;
|
|
511
581
|
const overflowsRight = centerX + contentWidth / 2 > windowWidth - EDGE_MARGIN;
|
|
512
582
|
const overflowsLeft = centerX - contentWidth / 2 < EDGE_MARGIN;
|
|
@@ -520,15 +590,275 @@ function useAutoAlign(open, contentWidth, contentHeight) {
|
|
|
520
590
|
setMaxHeight(Math.max(above ? roomAbove : roomBelow, 0));
|
|
521
591
|
setMeasured(true);
|
|
522
592
|
});
|
|
523
|
-
}, [contentWidth, contentHeight, windowWidth, windowHeight]);
|
|
593
|
+
}, [contentWidth, contentHeight, windowWidth, windowHeight, rotation]);
|
|
524
594
|
useEffect(() => {
|
|
525
595
|
if (open) measure();
|
|
526
596
|
}, [open, measure]);
|
|
527
597
|
return { align, maxHeight, measured, triggerRef, verticalAlign };
|
|
528
598
|
}
|
|
529
599
|
|
|
600
|
+
// src/SectionedDropdown.tsx
|
|
601
|
+
import { Fragment as Fragment3, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
602
|
+
var MENU_BORDER_WIDTH = 1;
|
|
603
|
+
var TRIGGER_SIZE = 44;
|
|
604
|
+
var MENU_MIN_WIDTH = 200;
|
|
605
|
+
var MENU_MAX_WIDTH = 220;
|
|
606
|
+
var MENU_ITEM_ICON_SIZE = 18;
|
|
607
|
+
var MENU_ITEM_LABEL_MAX_WIDTH = 150;
|
|
608
|
+
var MENU_ITEM_HEIGHT = 40;
|
|
609
|
+
var MENU_ITEM_HEIGHT_WITH_DESCRIPTION = 58;
|
|
610
|
+
var MENU_DIVIDER_HEIGHT = 9;
|
|
611
|
+
var MENU_VERTICAL_PADDING = 12;
|
|
612
|
+
function SectionedDropdown({ id, host, icon, accessibilityLabel, sections, accentColor, mutedColor, onAccentColor, dark, align: alignOverride, rotation: rotationOverride, autoDismiss = true, labelFontFamily = MONO_FONT, allClearLabels = { all: "All", clear: "Clear" } }) {
|
|
613
|
+
const ambientRotation = useRotation3();
|
|
614
|
+
const rotation = rotationOverride ?? ambientRotation;
|
|
615
|
+
const menuBg = dark ? "#000000" : "#FFFFFF";
|
|
616
|
+
const menuBorderColor = getBlendedColor(mutedColor, menuBg, 0.5);
|
|
617
|
+
const resolvedOnAccentColor = onAccentColor ?? getColorRoles(accentColor, menuBg).onColor;
|
|
618
|
+
const fg = dark ? "#FFFFFF" : "#000000";
|
|
619
|
+
const open = host.openId === id;
|
|
620
|
+
const estimatedHeight = MENU_VERTICAL_PADDING + sections.reduce((sum, section, sectionIndex) => {
|
|
621
|
+
const rows = section.options.reduce((rowSum, option) => rowSum + (option.description ? MENU_ITEM_HEIGHT_WITH_DESCRIPTION : MENU_ITEM_HEIGHT), 0);
|
|
622
|
+
const footer = section.kind === "multi" && section.allClear ? MENU_ITEM_HEIGHT : 0;
|
|
623
|
+
const divider = sectionIndex > 0 ? MENU_DIVIDER_HEIGHT : 0;
|
|
624
|
+
return sum + rows + footer + divider;
|
|
625
|
+
}, 0);
|
|
626
|
+
const { align: autoAlign, maxHeight, measured, triggerRef, verticalAlign } = useAutoAlign(open, MENU_MAX_WIDTH, estimatedHeight, rotation);
|
|
627
|
+
const align = alignOverride ?? autoAlign;
|
|
628
|
+
const onlySection = sections.length === 1 ? sections[0] : null;
|
|
629
|
+
const selectedOption = onlySection?.kind === "single" ? onlySection.options.find((o) => o.value === onlySection.value) : void 0;
|
|
630
|
+
const triggerIcon = selectedOption?.icon ?? icon;
|
|
631
|
+
const triggerIconSize = selectedOption?.iconSize ?? 22;
|
|
632
|
+
const hasMultiSection = sections.some((s) => s.kind === "multi");
|
|
633
|
+
const anyMultiSelected = sections.some((s) => s.kind === "multi" && s.value.length > 0);
|
|
634
|
+
const triggerIconColor = hasMultiSection ? anyMultiSelected ? accentColor : fg : fg;
|
|
635
|
+
const gaugeSegments = sections.reduce((sum, section) => sum + section.options.length, 0);
|
|
636
|
+
const gaugeLitIndices = [];
|
|
637
|
+
let gaugeOffset = 0;
|
|
638
|
+
for (const section of sections) {
|
|
639
|
+
if (section.kind === "single") {
|
|
640
|
+
const index = section.options.findIndex((o) => o.value === section.value);
|
|
641
|
+
if (index >= 0) gaugeLitIndices.push(gaugeOffset + index);
|
|
642
|
+
} else {
|
|
643
|
+
section.options.forEach((o, i) => {
|
|
644
|
+
if (section.value.includes(o.value)) gaugeLitIndices.push(gaugeOffset + i);
|
|
645
|
+
});
|
|
646
|
+
}
|
|
647
|
+
gaugeOffset += section.options.length;
|
|
648
|
+
}
|
|
649
|
+
const anchorStyle = [styles7.anchor, open && styles7.anchorOpen];
|
|
650
|
+
const menuStyle = { backgroundColor: menuBg, borderColor: menuBorderColor, maxHeight };
|
|
651
|
+
const dividerStyle = { backgroundColor: menuBorderColor };
|
|
652
|
+
return /* @__PURE__ */ jsxs7(View8, { style: anchorStyle, children: [
|
|
653
|
+
/* @__PURE__ */ jsxs7(View8, { ref: triggerRef, collapsable: false, style: styles7.triggerBox, children: [
|
|
654
|
+
/* @__PURE__ */ jsx8(TriggerGaugeHost, { segments: gaugeSegments, litIndices: gaugeLitIndices, size: TRIGGER_SIZE, accentColor, mutedColor }),
|
|
655
|
+
/* @__PURE__ */ jsx8(IconButton2, { icon: triggerIcon, iconColor: triggerIconColor, size: triggerIconSize, accessibilityLabel, onPress: () => host.toggle(id) })
|
|
656
|
+
] }),
|
|
657
|
+
/* @__PURE__ */ jsx8(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: menuBorderColor, caretBorderWidth: MENU_BORDER_WIDTH, triggerSize: TRIGGER_SIZE, children: /* @__PURE__ */ jsx8(ScrollView3, { style: [styles7.menu, menuStyle], contentContainerStyle: styles7.menuContent, showsVerticalScrollIndicator: false, children: sections.map((section, sectionIndex) => /* @__PURE__ */ jsxs7(View8, { children: [
|
|
658
|
+
sectionIndex > 0 && /* @__PURE__ */ jsx8(View8, { style: [styles7.divider, dividerStyle] }),
|
|
659
|
+
section.kind === "single" ? /* @__PURE__ */ jsx8(
|
|
660
|
+
SingleSection,
|
|
661
|
+
{
|
|
662
|
+
section,
|
|
663
|
+
accentColor,
|
|
664
|
+
onAccentColor: resolvedOnAccentColor,
|
|
665
|
+
mutedColor,
|
|
666
|
+
labelFontFamily,
|
|
667
|
+
onSelect: (value) => {
|
|
668
|
+
section.onChange(value);
|
|
669
|
+
if (autoDismiss) host.close();
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
) : /* @__PURE__ */ jsx8(MultiSection, { section, accentColor, onAccentColor: resolvedOnAccentColor, mutedColor, labelFontFamily, allClearLabels })
|
|
673
|
+
] }, section.id)) }) })
|
|
674
|
+
] });
|
|
675
|
+
}
|
|
676
|
+
function SingleSection({
|
|
677
|
+
section,
|
|
678
|
+
accentColor,
|
|
679
|
+
onAccentColor,
|
|
680
|
+
mutedColor,
|
|
681
|
+
labelFontFamily,
|
|
682
|
+
onSelect
|
|
683
|
+
}) {
|
|
684
|
+
return /* @__PURE__ */ jsx8(Fragment3, { children: section.options.map((option) => {
|
|
685
|
+
const selected = option.value === section.value;
|
|
686
|
+
const taken = !selected && option.value === section.takenValue;
|
|
687
|
+
const rowColor = selected ? onAccentColor : mutedColor;
|
|
688
|
+
const itemStyle = [styles7.item, selected && { backgroundColor: accentColor }, taken && styles7.itemTaken];
|
|
689
|
+
const labelStyle = { fontFamily: labelFontFamily, color: rowColor, fontWeight: selected ? "bold" : "normal" };
|
|
690
|
+
const descriptionStyle = { fontFamily: labelFontFamily, color: rowColor };
|
|
691
|
+
return /* @__PURE__ */ jsx8(TouchableRipple2, { disabled: taken, onPress: () => onSelect(option.value), style: itemStyle, children: /* @__PURE__ */ jsxs7(View8, { style: styles7.itemRow, children: [
|
|
692
|
+
option.icon && /* @__PURE__ */ jsx8(Icon5, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
|
|
693
|
+
/* @__PURE__ */ jsxs7(View8, { style: styles7.itemLabelColumn, children: [
|
|
694
|
+
/* @__PURE__ */ jsx8(Text5, { variant: "labelLarge", style: labelStyle, children: option.label }),
|
|
695
|
+
option.description && /* @__PURE__ */ jsx8(Text5, { variant: "labelSmall", style: descriptionStyle, children: option.description })
|
|
696
|
+
] })
|
|
697
|
+
] }) }, option.value);
|
|
698
|
+
}) });
|
|
699
|
+
}
|
|
700
|
+
function MultiSection({
|
|
701
|
+
section,
|
|
702
|
+
accentColor,
|
|
703
|
+
onAccentColor,
|
|
704
|
+
mutedColor,
|
|
705
|
+
labelFontFamily,
|
|
706
|
+
allClearLabels
|
|
707
|
+
}) {
|
|
708
|
+
const allSelected = section.value.length === section.options.length;
|
|
709
|
+
return /* @__PURE__ */ jsxs7(Fragment3, { children: [
|
|
710
|
+
section.options.map((option, i) => {
|
|
711
|
+
const selected = section.value.includes(option.value);
|
|
712
|
+
const rowColor = selected ? onAccentColor : mutedColor;
|
|
713
|
+
const prevSelected = selected && i > 0 && section.value.includes(section.options[i - 1].value);
|
|
714
|
+
const nextSelected = selected && i < section.options.length - 1 && section.value.includes(section.options[i + 1].value);
|
|
715
|
+
const itemStyle = [styles7.item, selected && { backgroundColor: accentColor }, prevSelected && { borderTopLeftRadius: 0, borderTopRightRadius: 0 }, nextSelected && { borderBottomLeftRadius: 0, borderBottomRightRadius: 0 }];
|
|
716
|
+
const labelStyle = { fontFamily: labelFontFamily, color: rowColor, fontWeight: selected ? "bold" : "normal" };
|
|
717
|
+
return /* @__PURE__ */ jsx8(TouchableRipple2, { onPress: () => section.onChange(selected ? section.value.filter((v) => v !== option.value) : [...section.value, option.value]), style: itemStyle, children: /* @__PURE__ */ jsxs7(View8, { style: styles7.itemRow, children: [
|
|
718
|
+
option.icon && /* @__PURE__ */ jsx8(Icon5, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
|
|
719
|
+
/* @__PURE__ */ jsx8(Text5, { variant: "labelLarge", style: [styles7.itemLabelFlex, labelStyle], children: option.label })
|
|
720
|
+
] }) }, option.value);
|
|
721
|
+
}),
|
|
722
|
+
section.allClear && /* @__PURE__ */ jsx8(TouchableRipple2, { onPress: () => section.onChange(allSelected ? [] : section.options.map((o) => o.value)), style: styles7.item, children: /* @__PURE__ */ jsx8(Text5, { variant: "labelLarge", style: [styles7.allClearLabel, { fontFamily: labelFontFamily, color: accentColor }], children: allSelected ? allClearLabels.clear : allClearLabels.all }) })
|
|
723
|
+
] });
|
|
724
|
+
}
|
|
725
|
+
var styles7 = StyleSheet7.create({
|
|
726
|
+
allClearLabel: {
|
|
727
|
+
fontWeight: "bold",
|
|
728
|
+
textAlign: "center"
|
|
729
|
+
},
|
|
730
|
+
anchor: {
|
|
731
|
+
position: "relative"
|
|
732
|
+
},
|
|
733
|
+
// React Native Web gives every position:'relative' view an explicit zIndex (0, not 'auto'),
|
|
734
|
+
// which makes each one its own stacking context — so a zIndex set only on the popover content
|
|
735
|
+
// below only wins comparisons within this anchor's own box, not against this anchor's own later
|
|
736
|
+
// siblings (e.g. a Ready button), which are otherwise painted on top by DOM-order tiebreak.
|
|
737
|
+
// Elevating the anchor itself, only while its popover is open, fixes that at the right level.
|
|
738
|
+
anchorOpen: {
|
|
739
|
+
zIndex: 100
|
|
740
|
+
},
|
|
741
|
+
divider: {
|
|
742
|
+
height: StyleSheet7.hairlineWidth,
|
|
743
|
+
marginVertical: 4
|
|
744
|
+
},
|
|
745
|
+
item: {
|
|
746
|
+
borderRadius: 8,
|
|
747
|
+
paddingHorizontal: 12,
|
|
748
|
+
paddingVertical: 8
|
|
749
|
+
},
|
|
750
|
+
itemLabelColumn: {
|
|
751
|
+
maxWidth: MENU_ITEM_LABEL_MAX_WIDTH
|
|
752
|
+
},
|
|
753
|
+
itemLabelFlex: {
|
|
754
|
+
flex: 1
|
|
755
|
+
},
|
|
756
|
+
itemRow: {
|
|
757
|
+
alignItems: "center",
|
|
758
|
+
flexDirection: "row",
|
|
759
|
+
gap: 8
|
|
760
|
+
},
|
|
761
|
+
// Same opacity as ProfilePicker's rowDisabled / InlineColorPicker's swatchTaken — the fleet's
|
|
762
|
+
// established "shown, not removed" treatment for another seat's own current pick.
|
|
763
|
+
itemTaken: {
|
|
764
|
+
opacity: 0.35
|
|
765
|
+
},
|
|
766
|
+
menu: {
|
|
767
|
+
borderRadius: 12,
|
|
768
|
+
borderWidth: MENU_BORDER_WIDTH,
|
|
769
|
+
elevation: 8,
|
|
770
|
+
maxWidth: MENU_MAX_WIDTH,
|
|
771
|
+
minWidth: MENU_MIN_WIDTH,
|
|
772
|
+
shadowColor: "#000000",
|
|
773
|
+
shadowOffset: { height: 2, width: 0 },
|
|
774
|
+
shadowOpacity: 0.3,
|
|
775
|
+
shadowRadius: 8
|
|
776
|
+
},
|
|
777
|
+
// Separate from `menu` itself — a ScrollView's own style sets the scrolling frame's bounds
|
|
778
|
+
// (including the maxHeight that actually caps it), while padding/gap belong to its
|
|
779
|
+
// contentContainerStyle, which sizes to the *unclamped* content instead of the frame.
|
|
780
|
+
menuContent: {
|
|
781
|
+
gap: 4,
|
|
782
|
+
padding: 6
|
|
783
|
+
},
|
|
784
|
+
// Fixed hit-area regardless of the current option's iconSize, so a small-vs-large trigger icon
|
|
785
|
+
// doesn't shift this picker's position within its row.
|
|
786
|
+
triggerBox: {
|
|
787
|
+
alignItems: "center",
|
|
788
|
+
height: TRIGGER_SIZE,
|
|
789
|
+
justifyContent: "center",
|
|
790
|
+
width: TRIGGER_SIZE
|
|
791
|
+
}
|
|
792
|
+
});
|
|
793
|
+
|
|
794
|
+
// src/ControlSchemePicker.tsx
|
|
795
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
796
|
+
function ControlSchemePicker({ id, host, value, onChange, options, takenValue, accentColor, mutedColor, onAccentColor, dark, align, labelFontFamily }) {
|
|
797
|
+
const isTouchPrimary = useIsTouchPrimaryDevice2();
|
|
798
|
+
if (Platform3.OS !== "web" || isTouchPrimary) return null;
|
|
799
|
+
return /* @__PURE__ */ jsx9(SectionedDropdown, { id, host, icon: "keyboard-outline", accessibilityLabel: "Control scheme", sections: [{ kind: "single", id: "controls", options, value, onChange, takenValue }], accentColor, mutedColor, onAccentColor, dark, align, labelFontFamily });
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
// src/CornerActionButtons.tsx
|
|
803
|
+
import { IconButton as IconButton3 } from "@rific/feedback-press";
|
|
804
|
+
import { StyleSheet as StyleSheet8 } from "react-native";
|
|
805
|
+
import { Fragment as Fragment4, jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
806
|
+
function CornerActionButtons({ onBack, onSettings, fg, insets, backIcon = "arrow-left", backLabel = "Back" }) {
|
|
807
|
+
return /* @__PURE__ */ jsxs8(Fragment4, { children: [
|
|
808
|
+
/* @__PURE__ */ jsx10(IconButton3, { icon: backIcon, iconColor: fg, size: 24, style: [styles8.back, { top: 8 + insets.top, left: 8 + insets.left }], onPress: onBack, accessibilityLabel: backLabel }),
|
|
809
|
+
/* @__PURE__ */ jsx10(IconButton3, { icon: "cog", iconColor: fg, size: 24, style: [styles8.topRight, { top: 8 + insets.top, right: 8 + insets.right }], onPress: onSettings, accessibilityLabel: "Settings" })
|
|
810
|
+
] });
|
|
811
|
+
}
|
|
812
|
+
var styles8 = StyleSheet8.create({
|
|
813
|
+
back: {
|
|
814
|
+
position: "absolute"
|
|
815
|
+
},
|
|
816
|
+
topRight: {
|
|
817
|
+
position: "absolute"
|
|
818
|
+
}
|
|
819
|
+
});
|
|
820
|
+
|
|
821
|
+
// src/CornerStatusBadges.tsx
|
|
822
|
+
import { StyleSheet as StyleSheet9, View as View9 } from "react-native";
|
|
823
|
+
import { Icon as Icon6 } from "react-native-paper";
|
|
824
|
+
import { Fragment as Fragment5, jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
825
|
+
var BADGE_SIZE = 30;
|
|
826
|
+
function StatusBadge({ icon }) {
|
|
827
|
+
return /* @__PURE__ */ jsx11(View9, { style: styles9.badge, children: icon && /* @__PURE__ */ jsx11(Icon6, { source: icon, size: 16, color: "rgba(255,255,255,0.85)" }) });
|
|
828
|
+
}
|
|
829
|
+
function CornerStatusBadges({ orientationMode, p1OnRight, p1, p2 }) {
|
|
830
|
+
const p1OnRightSide = orientationMode === "sideBySide" && p1OnRight;
|
|
831
|
+
const p2OnLeftSide = orientationMode === "sideBySide" && !p1OnRight;
|
|
832
|
+
return /* @__PURE__ */ jsxs9(Fragment5, { children: [
|
|
833
|
+
p1 && /* @__PURE__ */ jsx11(View9, { pointerEvents: "none", style: p1OnRightSide ? styles9.bottomRight : styles9.bottomLeft, children: /* @__PURE__ */ jsx11(StatusBadge, { icon: p1.icon }) }),
|
|
834
|
+
p2 && /* @__PURE__ */ jsx11(View9, { pointerEvents: "none", style: p2OnLeftSide ? styles9.topLeft : styles9.topRight, children: /* @__PURE__ */ jsx11(StatusBadge, { icon: p2.icon }) })
|
|
835
|
+
] });
|
|
836
|
+
}
|
|
837
|
+
var styles9 = StyleSheet9.create({
|
|
838
|
+
badge: {
|
|
839
|
+
alignItems: "center",
|
|
840
|
+
backgroundColor: "rgba(0,0,0,0.28)",
|
|
841
|
+
borderColor: "rgba(255,255,255,0.18)",
|
|
842
|
+
borderRadius: BADGE_SIZE / 2,
|
|
843
|
+
borderWidth: 1,
|
|
844
|
+
height: BADGE_SIZE,
|
|
845
|
+
justifyContent: "center",
|
|
846
|
+
opacity: 0.7,
|
|
847
|
+
width: BADGE_SIZE
|
|
848
|
+
},
|
|
849
|
+
bottomLeft: { bottom: 12, left: 12, position: "absolute" },
|
|
850
|
+
bottomRight: { bottom: 12, position: "absolute", right: 12 },
|
|
851
|
+
topLeft: { left: 12, position: "absolute", top: 12 },
|
|
852
|
+
topRight: { position: "absolute", right: 12, top: 12 }
|
|
853
|
+
});
|
|
854
|
+
|
|
530
855
|
// src/InlineColorPicker.tsx
|
|
531
|
-
import {
|
|
856
|
+
import { defaultColors, getContrastColor } from "@rific/auto-paper";
|
|
857
|
+
import { TouchableRipple as TouchableRipple3 } from "@rific/feedback-press";
|
|
858
|
+
import { clamp, useRotation as useRotation4 } from "@tastic/core";
|
|
859
|
+
import { ScrollView as ScrollView4, StyleSheet as StyleSheet10, useWindowDimensions as useWindowDimensions3, View as View10 } from "react-native";
|
|
860
|
+
import { Icon as Icon7, Text as Text6 } from "react-native-paper";
|
|
861
|
+
import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
532
862
|
var EMOJI_PATTERN = /\p{Extended_Pictographic}/u;
|
|
533
863
|
var DEFAULT_SIZE = 48;
|
|
534
864
|
var SWATCH_SIZE = 28;
|
|
@@ -541,7 +871,9 @@ var SCREEN_MARGIN = 40;
|
|
|
541
871
|
function widthForColumns(columns) {
|
|
542
872
|
return SWATCHES_BORDER_WIDTH * 2 + SWATCHES_PADDING * 2 + SWATCH_SIZE * columns + SWATCHES_GAP * (columns - 1);
|
|
543
873
|
}
|
|
544
|
-
function InlineColorPicker({ id, host, value, onChange, previewValue, swatches = defaultColors, takenValue, allowSwapTaken, dark, align: alignOverride, icon = "palette", tag, labelFontFamily = MONO_FONT, autoDismiss = true, columns, size = DEFAULT_SIZE }) {
|
|
874
|
+
function InlineColorPicker({ id, host, value, onChange, previewValue, swatches = defaultColors, takenValue, allowSwapTaken, dark, align: alignOverride, rotation: rotationOverride, icon = "palette", tag, labelFontFamily = MONO_FONT, autoDismiss = true, columns, size = DEFAULT_SIZE }) {
|
|
875
|
+
const ambientRotation = useRotation4();
|
|
876
|
+
const rotation = rotationOverride ?? ambientRotation;
|
|
545
877
|
const menuBg = dark ? "#000000" : "#FFFFFF";
|
|
546
878
|
const { width: windowWidth } = useWindowDimensions3();
|
|
547
879
|
const autoColumns = clamp(Math.floor((windowWidth - 2 * SCREEN_MARGIN + SWATCHES_GAP) / (SWATCH_SIZE + SWATCHES_GAP)), MIN_COLUMNS, MAX_COLUMNS);
|
|
@@ -550,21 +882,21 @@ function InlineColorPicker({ id, host, value, onChange, previewValue, swatches =
|
|
|
550
882
|
const swatchRows = Math.ceil(swatches.length / resolvedColumns);
|
|
551
883
|
const swatchesHeight = SWATCHES_BORDER_WIDTH * 2 + SWATCHES_PADDING * 2 + SWATCH_SIZE * swatchRows + SWATCHES_GAP * (swatchRows - 1);
|
|
552
884
|
const open = host.openId === id;
|
|
553
|
-
const { align: autoAlign, maxHeight, measured, triggerRef, verticalAlign } = useAutoAlign(open, swatchesWidth, swatchesHeight);
|
|
885
|
+
const { align: autoAlign, maxHeight, measured, triggerRef, verticalAlign } = useAutoAlign(open, swatchesWidth, swatchesHeight, rotation);
|
|
554
886
|
const align = alignOverride ?? autoAlign;
|
|
555
887
|
const displayFor = previewValue ?? ((hex) => hex);
|
|
556
888
|
const displayValue = displayFor(value);
|
|
557
889
|
const contrastColor = getContrastColor(displayValue);
|
|
558
890
|
const tagFontSize = size * (tag && EMOJI_PATTERN.test(tag) ? 0.6 : 0.4);
|
|
559
|
-
return /* @__PURE__ */
|
|
560
|
-
/* @__PURE__ */
|
|
561
|
-
/* @__PURE__ */
|
|
891
|
+
return /* @__PURE__ */ jsxs10(View10, { style: [styles10.anchor, open && styles10.anchorOpen], children: [
|
|
892
|
+
/* @__PURE__ */ jsx12(TouchableRipple3, { onPress: () => host.toggle(id), borderless: true, style: [styles10.trigger, { backgroundColor: displayValue, borderRadius: size / 2, height: size, width: size }], children: /* @__PURE__ */ jsx12(View10, { ref: triggerRef, collapsable: false, style: styles10.triggerMeasure, children: tag ? /* @__PURE__ */ jsx12(Text6, { style: [styles10.tagLabel, { color: contrastColor, fontFamily: labelFontFamily, fontSize: tagFontSize }], numberOfLines: 1, adjustsFontSizeToFit: true, children: tag }) : /* @__PURE__ */ jsx12(Icon7, { source: icon, size: size * 0.6, color: contrastColor }) }) }),
|
|
893
|
+
/* @__PURE__ */ jsx12(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: displayValue, caretBorderWidth: SWATCHES_BORDER_WIDTH, triggerSize: size, children: /* @__PURE__ */ jsx12(ScrollView4, { style: [styles10.swatches, { backgroundColor: menuBg, borderColor: displayValue, width: swatchesWidth, maxHeight }], contentContainerStyle: styles10.swatchesContent, showsVerticalScrollIndicator: false, children: swatches.map((swatch) => {
|
|
562
894
|
const selected = swatch.value.toLowerCase() === value.toLowerCase();
|
|
563
895
|
const taken = !selected && !!takenValue && swatch.value.toLowerCase() === takenValue.toLowerCase();
|
|
564
896
|
const swappable = taken && allowSwapTaken;
|
|
565
897
|
const swatchDisplay = displayFor(swatch.value);
|
|
566
|
-
return /* @__PURE__ */
|
|
567
|
-
|
|
898
|
+
return /* @__PURE__ */ jsx12(
|
|
899
|
+
TouchableRipple3,
|
|
568
900
|
{
|
|
569
901
|
disabled: taken && !swappable,
|
|
570
902
|
onPress: () => {
|
|
@@ -572,15 +904,15 @@ function InlineColorPicker({ id, host, value, onChange, previewValue, swatches =
|
|
|
572
904
|
if (autoDismiss) host.close();
|
|
573
905
|
},
|
|
574
906
|
borderless: true,
|
|
575
|
-
style: [
|
|
576
|
-
children: selected ? /* @__PURE__ */
|
|
907
|
+
style: [styles10.swatch, { backgroundColor: swatchDisplay }, selected && styles10.swatchSelected, taken && !swappable && styles10.swatchTaken],
|
|
908
|
+
children: selected ? /* @__PURE__ */ jsx12(Icon7, { source: "check", size: 16, color: getContrastColor(swatchDisplay) }) : swappable ? /* @__PURE__ */ jsx12(Icon7, { source: "swap-horizontal", size: 16, color: getContrastColor(swatchDisplay) }) : taken ? /* @__PURE__ */ jsx12(Icon7, { source: "close", size: 16, color: getContrastColor(swatchDisplay) }) : /* @__PURE__ */ jsx12(View10, {})
|
|
577
909
|
},
|
|
578
910
|
swatch.value
|
|
579
911
|
);
|
|
580
912
|
}) }) })
|
|
581
913
|
] });
|
|
582
914
|
}
|
|
583
|
-
var
|
|
915
|
+
var styles10 = StyleSheet10.create({
|
|
584
916
|
anchor: {
|
|
585
917
|
position: "relative"
|
|
586
918
|
},
|
|
@@ -653,10 +985,10 @@ var styles7 = StyleSheet7.create({
|
|
|
653
985
|
|
|
654
986
|
// src/LabeledDropdown.tsx
|
|
655
987
|
import { getContrastColor as getContrastColor2 } from "@rific/auto-paper";
|
|
656
|
-
import { TouchableRipple as
|
|
657
|
-
import { ScrollView as
|
|
658
|
-
import { Icon as
|
|
659
|
-
import { jsx as
|
|
988
|
+
import { TouchableRipple as TouchableRipple4 } from "@rific/feedback-press";
|
|
989
|
+
import { ScrollView as ScrollView5, StyleSheet as StyleSheet11, View as View11 } from "react-native";
|
|
990
|
+
import { Icon as Icon8, Text as Text7 } from "react-native-paper";
|
|
991
|
+
import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
660
992
|
var TRIGGER_HEIGHT = 28;
|
|
661
993
|
var POPOVER_WIDTH = 180;
|
|
662
994
|
var ROW_HEIGHT = 36;
|
|
@@ -679,22 +1011,22 @@ function LabeledDropdown({ id, host, options, value, onChange, color, dark, alig
|
|
|
679
1011
|
onChange(option.value);
|
|
680
1012
|
host.close();
|
|
681
1013
|
};
|
|
682
|
-
return /* @__PURE__ */
|
|
683
|
-
/* @__PURE__ */
|
|
684
|
-
/* @__PURE__ */
|
|
685
|
-
/* @__PURE__ */
|
|
1014
|
+
return /* @__PURE__ */ jsxs11(View11, { style: [styles11.anchor, open && styles11.anchorOpen], children: [
|
|
1015
|
+
/* @__PURE__ */ jsx13(TouchableRipple4, { onPress: () => host.toggle(id), style: styles11.trigger, children: /* @__PURE__ */ jsxs11(View11, { ref: triggerRef, collapsable: false, style: styles11.triggerInner, children: [
|
|
1016
|
+
/* @__PURE__ */ jsx13(Text7, { style: [styles11.triggerLabel, { color }], numberOfLines: 1, children: (selected?.label ?? "").toUpperCase() }),
|
|
1017
|
+
/* @__PURE__ */ jsx13(Icon8, { source: "menu-down", size: 16, color })
|
|
686
1018
|
] }) }),
|
|
687
|
-
/* @__PURE__ */
|
|
1019
|
+
/* @__PURE__ */ jsx13(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: color, caretBorderWidth: 2, triggerSize: TRIGGER_HEIGHT, children: /* @__PURE__ */ jsx13(ScrollView5, { style: [styles11.menu, { backgroundColor: menuBg, borderColor: color, width: POPOVER_WIDTH, maxHeight }], contentContainerStyle: styles11.menuContent, showsVerticalScrollIndicator: false, children: options.map((option) => {
|
|
688
1020
|
const isSelected = option.value === value;
|
|
689
1021
|
const onColor = getContrastColor2(color);
|
|
690
|
-
return /* @__PURE__ */
|
|
691
|
-
option.icon && /* @__PURE__ */
|
|
692
|
-
/* @__PURE__ */
|
|
1022
|
+
return /* @__PURE__ */ jsx13(TouchableRipple4, { onPress: () => handleSelect(option), style: [styles11.row, isSelected && { backgroundColor: color }], children: /* @__PURE__ */ jsxs11(View11, { style: styles11.rowInner, children: [
|
|
1023
|
+
option.icon && /* @__PURE__ */ jsx13(Icon8, { source: option.icon, size: 18, color: isSelected ? onColor : fg }),
|
|
1024
|
+
/* @__PURE__ */ jsx13(Text7, { style: [styles11.rowLabel, { color: isSelected ? onColor : fg }], numberOfLines: 1, children: option.label })
|
|
693
1025
|
] }) }, option.value);
|
|
694
1026
|
}) }) })
|
|
695
1027
|
] });
|
|
696
1028
|
}
|
|
697
|
-
var
|
|
1029
|
+
var styles11 = StyleSheet11.create({
|
|
698
1030
|
anchor: {
|
|
699
1031
|
position: "relative"
|
|
700
1032
|
},
|
|
@@ -752,25 +1084,25 @@ function loadSkiaWeb() {
|
|
|
752
1084
|
}
|
|
753
1085
|
|
|
754
1086
|
// src/PressAwayOverlay.tsx
|
|
755
|
-
import { Pressable, StyleSheet as
|
|
756
|
-
import { jsx as
|
|
1087
|
+
import { Pressable, StyleSheet as StyleSheet12 } from "react-native";
|
|
1088
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
757
1089
|
function PressAwayOverlay({ active, onPress, style }) {
|
|
758
1090
|
if (!active) return null;
|
|
759
|
-
return /* @__PURE__ */
|
|
1091
|
+
return /* @__PURE__ */ jsx14(Pressable, { accessibilityLabel: "Dismiss", accessibilityRole: "button", onPress, style: [StyleSheet12.absoluteFill, style] });
|
|
760
1092
|
}
|
|
761
1093
|
|
|
762
1094
|
// src/ReadyButton.tsx
|
|
763
|
-
import { TouchableRipple as
|
|
764
|
-
import { StyleSheet as
|
|
765
|
-
import { Text as
|
|
766
|
-
import { jsx as
|
|
1095
|
+
import { TouchableRipple as TouchableRipple5 } from "@rific/feedback-press";
|
|
1096
|
+
import { StyleSheet as StyleSheet13 } from "react-native";
|
|
1097
|
+
import { Text as Text8 } from "react-native-paper";
|
|
1098
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
767
1099
|
function ReadyButton({ color, ready, onToggleReady, style, labelFontFamily = MONO_FONT }) {
|
|
768
|
-
const readyButtonStyle = [
|
|
1100
|
+
const readyButtonStyle = [styles12.readyButton, { borderColor: color }, ready && { backgroundColor: color }, style];
|
|
769
1101
|
const labelTextStyle = { fontFamily: labelFontFamily, fontWeight: "bold" };
|
|
770
1102
|
const labelColorStyle = { color: ready ? "#000000" : color };
|
|
771
|
-
return /* @__PURE__ */
|
|
1103
|
+
return /* @__PURE__ */ jsx15(TouchableRipple5, { onPress: onToggleReady, borderless: true, style: readyButtonStyle, children: /* @__PURE__ */ jsx15(Text8, { variant: "labelLarge", style: [labelTextStyle, labelColorStyle], children: ready ? "READY \u2713" : "READY?" }) });
|
|
772
1104
|
}
|
|
773
|
-
var
|
|
1105
|
+
var styles12 = StyleSheet13.create({
|
|
774
1106
|
readyButton: {
|
|
775
1107
|
alignItems: "center",
|
|
776
1108
|
borderRadius: 12,
|
|
@@ -782,228 +1114,22 @@ var styles9 = StyleSheet10.create({
|
|
|
782
1114
|
}
|
|
783
1115
|
});
|
|
784
1116
|
|
|
785
|
-
// src/SectionedDropdown.tsx
|
|
786
|
-
import { getBlendedColor, getColorRoles } from "@rific/auto-paper";
|
|
787
|
-
import { IconButton as IconButton3, TouchableRipple as TouchableRipple5 } from "@rific/feedback-press";
|
|
788
|
-
import { ScrollView as ScrollView5, StyleSheet as StyleSheet11, View as View9 } from "react-native";
|
|
789
|
-
import { Icon as Icon6, Text as Text7 } from "react-native-paper";
|
|
790
|
-
|
|
791
|
-
// src/TriggerGaugeHost.tsx
|
|
792
|
-
import { lazy, Suspense } from "react";
|
|
793
|
-
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
794
|
-
var LazyTriggerGauge = lazy(() => loadSkiaWeb().then(() => import("./TriggerGauge-2OJOOF6I.mjs").then((m) => ({ default: m.TriggerGauge }))));
|
|
795
|
-
function TriggerGaugeHost(props) {
|
|
796
|
-
return /* @__PURE__ */ jsx11(Suspense, { fallback: null, children: /* @__PURE__ */ jsx11(LazyTriggerGauge, { ...props }) });
|
|
797
|
-
}
|
|
798
|
-
|
|
799
|
-
// src/SectionedDropdown.tsx
|
|
800
|
-
import { Fragment as Fragment4, jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
801
|
-
var MENU_BORDER_WIDTH = 1;
|
|
802
|
-
var TRIGGER_SIZE = 44;
|
|
803
|
-
var MENU_MIN_WIDTH = 200;
|
|
804
|
-
var MENU_MAX_WIDTH = 220;
|
|
805
|
-
var MENU_ITEM_ICON_SIZE = 18;
|
|
806
|
-
var MENU_ITEM_LABEL_MAX_WIDTH = 150;
|
|
807
|
-
var MENU_ITEM_HEIGHT = 40;
|
|
808
|
-
var MENU_ITEM_HEIGHT_WITH_DESCRIPTION = 58;
|
|
809
|
-
var MENU_DIVIDER_HEIGHT = 9;
|
|
810
|
-
var MENU_VERTICAL_PADDING = 12;
|
|
811
|
-
function SectionedDropdown({ id, host, icon, accessibilityLabel, sections, accentColor, mutedColor, onAccentColor, dark, align: alignOverride, autoDismiss = true, labelFontFamily = MONO_FONT, allClearLabels = { all: "All", clear: "Clear" } }) {
|
|
812
|
-
const menuBg = dark ? "#000000" : "#FFFFFF";
|
|
813
|
-
const menuBorderColor = getBlendedColor(mutedColor, menuBg, 0.5);
|
|
814
|
-
const resolvedOnAccentColor = onAccentColor ?? getColorRoles(accentColor, menuBg).onColor;
|
|
815
|
-
const fg = dark ? "#FFFFFF" : "#000000";
|
|
816
|
-
const open = host.openId === id;
|
|
817
|
-
const estimatedHeight = MENU_VERTICAL_PADDING + sections.reduce((sum, section, sectionIndex) => {
|
|
818
|
-
const rows = section.options.reduce((rowSum, option) => rowSum + (option.description ? MENU_ITEM_HEIGHT_WITH_DESCRIPTION : MENU_ITEM_HEIGHT), 0);
|
|
819
|
-
const footer = section.kind === "multi" && section.allClear ? MENU_ITEM_HEIGHT : 0;
|
|
820
|
-
const divider = sectionIndex > 0 ? MENU_DIVIDER_HEIGHT : 0;
|
|
821
|
-
return sum + rows + footer + divider;
|
|
822
|
-
}, 0);
|
|
823
|
-
const { align: autoAlign, maxHeight, measured, triggerRef, verticalAlign } = useAutoAlign(open, MENU_MAX_WIDTH, estimatedHeight);
|
|
824
|
-
const align = alignOverride ?? autoAlign;
|
|
825
|
-
const onlySection = sections.length === 1 ? sections[0] : null;
|
|
826
|
-
const selectedOption = onlySection?.kind === "single" ? onlySection.options.find((o) => o.value === onlySection.value) : void 0;
|
|
827
|
-
const triggerIcon = selectedOption?.icon ?? icon;
|
|
828
|
-
const triggerIconSize = selectedOption?.iconSize ?? 22;
|
|
829
|
-
const hasMultiSection = sections.some((s) => s.kind === "multi");
|
|
830
|
-
const anyMultiSelected = sections.some((s) => s.kind === "multi" && s.value.length > 0);
|
|
831
|
-
const triggerIconColor = hasMultiSection ? anyMultiSelected ? accentColor : fg : fg;
|
|
832
|
-
const gaugeSegments = sections.reduce((sum, section) => sum + section.options.length, 0);
|
|
833
|
-
const gaugeLitIndices = [];
|
|
834
|
-
let gaugeOffset = 0;
|
|
835
|
-
for (const section of sections) {
|
|
836
|
-
if (section.kind === "single") {
|
|
837
|
-
const index = section.options.findIndex((o) => o.value === section.value);
|
|
838
|
-
if (index >= 0) gaugeLitIndices.push(gaugeOffset + index);
|
|
839
|
-
} else {
|
|
840
|
-
section.options.forEach((o, i) => {
|
|
841
|
-
if (section.value.includes(o.value)) gaugeLitIndices.push(gaugeOffset + i);
|
|
842
|
-
});
|
|
843
|
-
}
|
|
844
|
-
gaugeOffset += section.options.length;
|
|
845
|
-
}
|
|
846
|
-
const anchorStyle = [styles10.anchor, open && styles10.anchorOpen];
|
|
847
|
-
const menuStyle = { backgroundColor: menuBg, borderColor: menuBorderColor, maxHeight };
|
|
848
|
-
const dividerStyle = { backgroundColor: menuBorderColor };
|
|
849
|
-
return /* @__PURE__ */ jsxs9(View9, { style: anchorStyle, children: [
|
|
850
|
-
/* @__PURE__ */ jsxs9(View9, { ref: triggerRef, collapsable: false, style: styles10.triggerBox, children: [
|
|
851
|
-
/* @__PURE__ */ jsx12(TriggerGaugeHost, { segments: gaugeSegments, litIndices: gaugeLitIndices, size: TRIGGER_SIZE, accentColor, mutedColor }),
|
|
852
|
-
/* @__PURE__ */ jsx12(IconButton3, { icon: triggerIcon, iconColor: triggerIconColor, size: triggerIconSize, accessibilityLabel, onPress: () => host.toggle(id) })
|
|
853
|
-
] }),
|
|
854
|
-
/* @__PURE__ */ jsx12(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: menuBorderColor, caretBorderWidth: MENU_BORDER_WIDTH, triggerSize: TRIGGER_SIZE, children: /* @__PURE__ */ jsx12(ScrollView5, { style: [styles10.menu, menuStyle], contentContainerStyle: styles10.menuContent, showsVerticalScrollIndicator: false, children: sections.map((section, sectionIndex) => /* @__PURE__ */ jsxs9(View9, { children: [
|
|
855
|
-
sectionIndex > 0 && /* @__PURE__ */ jsx12(View9, { style: [styles10.divider, dividerStyle] }),
|
|
856
|
-
section.kind === "single" ? /* @__PURE__ */ jsx12(
|
|
857
|
-
SingleSection,
|
|
858
|
-
{
|
|
859
|
-
section,
|
|
860
|
-
accentColor,
|
|
861
|
-
onAccentColor: resolvedOnAccentColor,
|
|
862
|
-
mutedColor,
|
|
863
|
-
labelFontFamily,
|
|
864
|
-
onSelect: (value) => {
|
|
865
|
-
section.onChange(value);
|
|
866
|
-
if (autoDismiss) host.close();
|
|
867
|
-
}
|
|
868
|
-
}
|
|
869
|
-
) : /* @__PURE__ */ jsx12(MultiSection, { section, accentColor, onAccentColor: resolvedOnAccentColor, mutedColor, labelFontFamily, allClearLabels })
|
|
870
|
-
] }, section.id)) }) })
|
|
871
|
-
] });
|
|
872
|
-
}
|
|
873
|
-
function SingleSection({
|
|
874
|
-
section,
|
|
875
|
-
accentColor,
|
|
876
|
-
onAccentColor,
|
|
877
|
-
mutedColor,
|
|
878
|
-
labelFontFamily,
|
|
879
|
-
onSelect
|
|
880
|
-
}) {
|
|
881
|
-
return /* @__PURE__ */ jsx12(Fragment4, { children: section.options.map((option) => {
|
|
882
|
-
const selected = option.value === section.value;
|
|
883
|
-
const taken = !selected && option.value === section.takenValue;
|
|
884
|
-
const rowColor = selected ? onAccentColor : mutedColor;
|
|
885
|
-
const itemStyle = [styles10.item, selected && { backgroundColor: accentColor }, taken && styles10.itemTaken];
|
|
886
|
-
const labelStyle = { fontFamily: labelFontFamily, color: rowColor, fontWeight: selected ? "bold" : "normal" };
|
|
887
|
-
const descriptionStyle = { fontFamily: labelFontFamily, color: rowColor };
|
|
888
|
-
return /* @__PURE__ */ jsx12(TouchableRipple5, { disabled: taken, onPress: () => onSelect(option.value), style: itemStyle, children: /* @__PURE__ */ jsxs9(View9, { style: styles10.itemRow, children: [
|
|
889
|
-
option.icon && /* @__PURE__ */ jsx12(Icon6, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
|
|
890
|
-
/* @__PURE__ */ jsxs9(View9, { style: styles10.itemLabelColumn, children: [
|
|
891
|
-
/* @__PURE__ */ jsx12(Text7, { variant: "labelLarge", style: labelStyle, children: option.label }),
|
|
892
|
-
option.description && /* @__PURE__ */ jsx12(Text7, { variant: "labelSmall", style: descriptionStyle, children: option.description })
|
|
893
|
-
] })
|
|
894
|
-
] }) }, option.value);
|
|
895
|
-
}) });
|
|
896
|
-
}
|
|
897
|
-
function MultiSection({
|
|
898
|
-
section,
|
|
899
|
-
accentColor,
|
|
900
|
-
onAccentColor,
|
|
901
|
-
mutedColor,
|
|
902
|
-
labelFontFamily,
|
|
903
|
-
allClearLabels
|
|
904
|
-
}) {
|
|
905
|
-
const allSelected = section.value.length === section.options.length;
|
|
906
|
-
return /* @__PURE__ */ jsxs9(Fragment4, { children: [
|
|
907
|
-
section.options.map((option, i) => {
|
|
908
|
-
const selected = section.value.includes(option.value);
|
|
909
|
-
const rowColor = selected ? onAccentColor : mutedColor;
|
|
910
|
-
const prevSelected = selected && i > 0 && section.value.includes(section.options[i - 1].value);
|
|
911
|
-
const nextSelected = selected && i < section.options.length - 1 && section.value.includes(section.options[i + 1].value);
|
|
912
|
-
const itemStyle = [styles10.item, selected && { backgroundColor: accentColor }, prevSelected && { borderTopLeftRadius: 0, borderTopRightRadius: 0 }, nextSelected && { borderBottomLeftRadius: 0, borderBottomRightRadius: 0 }];
|
|
913
|
-
const labelStyle = { fontFamily: labelFontFamily, color: rowColor, fontWeight: selected ? "bold" : "normal" };
|
|
914
|
-
return /* @__PURE__ */ jsx12(TouchableRipple5, { onPress: () => section.onChange(selected ? section.value.filter((v) => v !== option.value) : [...section.value, option.value]), style: itemStyle, children: /* @__PURE__ */ jsxs9(View9, { style: styles10.itemRow, children: [
|
|
915
|
-
option.icon && /* @__PURE__ */ jsx12(Icon6, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
|
|
916
|
-
/* @__PURE__ */ jsx12(Text7, { variant: "labelLarge", style: [styles10.itemLabelFlex, labelStyle], children: option.label })
|
|
917
|
-
] }) }, option.value);
|
|
918
|
-
}),
|
|
919
|
-
section.allClear && /* @__PURE__ */ jsx12(TouchableRipple5, { onPress: () => section.onChange(allSelected ? [] : section.options.map((o) => o.value)), style: styles10.item, children: /* @__PURE__ */ jsx12(Text7, { variant: "labelLarge", style: [styles10.allClearLabel, { fontFamily: labelFontFamily, color: accentColor }], children: allSelected ? allClearLabels.clear : allClearLabels.all }) })
|
|
920
|
-
] });
|
|
921
|
-
}
|
|
922
|
-
var styles10 = StyleSheet11.create({
|
|
923
|
-
allClearLabel: {
|
|
924
|
-
fontWeight: "bold",
|
|
925
|
-
textAlign: "center"
|
|
926
|
-
},
|
|
927
|
-
anchor: {
|
|
928
|
-
position: "relative"
|
|
929
|
-
},
|
|
930
|
-
// React Native Web gives every position:'relative' view an explicit zIndex (0, not 'auto'),
|
|
931
|
-
// which makes each one its own stacking context — so a zIndex set only on the popover content
|
|
932
|
-
// below only wins comparisons within this anchor's own box, not against this anchor's own later
|
|
933
|
-
// siblings (e.g. a Ready button), which are otherwise painted on top by DOM-order tiebreak.
|
|
934
|
-
// Elevating the anchor itself, only while its popover is open, fixes that at the right level.
|
|
935
|
-
anchorOpen: {
|
|
936
|
-
zIndex: 100
|
|
937
|
-
},
|
|
938
|
-
divider: {
|
|
939
|
-
height: StyleSheet11.hairlineWidth,
|
|
940
|
-
marginVertical: 4
|
|
941
|
-
},
|
|
942
|
-
item: {
|
|
943
|
-
borderRadius: 8,
|
|
944
|
-
paddingHorizontal: 12,
|
|
945
|
-
paddingVertical: 8
|
|
946
|
-
},
|
|
947
|
-
itemLabelColumn: {
|
|
948
|
-
maxWidth: MENU_ITEM_LABEL_MAX_WIDTH
|
|
949
|
-
},
|
|
950
|
-
itemLabelFlex: {
|
|
951
|
-
flex: 1
|
|
952
|
-
},
|
|
953
|
-
itemRow: {
|
|
954
|
-
alignItems: "center",
|
|
955
|
-
flexDirection: "row",
|
|
956
|
-
gap: 8
|
|
957
|
-
},
|
|
958
|
-
// Same opacity as ProfilePicker's rowDisabled / InlineColorPicker's swatchTaken — the fleet's
|
|
959
|
-
// established "shown, not removed" treatment for another seat's own current pick.
|
|
960
|
-
itemTaken: {
|
|
961
|
-
opacity: 0.35
|
|
962
|
-
},
|
|
963
|
-
menu: {
|
|
964
|
-
borderRadius: 12,
|
|
965
|
-
borderWidth: MENU_BORDER_WIDTH,
|
|
966
|
-
elevation: 8,
|
|
967
|
-
maxWidth: MENU_MAX_WIDTH,
|
|
968
|
-
minWidth: MENU_MIN_WIDTH,
|
|
969
|
-
shadowColor: "#000000",
|
|
970
|
-
shadowOffset: { height: 2, width: 0 },
|
|
971
|
-
shadowOpacity: 0.3,
|
|
972
|
-
shadowRadius: 8
|
|
973
|
-
},
|
|
974
|
-
// Separate from `menu` itself — a ScrollView's own style sets the scrolling frame's bounds
|
|
975
|
-
// (including the maxHeight that actually caps it), while padding/gap belong to its
|
|
976
|
-
// contentContainerStyle, which sizes to the *unclamped* content instead of the frame.
|
|
977
|
-
menuContent: {
|
|
978
|
-
gap: 4,
|
|
979
|
-
padding: 6
|
|
980
|
-
},
|
|
981
|
-
// Fixed hit-area regardless of the current option's iconSize, so a small-vs-large trigger icon
|
|
982
|
-
// doesn't shift this picker's position within its row.
|
|
983
|
-
triggerBox: {
|
|
984
|
-
alignItems: "center",
|
|
985
|
-
height: TRIGGER_SIZE,
|
|
986
|
-
justifyContent: "center",
|
|
987
|
-
width: TRIGGER_SIZE
|
|
988
|
-
}
|
|
989
|
-
});
|
|
990
|
-
|
|
991
1117
|
// src/SharedActionBand.tsx
|
|
992
1118
|
import { IconButton as IconButton4 } from "@rific/feedback-press";
|
|
993
|
-
import { StyleSheet as
|
|
994
|
-
import { jsx as
|
|
1119
|
+
import { StyleSheet as StyleSheet14, View as View12 } from "react-native";
|
|
1120
|
+
import { jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
995
1121
|
function SharedActionBand({ onBack, onSettings, onRandomize, onReset, fg, popoverOpen, children }) {
|
|
996
|
-
return /* @__PURE__ */
|
|
997
|
-
/* @__PURE__ */
|
|
998
|
-
/* @__PURE__ */
|
|
999
|
-
onRandomize && /* @__PURE__ */
|
|
1000
|
-
onReset && /* @__PURE__ */
|
|
1001
|
-
/* @__PURE__ */
|
|
1122
|
+
return /* @__PURE__ */ jsxs12(View12, { style: [styles13.column, popoverOpen && styles13.columnOpen], children: [
|
|
1123
|
+
/* @__PURE__ */ jsxs12(View12, { style: styles13.actionsRow, children: [
|
|
1124
|
+
/* @__PURE__ */ jsx16(IconButton4, { icon: "arrow-left", iconColor: fg, size: 20, onPress: onBack, accessibilityLabel: "Back" }),
|
|
1125
|
+
onRandomize && /* @__PURE__ */ jsx16(IconButton4, { icon: "dice-multiple", iconColor: fg, size: 18, onPress: onRandomize, accessibilityLabel: "Randomize match settings" }),
|
|
1126
|
+
onReset && /* @__PURE__ */ jsx16(IconButton4, { icon: "restore", iconColor: fg, size: 18, onPress: onReset, accessibilityLabel: "Reset match settings to defaults" }),
|
|
1127
|
+
/* @__PURE__ */ jsx16(IconButton4, { icon: "cog", iconColor: fg, size: 20, onPress: onSettings, accessibilityLabel: "Settings" })
|
|
1002
1128
|
] }),
|
|
1003
1129
|
children
|
|
1004
1130
|
] });
|
|
1005
1131
|
}
|
|
1006
|
-
var
|
|
1132
|
+
var styles13 = StyleSheet14.create({
|
|
1007
1133
|
actionsRow: {
|
|
1008
1134
|
alignItems: "center",
|
|
1009
1135
|
flexDirection: "row",
|
|
@@ -1019,20 +1145,20 @@ var styles11 = StyleSheet12.create({
|
|
|
1019
1145
|
});
|
|
1020
1146
|
|
|
1021
1147
|
// src/StatRow.tsx
|
|
1022
|
-
import { useAutoPaperTheme as
|
|
1023
|
-
import { StyleSheet as
|
|
1024
|
-
import { Text as
|
|
1025
|
-
import { jsx as
|
|
1148
|
+
import { useAutoPaperTheme as useAutoPaperTheme5 } from "@rific/auto-paper";
|
|
1149
|
+
import { StyleSheet as StyleSheet15, View as View13 } from "react-native";
|
|
1150
|
+
import { Text as Text9 } from "react-native-paper";
|
|
1151
|
+
import { jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1026
1152
|
function StatRow({ label, value, fg: fgOverride, fgMuted: fgMutedOverride }) {
|
|
1027
|
-
const { dark } =
|
|
1153
|
+
const { dark } = useAutoPaperTheme5();
|
|
1028
1154
|
const fg = fgOverride ?? (dark ? "#FFFFFF" : "#000000");
|
|
1029
1155
|
const fgMuted = fgMutedOverride ?? (dark ? "rgba(255,255,255,0.5)" : "rgba(0,0,0,0.5)");
|
|
1030
|
-
return /* @__PURE__ */
|
|
1031
|
-
/* @__PURE__ */
|
|
1032
|
-
/* @__PURE__ */
|
|
1156
|
+
return /* @__PURE__ */ jsxs13(View13, { style: styles14.row, children: [
|
|
1157
|
+
/* @__PURE__ */ jsx17(Text9, { variant: "bodyMedium", style: { color: fgMuted }, children: label }),
|
|
1158
|
+
/* @__PURE__ */ jsx17(Text9, { variant: "bodyMedium", style: [styles14.value, { color: fg }], children: value })
|
|
1033
1159
|
] });
|
|
1034
1160
|
}
|
|
1035
|
-
var
|
|
1161
|
+
var styles14 = StyleSheet15.create({
|
|
1036
1162
|
row: {
|
|
1037
1163
|
alignItems: "center",
|
|
1038
1164
|
flexDirection: "row",
|
|
@@ -1044,20 +1170,20 @@ var styles12 = StyleSheet13.create({
|
|
|
1044
1170
|
});
|
|
1045
1171
|
|
|
1046
1172
|
// src/StatSection.tsx
|
|
1047
|
-
import { useAutoPaperTheme as
|
|
1048
|
-
import { StyleSheet as
|
|
1049
|
-
import { Text as
|
|
1050
|
-
import { jsx as
|
|
1173
|
+
import { useAutoPaperTheme as useAutoPaperTheme6 } from "@rific/auto-paper";
|
|
1174
|
+
import { StyleSheet as StyleSheet16, View as View14 } from "react-native";
|
|
1175
|
+
import { Text as Text10 } from "react-native-paper";
|
|
1176
|
+
import { jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1051
1177
|
function StatSection({ label, fg: fgOverride, sectionBg: sectionBgOverride, children }) {
|
|
1052
|
-
const { dark } =
|
|
1178
|
+
const { dark } = useAutoPaperTheme6();
|
|
1053
1179
|
const fg = fgOverride ?? (dark ? "#FFFFFF" : "#000000");
|
|
1054
1180
|
const sectionBg = sectionBgOverride ?? (dark ? "rgba(255,255,255,0.06)" : "rgba(0,0,0,0.04)");
|
|
1055
|
-
return /* @__PURE__ */
|
|
1056
|
-
/* @__PURE__ */
|
|
1181
|
+
return /* @__PURE__ */ jsxs14(View14, { style: [styles15.section, { backgroundColor: sectionBg }], children: [
|
|
1182
|
+
/* @__PURE__ */ jsx18(Text10, { variant: "labelMedium", style: [styles15.label, { color: fg }], children: label }),
|
|
1057
1183
|
children
|
|
1058
1184
|
] });
|
|
1059
1185
|
}
|
|
1060
|
-
var
|
|
1186
|
+
var styles15 = StyleSheet16.create({
|
|
1061
1187
|
// Bold and full-contrast (fg), not the original fontless/fgMuted treatment — that read at the
|
|
1062
1188
|
// same visual weight as StatRow's own row labels below it (both used the identical muted color;
|
|
1063
1189
|
// letterSpacing/variant alone didn't separate them enough to read as "this is the group header"
|
|
@@ -1087,8 +1213,11 @@ export {
|
|
|
1087
1213
|
AchievementRow,
|
|
1088
1214
|
BaseSettingsDialog,
|
|
1089
1215
|
BaseStatsScreen,
|
|
1216
|
+
ConfirmDialog,
|
|
1090
1217
|
ContentGutter,
|
|
1218
|
+
ControlSchemePicker,
|
|
1091
1219
|
CornerActionButtons,
|
|
1220
|
+
CornerStatusBadges,
|
|
1092
1221
|
InlineColorPicker,
|
|
1093
1222
|
LABELED_DROPDOWN_POPOVER_WIDTH,
|
|
1094
1223
|
LOCKED_BADGE_COLOR,
|
|
@@ -1099,6 +1228,7 @@ export {
|
|
|
1099
1228
|
ReadyButton,
|
|
1100
1229
|
SectionedDropdown,
|
|
1101
1230
|
SharedActionBand,
|
|
1231
|
+
SkiaGate,
|
|
1102
1232
|
StatRow,
|
|
1103
1233
|
StatSection,
|
|
1104
1234
|
TriggerGaugeHost,
|