@tastic/hud 0.6.0 → 0.7.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/dist/index.d.mts +107 -63
- package/dist/index.d.ts +107 -63
- package/dist/index.js +448 -337
- package/dist/index.mjs +415 -307
- package/package.json +1 -1
- 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/index.ts +3 -0
package/dist/index.js
CHANGED
|
@@ -28,22 +28,22 @@ __export(TriggerGauge_exports, {
|
|
|
28
28
|
function TriggerGauge({ segments, litIndices, size, accentColor, mutedColor, dashWidth, startDeg = DEFAULT_START_DEG, endDeg = startDeg }) {
|
|
29
29
|
const totalDurationMs = MOUNT_DURATION_MS + Math.max(0, segments - 1) * MOUNT_STAGGER_MS;
|
|
30
30
|
const mountProgress = (0, import_react_native_reanimated.useSharedValue)(0);
|
|
31
|
-
(0,
|
|
31
|
+
(0, import_react3.useLayoutEffect)(() => {
|
|
32
32
|
mountProgress.value = (0, import_react_native_reanimated.withTiming)(1, { duration: totalDurationMs, easing: import_react_native_reanimated.Easing.out(import_react_native_reanimated.Easing.cubic) });
|
|
33
33
|
}, []);
|
|
34
34
|
const rawSweepDeg = ((endDeg - startDeg) % 360 + 360) % 360;
|
|
35
35
|
const totalSweepDeg = rawSweepDeg === 0 ? 360 : rawSweepDeg;
|
|
36
36
|
const step = segments > 0 ? totalSweepDeg / segments : 0;
|
|
37
|
-
const centerDeg = (0,
|
|
37
|
+
const centerDeg = (0, import_react3.useCallback)((i) => startDeg + (i + 0.5) * step, [startDeg, step]);
|
|
38
38
|
const singleSelect = litIndices.length === 1;
|
|
39
39
|
const angleDeg = (0, import_react_native_reanimated.useSharedValue)(centerDeg(litIndices[0] ?? 0));
|
|
40
40
|
const litIndicesKey = [...litIndices].sort((a, b) => a - b).join(",");
|
|
41
|
-
const [transitionFrom, setTransitionFrom] = (0,
|
|
41
|
+
const [transitionFrom, setTransitionFrom] = (0, import_react3.useState)(litIndices);
|
|
42
42
|
const transitionFromKey = [...transitionFrom].sort((a, b) => a - b).join(",");
|
|
43
|
-
const lastKeyRef = (0,
|
|
44
|
-
const lastIndicesRef = (0,
|
|
43
|
+
const lastKeyRef = (0, import_react3.useRef)(litIndicesKey);
|
|
44
|
+
const lastIndicesRef = (0, import_react3.useRef)(litIndices);
|
|
45
45
|
const selectionProgress = (0, import_react_native_reanimated.useSharedValue)(1);
|
|
46
|
-
(0,
|
|
46
|
+
(0, import_react3.useLayoutEffect)(() => {
|
|
47
47
|
if (litIndicesKey !== lastKeyRef.current) {
|
|
48
48
|
if (singleSelect && lastIndicesRef.current.length === 1) {
|
|
49
49
|
angleDeg.value = (0, import_react_native_reanimated.withTiming)(centerDeg(litIndices[0]), { duration: SELECTION_TRANSITION_DURATION_MS, easing: import_react_native_reanimated.Easing.out(import_react_native_reanimated.Easing.cubic) });
|
|
@@ -72,7 +72,7 @@ function TriggerGauge({ segments, litIndices, size, accentColor, mutedColor, das
|
|
|
72
72
|
if (mountProgress.value < 1) {
|
|
73
73
|
const startFrac = i * MOUNT_STAGGER_MS / totalDurationMs;
|
|
74
74
|
const endFrac = startFrac + MOUNT_DURATION_MS / totalDurationMs;
|
|
75
|
-
local = (0,
|
|
75
|
+
local = (0, import_core3.clamp)((mountProgress.value - startFrac) / (endFrac - startFrac), 0, 1);
|
|
76
76
|
}
|
|
77
77
|
const sweep = dashAngleDeg * local;
|
|
78
78
|
if (sweep <= 0) continue;
|
|
@@ -96,7 +96,7 @@ function TriggerGauge({ segments, litIndices, size, accentColor, mutedColor, das
|
|
|
96
96
|
if (!isLitNow) continue;
|
|
97
97
|
const startFrac = i * MOUNT_STAGGER_MS / totalDurationMs;
|
|
98
98
|
const endFrac = startFrac + MOUNT_DURATION_MS / totalDurationMs;
|
|
99
|
-
local = (0,
|
|
99
|
+
local = (0, import_core3.clamp)((mountProgress.value - startFrac) / (endFrac - startFrac), 0, 1);
|
|
100
100
|
} else if (isLitNow === wasLit) {
|
|
101
101
|
local = 1;
|
|
102
102
|
} else if (isLitNow) {
|
|
@@ -120,21 +120,21 @@ function TriggerGauge({ segments, litIndices, size, accentColor, mutedColor, das
|
|
|
120
120
|
height: canvasSize,
|
|
121
121
|
width: canvasSize
|
|
122
122
|
};
|
|
123
|
-
return /* @__PURE__ */ (0,
|
|
124
|
-
/* @__PURE__ */ (0,
|
|
125
|
-
/* @__PURE__ */ (0,
|
|
123
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native8.View, { style: [styles7.container, gaugeSizeStyle], pointerEvents: "none", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_native_skia.Canvas, { style: canvasSizeStyle, children: [
|
|
124
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native_skia.Path, { path: unlitPath, style: "stroke", strokeWidth: UNLIT_THICKNESS, strokeCap: "round", color: mutedColor, opacity: 0.35 }),
|
|
125
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native_skia.Path, { path: litPath, style: "stroke", strokeWidth: LIT_THICKNESS, strokeCap: "round", color: accentColor, opacity: 1 })
|
|
126
126
|
] }) });
|
|
127
127
|
}
|
|
128
|
-
var import_react_native_skia,
|
|
128
|
+
var import_react_native_skia, import_core3, import_react3, import_react_native8, import_react_native_reanimated, import_jsx_runtime7, UNLIT_THICKNESS, LIT_THICKNESS, DASH_GAP_PX, ARC_GAP, DEFAULT_START_DEG, MIN_DASH_ANGLE_DEG, MOUNT_DURATION_MS, MOUNT_STAGGER_MS, SELECTION_TRANSITION_DURATION_MS, styles7;
|
|
129
129
|
var init_TriggerGauge = __esm({
|
|
130
130
|
"src/TriggerGauge.tsx"() {
|
|
131
131
|
"use strict";
|
|
132
132
|
import_react_native_skia = require("@shopify/react-native-skia");
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
133
|
+
import_core3 = require("@tastic/core");
|
|
134
|
+
import_react3 = require("react");
|
|
135
|
+
import_react_native8 = require("react-native");
|
|
136
136
|
import_react_native_reanimated = require("react-native-reanimated");
|
|
137
|
-
|
|
137
|
+
import_jsx_runtime7 = require("react/jsx-runtime");
|
|
138
138
|
UNLIT_THICKNESS = 3;
|
|
139
139
|
LIT_THICKNESS = 7;
|
|
140
140
|
DASH_GAP_PX = 9;
|
|
@@ -144,7 +144,7 @@ var init_TriggerGauge = __esm({
|
|
|
144
144
|
MOUNT_DURATION_MS = 450;
|
|
145
145
|
MOUNT_STAGGER_MS = 40;
|
|
146
146
|
SELECTION_TRANSITION_DURATION_MS = 260;
|
|
147
|
-
|
|
147
|
+
styles7 = import_react_native8.StyleSheet.create({
|
|
148
148
|
container: {
|
|
149
149
|
alignItems: "center",
|
|
150
150
|
justifyContent: "center",
|
|
@@ -160,8 +160,11 @@ __export(index_exports, {
|
|
|
160
160
|
AchievementRow: () => AchievementRow,
|
|
161
161
|
BaseSettingsDialog: () => BaseSettingsDialog,
|
|
162
162
|
BaseStatsScreen: () => BaseStatsScreen,
|
|
163
|
+
ConfirmDialog: () => ConfirmDialog,
|
|
163
164
|
ContentGutter: () => ContentGutter,
|
|
165
|
+
ControlSchemePicker: () => ControlSchemePicker,
|
|
164
166
|
CornerActionButtons: () => CornerActionButtons,
|
|
167
|
+
CornerStatusBadges: () => CornerStatusBadges,
|
|
165
168
|
InlineColorPicker: () => InlineColorPicker,
|
|
166
169
|
LABELED_DROPDOWN_POPOVER_WIDTH: () => LABELED_DROPDOWN_POPOVER_WIDTH,
|
|
167
170
|
LOCKED_BADGE_COLOR: () => LOCKED_BADGE_COLOR,
|
|
@@ -553,60 +556,103 @@ var styles3 = import_react_native3.StyleSheet.create({
|
|
|
553
556
|
}
|
|
554
557
|
});
|
|
555
558
|
|
|
556
|
-
// src/
|
|
557
|
-
var
|
|
559
|
+
// src/ConfirmDialog.tsx
|
|
560
|
+
var import_auto_paper4 = require("@rific/auto-paper");
|
|
561
|
+
var import_feedback_press3 = require("@rific/feedback-press");
|
|
558
562
|
var import_react_native4 = require("react-native");
|
|
563
|
+
var import_react_native_paper4 = require("react-native-paper");
|
|
559
564
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
560
|
-
function
|
|
561
|
-
const {
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
565
|
+
function ConfirmDialog({ visible, title, message, confirmLabel, cancelLabel, onConfirm, onCancel, rotation = 0, icon = "help-circle-outline", destructive = false }) {
|
|
566
|
+
const { dark, colors } = (0, import_auto_paper4.useAutoPaperTheme)();
|
|
567
|
+
if (!visible) return null;
|
|
568
|
+
const fg = dark ? "#FFFFFF" : "#000000";
|
|
569
|
+
const cardBg = dark ? "#111111" : "#F2F2F2";
|
|
570
|
+
const cardBorder = dark ? "rgba(255,255,255,0.2)" : "rgba(0,0,0,0.2)";
|
|
571
|
+
const accent = destructive ? colors.danger : colors.primary;
|
|
572
|
+
const onAccent = destructive ? colors.onDanger : colors.onPrimary;
|
|
573
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native_paper4.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.View, { style: styles4.overlay, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native4.View, { style: [styles4.card, { backgroundColor: cardBg, borderColor: cardBorder }, rotation % 360 !== 0 && { transform: [{ rotate: `${rotation}deg` }] }], children: [
|
|
574
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native_paper4.Icon, { source: icon, size: 64, color: accent }),
|
|
575
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native_paper4.Text, { variant: "headlineLarge", style: [styles4.title, { color: accent }], children: title }),
|
|
576
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native_paper4.Text, { variant: "bodyLarge", style: [styles4.body, { color: fg }], children: message }),
|
|
577
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native4.View, { style: styles4.actions, children: [
|
|
578
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_feedback_press3.Button, { mode: "outlined", onPress: onCancel, style: styles4.actionButton, children: cancelLabel }),
|
|
579
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_feedback_press3.Button, { mode: "contained", onPress: onConfirm, style: styles4.actionButton, buttonColor: accent, textColor: onAccent, children: confirmLabel })
|
|
580
|
+
] })
|
|
581
|
+
] }) }) });
|
|
568
582
|
}
|
|
569
583
|
var styles4 = import_react_native4.StyleSheet.create({
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
gutter: {
|
|
573
|
-
overflow: "hidden"
|
|
584
|
+
actionButton: {
|
|
585
|
+
flex: 1
|
|
574
586
|
},
|
|
575
|
-
|
|
576
|
-
flexDirection: "row"
|
|
587
|
+
actions: {
|
|
588
|
+
flexDirection: "row",
|
|
589
|
+
gap: 12,
|
|
590
|
+
width: "100%"
|
|
591
|
+
},
|
|
592
|
+
body: {
|
|
593
|
+
textAlign: "center"
|
|
594
|
+
},
|
|
595
|
+
card: {
|
|
596
|
+
alignItems: "center",
|
|
597
|
+
borderRadius: 20,
|
|
598
|
+
borderWidth: 1,
|
|
599
|
+
gap: 16,
|
|
600
|
+
maxWidth: 360,
|
|
601
|
+
padding: 32
|
|
602
|
+
},
|
|
603
|
+
overlay: {
|
|
604
|
+
alignItems: "center",
|
|
605
|
+
backgroundColor: "rgba(0,0,0,0.72)",
|
|
606
|
+
bottom: 0,
|
|
607
|
+
justifyContent: "center",
|
|
608
|
+
left: 0,
|
|
609
|
+
position: "absolute",
|
|
610
|
+
right: 0,
|
|
611
|
+
top: 0
|
|
612
|
+
},
|
|
613
|
+
title: {
|
|
614
|
+
fontWeight: "bold"
|
|
577
615
|
}
|
|
578
616
|
});
|
|
579
617
|
|
|
580
|
-
// src/
|
|
581
|
-
var
|
|
618
|
+
// src/ContentGutter.tsx
|
|
619
|
+
var import_core2 = require("@tastic/core");
|
|
582
620
|
var import_react_native5 = require("react-native");
|
|
583
621
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
584
|
-
function
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
622
|
+
function ContentGutter({ maxContentWidth, leftGutter, rightGutter, style, children }) {
|
|
623
|
+
const { width: windowWidth } = (0, import_react_native5.useWindowDimensions)();
|
|
624
|
+
const { contentWidth, gutterWidth } = (0, import_core2.computeContentBounds)(windowWidth, maxContentWidth ?? Infinity);
|
|
625
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native5.View, { style: [styles5.row, style], children: [
|
|
626
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native5.View, { style: [styles5.gutter, { width: gutterWidth }], children: leftGutter }),
|
|
627
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native5.View, { style: { width: contentWidth }, children }),
|
|
628
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native5.View, { style: [styles5.gutter, { width: gutterWidth }], children: rightGutter })
|
|
588
629
|
] });
|
|
589
630
|
}
|
|
590
631
|
var styles5 = import_react_native5.StyleSheet.create({
|
|
591
|
-
|
|
592
|
-
|
|
632
|
+
// overflow:'hidden' keeps an oversized leftGutter/rightGutter from bleeding into the content
|
|
633
|
+
// column instead of clipping cleanly at its own real width.
|
|
634
|
+
gutter: {
|
|
635
|
+
overflow: "hidden"
|
|
593
636
|
},
|
|
594
|
-
|
|
595
|
-
|
|
637
|
+
row: {
|
|
638
|
+
flexDirection: "row"
|
|
596
639
|
}
|
|
597
640
|
});
|
|
598
641
|
|
|
642
|
+
// src/ControlSchemePicker.tsx
|
|
643
|
+
var import_core4 = require("@tastic/core");
|
|
644
|
+
var import_react_native11 = require("react-native");
|
|
645
|
+
|
|
646
|
+
// src/SectionedDropdown.tsx
|
|
647
|
+
var import_auto_paper5 = require("@rific/auto-paper");
|
|
648
|
+
var import_feedback_press4 = require("@rific/feedback-press");
|
|
649
|
+
var import_react_native10 = require("react-native");
|
|
650
|
+
var import_react_native_paper5 = require("react-native-paper");
|
|
651
|
+
|
|
599
652
|
// src/fonts.ts
|
|
600
653
|
var import_react_native6 = require("react-native");
|
|
601
654
|
var MONO_FONT = import_react_native6.Platform.select({ ios: "Menlo", android: "monospace", default: "monospace" });
|
|
602
655
|
|
|
603
|
-
// src/InlineColorPicker.tsx
|
|
604
|
-
var import_auto_paper4 = require("@rific/auto-paper");
|
|
605
|
-
var import_feedback_press4 = require("@rific/feedback-press");
|
|
606
|
-
var import_core3 = require("@tastic/core");
|
|
607
|
-
var import_react_native9 = require("react-native");
|
|
608
|
-
var import_react_native_paper4 = require("react-native-paper");
|
|
609
|
-
|
|
610
656
|
// src/PopoverBody.tsx
|
|
611
657
|
var import_react_native7 = require("react-native");
|
|
612
658
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
@@ -673,23 +719,38 @@ var styles6 = import_react_native7.StyleSheet.create({
|
|
|
673
719
|
}
|
|
674
720
|
});
|
|
675
721
|
|
|
722
|
+
// src/TriggerGaugeHost.tsx
|
|
723
|
+
var import_react4 = require("react");
|
|
724
|
+
|
|
725
|
+
// src/loadSkiaWeb.ts
|
|
726
|
+
function loadSkiaWeb() {
|
|
727
|
+
return Promise.resolve();
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
// src/TriggerGaugeHost.tsx
|
|
731
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
732
|
+
var LazyTriggerGauge = (0, import_react4.lazy)(() => loadSkiaWeb().then(() => Promise.resolve().then(() => (init_TriggerGauge(), TriggerGauge_exports)).then((m) => ({ default: m.TriggerGauge }))));
|
|
733
|
+
function TriggerGaugeHost(props) {
|
|
734
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react4.Suspense, { fallback: null, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(LazyTriggerGauge, { ...props }) });
|
|
735
|
+
}
|
|
736
|
+
|
|
676
737
|
// src/useAutoAlign.ts
|
|
677
|
-
var
|
|
678
|
-
var
|
|
738
|
+
var import_react5 = require("react");
|
|
739
|
+
var import_react_native9 = require("react-native");
|
|
679
740
|
var EDGE_MARGIN = 12;
|
|
680
741
|
function useAutoAlign(open, contentWidth, contentHeight) {
|
|
681
|
-
const triggerRef = (0,
|
|
682
|
-
const { width: windowWidth, height: windowHeight } = (0,
|
|
683
|
-
const [align, setAlign] = (0,
|
|
684
|
-
const [verticalAlign, setVerticalAlign] = (0,
|
|
685
|
-
const [maxHeight, setMaxHeight] = (0,
|
|
686
|
-
const [measured, setMeasured] = (0,
|
|
687
|
-
const [prevOpen, setPrevOpen] = (0,
|
|
742
|
+
const triggerRef = (0, import_react5.useRef)(null);
|
|
743
|
+
const { width: windowWidth, height: windowHeight } = (0, import_react_native9.useWindowDimensions)();
|
|
744
|
+
const [align, setAlign] = (0, import_react5.useState)("center");
|
|
745
|
+
const [verticalAlign, setVerticalAlign] = (0, import_react5.useState)("below");
|
|
746
|
+
const [maxHeight, setMaxHeight] = (0, import_react5.useState)(contentHeight);
|
|
747
|
+
const [measured, setMeasured] = (0, import_react5.useState)(false);
|
|
748
|
+
const [prevOpen, setPrevOpen] = (0, import_react5.useState)(open);
|
|
688
749
|
if (open !== prevOpen) {
|
|
689
750
|
setPrevOpen(open);
|
|
690
751
|
if (open) setMeasured(false);
|
|
691
752
|
}
|
|
692
|
-
const measure = (0,
|
|
753
|
+
const measure = (0, import_react5.useCallback)(() => {
|
|
693
754
|
triggerRef.current?.measureInWindow((x, y, triggerWidth, triggerHeight) => {
|
|
694
755
|
const centerX = x + triggerWidth / 2;
|
|
695
756
|
const overflowsRight = centerX + contentWidth / 2 > windowWidth - EDGE_MARGIN;
|
|
@@ -705,14 +766,272 @@ function useAutoAlign(open, contentWidth, contentHeight) {
|
|
|
705
766
|
setMeasured(true);
|
|
706
767
|
});
|
|
707
768
|
}, [contentWidth, contentHeight, windowWidth, windowHeight]);
|
|
708
|
-
(0,
|
|
769
|
+
(0, import_react5.useEffect)(() => {
|
|
709
770
|
if (open) measure();
|
|
710
771
|
}, [open, measure]);
|
|
711
772
|
return { align, maxHeight, measured, triggerRef, verticalAlign };
|
|
712
773
|
}
|
|
713
774
|
|
|
775
|
+
// src/SectionedDropdown.tsx
|
|
776
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
777
|
+
var MENU_BORDER_WIDTH = 1;
|
|
778
|
+
var TRIGGER_SIZE = 44;
|
|
779
|
+
var MENU_MIN_WIDTH = 200;
|
|
780
|
+
var MENU_MAX_WIDTH = 220;
|
|
781
|
+
var MENU_ITEM_ICON_SIZE = 18;
|
|
782
|
+
var MENU_ITEM_LABEL_MAX_WIDTH = 150;
|
|
783
|
+
var MENU_ITEM_HEIGHT = 40;
|
|
784
|
+
var MENU_ITEM_HEIGHT_WITH_DESCRIPTION = 58;
|
|
785
|
+
var MENU_DIVIDER_HEIGHT = 9;
|
|
786
|
+
var MENU_VERTICAL_PADDING = 12;
|
|
787
|
+
function SectionedDropdown({ id, host, icon, accessibilityLabel, sections, accentColor, mutedColor, onAccentColor, dark, align: alignOverride, autoDismiss = true, labelFontFamily = MONO_FONT, allClearLabels = { all: "All", clear: "Clear" } }) {
|
|
788
|
+
const menuBg = dark ? "#000000" : "#FFFFFF";
|
|
789
|
+
const menuBorderColor = (0, import_auto_paper5.getBlendedColor)(mutedColor, menuBg, 0.5);
|
|
790
|
+
const resolvedOnAccentColor = onAccentColor ?? (0, import_auto_paper5.getColorRoles)(accentColor, menuBg).onColor;
|
|
791
|
+
const fg = dark ? "#FFFFFF" : "#000000";
|
|
792
|
+
const open = host.openId === id;
|
|
793
|
+
const estimatedHeight = MENU_VERTICAL_PADDING + sections.reduce((sum, section, sectionIndex) => {
|
|
794
|
+
const rows = section.options.reduce((rowSum, option) => rowSum + (option.description ? MENU_ITEM_HEIGHT_WITH_DESCRIPTION : MENU_ITEM_HEIGHT), 0);
|
|
795
|
+
const footer = section.kind === "multi" && section.allClear ? MENU_ITEM_HEIGHT : 0;
|
|
796
|
+
const divider = sectionIndex > 0 ? MENU_DIVIDER_HEIGHT : 0;
|
|
797
|
+
return sum + rows + footer + divider;
|
|
798
|
+
}, 0);
|
|
799
|
+
const { align: autoAlign, maxHeight, measured, triggerRef, verticalAlign } = useAutoAlign(open, MENU_MAX_WIDTH, estimatedHeight);
|
|
800
|
+
const align = alignOverride ?? autoAlign;
|
|
801
|
+
const onlySection = sections.length === 1 ? sections[0] : null;
|
|
802
|
+
const selectedOption = onlySection?.kind === "single" ? onlySection.options.find((o) => o.value === onlySection.value) : void 0;
|
|
803
|
+
const triggerIcon = selectedOption?.icon ?? icon;
|
|
804
|
+
const triggerIconSize = selectedOption?.iconSize ?? 22;
|
|
805
|
+
const hasMultiSection = sections.some((s) => s.kind === "multi");
|
|
806
|
+
const anyMultiSelected = sections.some((s) => s.kind === "multi" && s.value.length > 0);
|
|
807
|
+
const triggerIconColor = hasMultiSection ? anyMultiSelected ? accentColor : fg : fg;
|
|
808
|
+
const gaugeSegments = sections.reduce((sum, section) => sum + section.options.length, 0);
|
|
809
|
+
const gaugeLitIndices = [];
|
|
810
|
+
let gaugeOffset = 0;
|
|
811
|
+
for (const section of sections) {
|
|
812
|
+
if (section.kind === "single") {
|
|
813
|
+
const index = section.options.findIndex((o) => o.value === section.value);
|
|
814
|
+
if (index >= 0) gaugeLitIndices.push(gaugeOffset + index);
|
|
815
|
+
} else {
|
|
816
|
+
section.options.forEach((o, i) => {
|
|
817
|
+
if (section.value.includes(o.value)) gaugeLitIndices.push(gaugeOffset + i);
|
|
818
|
+
});
|
|
819
|
+
}
|
|
820
|
+
gaugeOffset += section.options.length;
|
|
821
|
+
}
|
|
822
|
+
const anchorStyle = [styles8.anchor, open && styles8.anchorOpen];
|
|
823
|
+
const menuStyle = { backgroundColor: menuBg, borderColor: menuBorderColor, maxHeight };
|
|
824
|
+
const dividerStyle = { backgroundColor: menuBorderColor };
|
|
825
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native10.View, { style: anchorStyle, children: [
|
|
826
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native10.View, { ref: triggerRef, collapsable: false, style: styles8.triggerBox, children: [
|
|
827
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TriggerGaugeHost, { segments: gaugeSegments, litIndices: gaugeLitIndices, size: TRIGGER_SIZE, accentColor, mutedColor }),
|
|
828
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_feedback_press4.IconButton, { icon: triggerIcon, iconColor: triggerIconColor, size: triggerIconSize, accessibilityLabel, onPress: () => host.toggle(id) })
|
|
829
|
+
] }),
|
|
830
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: menuBorderColor, caretBorderWidth: MENU_BORDER_WIDTH, triggerSize: TRIGGER_SIZE, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native10.ScrollView, { style: [styles8.menu, menuStyle], contentContainerStyle: styles8.menuContent, showsVerticalScrollIndicator: false, children: sections.map((section, sectionIndex) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native10.View, { children: [
|
|
831
|
+
sectionIndex > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native10.View, { style: [styles8.divider, dividerStyle] }),
|
|
832
|
+
section.kind === "single" ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
833
|
+
SingleSection,
|
|
834
|
+
{
|
|
835
|
+
section,
|
|
836
|
+
accentColor,
|
|
837
|
+
onAccentColor: resolvedOnAccentColor,
|
|
838
|
+
mutedColor,
|
|
839
|
+
labelFontFamily,
|
|
840
|
+
onSelect: (value) => {
|
|
841
|
+
section.onChange(value);
|
|
842
|
+
if (autoDismiss) host.close();
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(MultiSection, { section, accentColor, onAccentColor: resolvedOnAccentColor, mutedColor, labelFontFamily, allClearLabels })
|
|
846
|
+
] }, section.id)) }) })
|
|
847
|
+
] });
|
|
848
|
+
}
|
|
849
|
+
function SingleSection({
|
|
850
|
+
section,
|
|
851
|
+
accentColor,
|
|
852
|
+
onAccentColor,
|
|
853
|
+
mutedColor,
|
|
854
|
+
labelFontFamily,
|
|
855
|
+
onSelect
|
|
856
|
+
}) {
|
|
857
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_jsx_runtime9.Fragment, { children: section.options.map((option) => {
|
|
858
|
+
const selected = option.value === section.value;
|
|
859
|
+
const taken = !selected && option.value === section.takenValue;
|
|
860
|
+
const rowColor = selected ? onAccentColor : mutedColor;
|
|
861
|
+
const itemStyle = [styles8.item, selected && { backgroundColor: accentColor }, taken && styles8.itemTaken];
|
|
862
|
+
const labelStyle = { fontFamily: labelFontFamily, color: rowColor, fontWeight: selected ? "bold" : "normal" };
|
|
863
|
+
const descriptionStyle = { fontFamily: labelFontFamily, color: rowColor };
|
|
864
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_feedback_press4.TouchableRipple, { disabled: taken, onPress: () => onSelect(option.value), style: itemStyle, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native10.View, { style: styles8.itemRow, children: [
|
|
865
|
+
option.icon && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_paper5.Icon, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
|
|
866
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native10.View, { style: styles8.itemLabelColumn, children: [
|
|
867
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_paper5.Text, { variant: "labelLarge", style: labelStyle, children: option.label }),
|
|
868
|
+
option.description && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_paper5.Text, { variant: "labelSmall", style: descriptionStyle, children: option.description })
|
|
869
|
+
] })
|
|
870
|
+
] }) }, option.value);
|
|
871
|
+
}) });
|
|
872
|
+
}
|
|
873
|
+
function MultiSection({
|
|
874
|
+
section,
|
|
875
|
+
accentColor,
|
|
876
|
+
onAccentColor,
|
|
877
|
+
mutedColor,
|
|
878
|
+
labelFontFamily,
|
|
879
|
+
allClearLabels
|
|
880
|
+
}) {
|
|
881
|
+
const allSelected = section.value.length === section.options.length;
|
|
882
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
883
|
+
section.options.map((option, i) => {
|
|
884
|
+
const selected = section.value.includes(option.value);
|
|
885
|
+
const rowColor = selected ? onAccentColor : mutedColor;
|
|
886
|
+
const prevSelected = selected && i > 0 && section.value.includes(section.options[i - 1].value);
|
|
887
|
+
const nextSelected = selected && i < section.options.length - 1 && section.value.includes(section.options[i + 1].value);
|
|
888
|
+
const itemStyle = [styles8.item, selected && { backgroundColor: accentColor }, prevSelected && { borderTopLeftRadius: 0, borderTopRightRadius: 0 }, nextSelected && { borderBottomLeftRadius: 0, borderBottomRightRadius: 0 }];
|
|
889
|
+
const labelStyle = { fontFamily: labelFontFamily, color: rowColor, fontWeight: selected ? "bold" : "normal" };
|
|
890
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_feedback_press4.TouchableRipple, { onPress: () => section.onChange(selected ? section.value.filter((v) => v !== option.value) : [...section.value, option.value]), style: itemStyle, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native10.View, { style: styles8.itemRow, children: [
|
|
891
|
+
option.icon && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_paper5.Icon, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
|
|
892
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_paper5.Text, { variant: "labelLarge", style: [styles8.itemLabelFlex, labelStyle], children: option.label })
|
|
893
|
+
] }) }, option.value);
|
|
894
|
+
}),
|
|
895
|
+
section.allClear && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_feedback_press4.TouchableRipple, { onPress: () => section.onChange(allSelected ? [] : section.options.map((o) => o.value)), style: styles8.item, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_paper5.Text, { variant: "labelLarge", style: [styles8.allClearLabel, { fontFamily: labelFontFamily, color: accentColor }], children: allSelected ? allClearLabels.clear : allClearLabels.all }) })
|
|
896
|
+
] });
|
|
897
|
+
}
|
|
898
|
+
var styles8 = import_react_native10.StyleSheet.create({
|
|
899
|
+
allClearLabel: {
|
|
900
|
+
fontWeight: "bold",
|
|
901
|
+
textAlign: "center"
|
|
902
|
+
},
|
|
903
|
+
anchor: {
|
|
904
|
+
position: "relative"
|
|
905
|
+
},
|
|
906
|
+
// React Native Web gives every position:'relative' view an explicit zIndex (0, not 'auto'),
|
|
907
|
+
// which makes each one its own stacking context — so a zIndex set only on the popover content
|
|
908
|
+
// below only wins comparisons within this anchor's own box, not against this anchor's own later
|
|
909
|
+
// siblings (e.g. a Ready button), which are otherwise painted on top by DOM-order tiebreak.
|
|
910
|
+
// Elevating the anchor itself, only while its popover is open, fixes that at the right level.
|
|
911
|
+
anchorOpen: {
|
|
912
|
+
zIndex: 100
|
|
913
|
+
},
|
|
914
|
+
divider: {
|
|
915
|
+
height: import_react_native10.StyleSheet.hairlineWidth,
|
|
916
|
+
marginVertical: 4
|
|
917
|
+
},
|
|
918
|
+
item: {
|
|
919
|
+
borderRadius: 8,
|
|
920
|
+
paddingHorizontal: 12,
|
|
921
|
+
paddingVertical: 8
|
|
922
|
+
},
|
|
923
|
+
itemLabelColumn: {
|
|
924
|
+
maxWidth: MENU_ITEM_LABEL_MAX_WIDTH
|
|
925
|
+
},
|
|
926
|
+
itemLabelFlex: {
|
|
927
|
+
flex: 1
|
|
928
|
+
},
|
|
929
|
+
itemRow: {
|
|
930
|
+
alignItems: "center",
|
|
931
|
+
flexDirection: "row",
|
|
932
|
+
gap: 8
|
|
933
|
+
},
|
|
934
|
+
// Same opacity as ProfilePicker's rowDisabled / InlineColorPicker's swatchTaken — the fleet's
|
|
935
|
+
// established "shown, not removed" treatment for another seat's own current pick.
|
|
936
|
+
itemTaken: {
|
|
937
|
+
opacity: 0.35
|
|
938
|
+
},
|
|
939
|
+
menu: {
|
|
940
|
+
borderRadius: 12,
|
|
941
|
+
borderWidth: MENU_BORDER_WIDTH,
|
|
942
|
+
elevation: 8,
|
|
943
|
+
maxWidth: MENU_MAX_WIDTH,
|
|
944
|
+
minWidth: MENU_MIN_WIDTH,
|
|
945
|
+
shadowColor: "#000000",
|
|
946
|
+
shadowOffset: { height: 2, width: 0 },
|
|
947
|
+
shadowOpacity: 0.3,
|
|
948
|
+
shadowRadius: 8
|
|
949
|
+
},
|
|
950
|
+
// Separate from `menu` itself — a ScrollView's own style sets the scrolling frame's bounds
|
|
951
|
+
// (including the maxHeight that actually caps it), while padding/gap belong to its
|
|
952
|
+
// contentContainerStyle, which sizes to the *unclamped* content instead of the frame.
|
|
953
|
+
menuContent: {
|
|
954
|
+
gap: 4,
|
|
955
|
+
padding: 6
|
|
956
|
+
},
|
|
957
|
+
// Fixed hit-area regardless of the current option's iconSize, so a small-vs-large trigger icon
|
|
958
|
+
// doesn't shift this picker's position within its row.
|
|
959
|
+
triggerBox: {
|
|
960
|
+
alignItems: "center",
|
|
961
|
+
height: TRIGGER_SIZE,
|
|
962
|
+
justifyContent: "center",
|
|
963
|
+
width: TRIGGER_SIZE
|
|
964
|
+
}
|
|
965
|
+
});
|
|
966
|
+
|
|
967
|
+
// src/ControlSchemePicker.tsx
|
|
968
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
969
|
+
function ControlSchemePicker({ id, host, value, onChange, options, takenValue, accentColor, mutedColor, onAccentColor, dark, align, labelFontFamily }) {
|
|
970
|
+
const isTouchPrimary = (0, import_core4.useIsTouchPrimaryDevice)();
|
|
971
|
+
if (import_react_native11.Platform.OS !== "web" || isTouchPrimary) return null;
|
|
972
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SectionedDropdown, { id, host, icon: "keyboard-outline", accessibilityLabel: "Control scheme", sections: [{ kind: "single", id: "controls", options, value, onChange, takenValue }], accentColor, mutedColor, onAccentColor, dark, align, labelFontFamily });
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
// src/CornerActionButtons.tsx
|
|
976
|
+
var import_feedback_press5 = require("@rific/feedback-press");
|
|
977
|
+
var import_react_native12 = require("react-native");
|
|
978
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
979
|
+
function CornerActionButtons({ onBack, onSettings, fg, insets, backIcon = "arrow-left", backLabel = "Back" }) {
|
|
980
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
981
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_feedback_press5.IconButton, { icon: backIcon, iconColor: fg, size: 24, style: [styles9.back, { top: 8 + insets.top, left: 8 + insets.left }], onPress: onBack, accessibilityLabel: backLabel }),
|
|
982
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_feedback_press5.IconButton, { icon: "cog", iconColor: fg, size: 24, style: [styles9.topRight, { top: 8 + insets.top, right: 8 + insets.right }], onPress: onSettings, accessibilityLabel: "Settings" })
|
|
983
|
+
] });
|
|
984
|
+
}
|
|
985
|
+
var styles9 = import_react_native12.StyleSheet.create({
|
|
986
|
+
back: {
|
|
987
|
+
position: "absolute"
|
|
988
|
+
},
|
|
989
|
+
topRight: {
|
|
990
|
+
position: "absolute"
|
|
991
|
+
}
|
|
992
|
+
});
|
|
993
|
+
|
|
994
|
+
// src/CornerStatusBadges.tsx
|
|
995
|
+
var import_react_native13 = require("react-native");
|
|
996
|
+
var import_react_native_paper6 = require("react-native-paper");
|
|
997
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
998
|
+
var BADGE_SIZE = 30;
|
|
999
|
+
function StatusBadge({ icon }) {
|
|
1000
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native13.View, { style: styles10.badge, children: icon && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native_paper6.Icon, { source: icon, size: 16, color: "rgba(255,255,255,0.85)" }) });
|
|
1001
|
+
}
|
|
1002
|
+
function CornerStatusBadges({ orientationMode, p1OnRight, p1, p2 }) {
|
|
1003
|
+
const p1OnRightSide = orientationMode === "sideBySide" && p1OnRight;
|
|
1004
|
+
const p2OnLeftSide = orientationMode === "sideBySide" && !p1OnRight;
|
|
1005
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
|
|
1006
|
+
p1 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native13.View, { pointerEvents: "none", style: p1OnRightSide ? styles10.bottomRight : styles10.bottomLeft, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(StatusBadge, { icon: p1.icon }) }),
|
|
1007
|
+
p2 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native13.View, { pointerEvents: "none", style: p2OnLeftSide ? styles10.topLeft : styles10.topRight, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(StatusBadge, { icon: p2.icon }) })
|
|
1008
|
+
] });
|
|
1009
|
+
}
|
|
1010
|
+
var styles10 = import_react_native13.StyleSheet.create({
|
|
1011
|
+
badge: {
|
|
1012
|
+
alignItems: "center",
|
|
1013
|
+
backgroundColor: "rgba(0,0,0,0.28)",
|
|
1014
|
+
borderColor: "rgba(255,255,255,0.18)",
|
|
1015
|
+
borderRadius: BADGE_SIZE / 2,
|
|
1016
|
+
borderWidth: 1,
|
|
1017
|
+
height: BADGE_SIZE,
|
|
1018
|
+
justifyContent: "center",
|
|
1019
|
+
opacity: 0.7,
|
|
1020
|
+
width: BADGE_SIZE
|
|
1021
|
+
},
|
|
1022
|
+
bottomLeft: { bottom: 12, left: 12, position: "absolute" },
|
|
1023
|
+
bottomRight: { bottom: 12, position: "absolute", right: 12 },
|
|
1024
|
+
topLeft: { left: 12, position: "absolute", top: 12 },
|
|
1025
|
+
topRight: { position: "absolute", right: 12, top: 12 }
|
|
1026
|
+
});
|
|
1027
|
+
|
|
714
1028
|
// src/InlineColorPicker.tsx
|
|
715
|
-
var
|
|
1029
|
+
var import_auto_paper6 = require("@rific/auto-paper");
|
|
1030
|
+
var import_feedback_press6 = require("@rific/feedback-press");
|
|
1031
|
+
var import_core5 = require("@tastic/core");
|
|
1032
|
+
var import_react_native14 = require("react-native");
|
|
1033
|
+
var import_react_native_paper7 = require("react-native-paper");
|
|
1034
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
716
1035
|
var EMOJI_PATTERN = /\p{Extended_Pictographic}/u;
|
|
717
1036
|
var DEFAULT_SIZE = 48;
|
|
718
1037
|
var SWATCH_SIZE = 28;
|
|
@@ -725,10 +1044,10 @@ var SCREEN_MARGIN = 40;
|
|
|
725
1044
|
function widthForColumns(columns) {
|
|
726
1045
|
return SWATCHES_BORDER_WIDTH * 2 + SWATCHES_PADDING * 2 + SWATCH_SIZE * columns + SWATCHES_GAP * (columns - 1);
|
|
727
1046
|
}
|
|
728
|
-
function InlineColorPicker({ id, host, value, onChange, previewValue, swatches =
|
|
1047
|
+
function InlineColorPicker({ id, host, value, onChange, previewValue, swatches = import_auto_paper6.defaultColors, takenValue, allowSwapTaken, dark, align: alignOverride, icon = "palette", tag, labelFontFamily = MONO_FONT, autoDismiss = true, columns, size = DEFAULT_SIZE }) {
|
|
729
1048
|
const menuBg = dark ? "#000000" : "#FFFFFF";
|
|
730
|
-
const { width: windowWidth } = (0,
|
|
731
|
-
const autoColumns = (0,
|
|
1049
|
+
const { width: windowWidth } = (0, import_react_native14.useWindowDimensions)();
|
|
1050
|
+
const autoColumns = (0, import_core5.clamp)(Math.floor((windowWidth - 2 * SCREEN_MARGIN + SWATCHES_GAP) / (SWATCH_SIZE + SWATCHES_GAP)), MIN_COLUMNS, MAX_COLUMNS);
|
|
732
1051
|
const resolvedColumns = columns ?? autoColumns;
|
|
733
1052
|
const swatchesWidth = widthForColumns(resolvedColumns);
|
|
734
1053
|
const swatchRows = Math.ceil(swatches.length / resolvedColumns);
|
|
@@ -738,17 +1057,17 @@ function InlineColorPicker({ id, host, value, onChange, previewValue, swatches =
|
|
|
738
1057
|
const align = alignOverride ?? autoAlign;
|
|
739
1058
|
const displayFor = previewValue ?? ((hex) => hex);
|
|
740
1059
|
const displayValue = displayFor(value);
|
|
741
|
-
const contrastColor = (0,
|
|
1060
|
+
const contrastColor = (0, import_auto_paper6.getContrastColor)(displayValue);
|
|
742
1061
|
const tagFontSize = size * (tag && EMOJI_PATTERN.test(tag) ? 0.6 : 0.4);
|
|
743
|
-
return /* @__PURE__ */ (0,
|
|
744
|
-
/* @__PURE__ */ (0,
|
|
745
|
-
/* @__PURE__ */ (0,
|
|
1062
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_react_native14.View, { style: [styles11.anchor, open && styles11.anchorOpen], children: [
|
|
1063
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_feedback_press6.TouchableRipple, { onPress: () => host.toggle(id), borderless: true, style: [styles11.trigger, { backgroundColor: displayValue, borderRadius: size / 2, height: size, width: size }], children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native14.View, { ref: triggerRef, collapsable: false, style: styles11.triggerMeasure, children: tag ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native_paper7.Text, { style: [styles11.tagLabel, { color: contrastColor, fontFamily: labelFontFamily, fontSize: tagFontSize }], numberOfLines: 1, adjustsFontSizeToFit: true, children: tag }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native_paper7.Icon, { source: icon, size: size * 0.6, color: contrastColor }) }) }),
|
|
1064
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: displayValue, caretBorderWidth: SWATCHES_BORDER_WIDTH, triggerSize: size, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native14.ScrollView, { style: [styles11.swatches, { backgroundColor: menuBg, borderColor: displayValue, width: swatchesWidth, maxHeight }], contentContainerStyle: styles11.swatchesContent, showsVerticalScrollIndicator: false, children: swatches.map((swatch) => {
|
|
746
1065
|
const selected = swatch.value.toLowerCase() === value.toLowerCase();
|
|
747
1066
|
const taken = !selected && !!takenValue && swatch.value.toLowerCase() === takenValue.toLowerCase();
|
|
748
1067
|
const swappable = taken && allowSwapTaken;
|
|
749
1068
|
const swatchDisplay = displayFor(swatch.value);
|
|
750
|
-
return /* @__PURE__ */ (0,
|
|
751
|
-
|
|
1069
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1070
|
+
import_feedback_press6.TouchableRipple,
|
|
752
1071
|
{
|
|
753
1072
|
disabled: taken && !swappable,
|
|
754
1073
|
onPress: () => {
|
|
@@ -756,15 +1075,15 @@ function InlineColorPicker({ id, host, value, onChange, previewValue, swatches =
|
|
|
756
1075
|
if (autoDismiss) host.close();
|
|
757
1076
|
},
|
|
758
1077
|
borderless: true,
|
|
759
|
-
style: [
|
|
760
|
-
children: selected ? /* @__PURE__ */ (0,
|
|
1078
|
+
style: [styles11.swatch, { backgroundColor: swatchDisplay }, selected && styles11.swatchSelected, taken && !swappable && styles11.swatchTaken],
|
|
1079
|
+
children: selected ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native_paper7.Icon, { source: "check", size: 16, color: (0, import_auto_paper6.getContrastColor)(swatchDisplay) }) : swappable ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native_paper7.Icon, { source: "swap-horizontal", size: 16, color: (0, import_auto_paper6.getContrastColor)(swatchDisplay) }) : taken ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native_paper7.Icon, { source: "close", size: 16, color: (0, import_auto_paper6.getContrastColor)(swatchDisplay) }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native14.View, {})
|
|
761
1080
|
},
|
|
762
1081
|
swatch.value
|
|
763
1082
|
);
|
|
764
1083
|
}) }) })
|
|
765
1084
|
] });
|
|
766
1085
|
}
|
|
767
|
-
var
|
|
1086
|
+
var styles11 = import_react_native14.StyleSheet.create({
|
|
768
1087
|
anchor: {
|
|
769
1088
|
position: "relative"
|
|
770
1089
|
},
|
|
@@ -836,11 +1155,11 @@ var styles7 = import_react_native9.StyleSheet.create({
|
|
|
836
1155
|
});
|
|
837
1156
|
|
|
838
1157
|
// src/LabeledDropdown.tsx
|
|
839
|
-
var
|
|
840
|
-
var
|
|
841
|
-
var
|
|
842
|
-
var
|
|
843
|
-
var
|
|
1158
|
+
var import_auto_paper7 = require("@rific/auto-paper");
|
|
1159
|
+
var import_feedback_press7 = require("@rific/feedback-press");
|
|
1160
|
+
var import_react_native15 = require("react-native");
|
|
1161
|
+
var import_react_native_paper8 = require("react-native-paper");
|
|
1162
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
844
1163
|
var TRIGGER_HEIGHT = 28;
|
|
845
1164
|
var POPOVER_WIDTH = 180;
|
|
846
1165
|
var ROW_HEIGHT = 36;
|
|
@@ -863,22 +1182,22 @@ function LabeledDropdown({ id, host, options, value, onChange, color, dark, alig
|
|
|
863
1182
|
onChange(option.value);
|
|
864
1183
|
host.close();
|
|
865
1184
|
};
|
|
866
|
-
return /* @__PURE__ */ (0,
|
|
867
|
-
/* @__PURE__ */ (0,
|
|
868
|
-
/* @__PURE__ */ (0,
|
|
869
|
-
/* @__PURE__ */ (0,
|
|
1185
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react_native15.View, { style: [styles12.anchor, open && styles12.anchorOpen], children: [
|
|
1186
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_feedback_press7.TouchableRipple, { onPress: () => host.toggle(id), style: styles12.trigger, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react_native15.View, { ref: triggerRef, collapsable: false, style: styles12.triggerInner, children: [
|
|
1187
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_paper8.Text, { style: [styles12.triggerLabel, { color }], numberOfLines: 1, children: (selected?.label ?? "").toUpperCase() }),
|
|
1188
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_paper8.Icon, { source: "menu-down", size: 16, color })
|
|
870
1189
|
] }) }),
|
|
871
|
-
/* @__PURE__ */ (0,
|
|
1190
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: color, caretBorderWidth: 2, triggerSize: TRIGGER_HEIGHT, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native15.ScrollView, { style: [styles12.menu, { backgroundColor: menuBg, borderColor: color, width: POPOVER_WIDTH, maxHeight }], contentContainerStyle: styles12.menuContent, showsVerticalScrollIndicator: false, children: options.map((option) => {
|
|
872
1191
|
const isSelected = option.value === value;
|
|
873
|
-
const onColor = (0,
|
|
874
|
-
return /* @__PURE__ */ (0,
|
|
875
|
-
option.icon && /* @__PURE__ */ (0,
|
|
876
|
-
/* @__PURE__ */ (0,
|
|
1192
|
+
const onColor = (0, import_auto_paper7.getContrastColor)(color);
|
|
1193
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_feedback_press7.TouchableRipple, { onPress: () => handleSelect(option), style: [styles12.row, isSelected && { backgroundColor: color }], children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react_native15.View, { style: styles12.rowInner, children: [
|
|
1194
|
+
option.icon && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_paper8.Icon, { source: option.icon, size: 18, color: isSelected ? onColor : fg }),
|
|
1195
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_paper8.Text, { style: [styles12.rowLabel, { color: isSelected ? onColor : fg }], numberOfLines: 1, children: option.label })
|
|
877
1196
|
] }) }, option.value);
|
|
878
1197
|
}) }) })
|
|
879
1198
|
] });
|
|
880
1199
|
}
|
|
881
|
-
var
|
|
1200
|
+
var styles12 = import_react_native15.StyleSheet.create({
|
|
882
1201
|
anchor: {
|
|
883
1202
|
position: "relative"
|
|
884
1203
|
},
|
|
@@ -930,31 +1249,26 @@ var styles8 = import_react_native10.StyleSheet.create({
|
|
|
930
1249
|
}
|
|
931
1250
|
});
|
|
932
1251
|
|
|
933
|
-
// src/loadSkiaWeb.ts
|
|
934
|
-
function loadSkiaWeb() {
|
|
935
|
-
return Promise.resolve();
|
|
936
|
-
}
|
|
937
|
-
|
|
938
1252
|
// src/PressAwayOverlay.tsx
|
|
939
|
-
var
|
|
940
|
-
var
|
|
1253
|
+
var import_react_native16 = require("react-native");
|
|
1254
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
941
1255
|
function PressAwayOverlay({ active, onPress, style }) {
|
|
942
1256
|
if (!active) return null;
|
|
943
|
-
return /* @__PURE__ */ (0,
|
|
1257
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native16.Pressable, { accessibilityLabel: "Dismiss", accessibilityRole: "button", onPress, style: [import_react_native16.StyleSheet.absoluteFill, style] });
|
|
944
1258
|
}
|
|
945
1259
|
|
|
946
1260
|
// src/ReadyButton.tsx
|
|
947
|
-
var
|
|
948
|
-
var
|
|
949
|
-
var
|
|
950
|
-
var
|
|
1261
|
+
var import_feedback_press8 = require("@rific/feedback-press");
|
|
1262
|
+
var import_react_native17 = require("react-native");
|
|
1263
|
+
var import_react_native_paper9 = require("react-native-paper");
|
|
1264
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
951
1265
|
function ReadyButton({ color, ready, onToggleReady, style, labelFontFamily = MONO_FONT }) {
|
|
952
|
-
const readyButtonStyle = [
|
|
1266
|
+
const readyButtonStyle = [styles13.readyButton, { borderColor: color }, ready && { backgroundColor: color }, style];
|
|
953
1267
|
const labelTextStyle = { fontFamily: labelFontFamily, fontWeight: "bold" };
|
|
954
1268
|
const labelColorStyle = { color: ready ? "#000000" : color };
|
|
955
|
-
return /* @__PURE__ */ (0,
|
|
1269
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_feedback_press8.TouchableRipple, { onPress: onToggleReady, borderless: true, style: readyButtonStyle, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native_paper9.Text, { variant: "labelLarge", style: [labelTextStyle, labelColorStyle], children: ready ? "READY \u2713" : "READY?" }) });
|
|
956
1270
|
}
|
|
957
|
-
var
|
|
1271
|
+
var styles13 = import_react_native17.StyleSheet.create({
|
|
958
1272
|
readyButton: {
|
|
959
1273
|
alignItems: "center",
|
|
960
1274
|
borderRadius: 12,
|
|
@@ -966,228 +1280,22 @@ var styles9 = import_react_native12.StyleSheet.create({
|
|
|
966
1280
|
}
|
|
967
1281
|
});
|
|
968
1282
|
|
|
969
|
-
// src/SectionedDropdown.tsx
|
|
970
|
-
var import_auto_paper6 = require("@rific/auto-paper");
|
|
971
|
-
var import_feedback_press7 = require("@rific/feedback-press");
|
|
972
|
-
var import_react_native14 = require("react-native");
|
|
973
|
-
var import_react_native_paper7 = require("react-native-paper");
|
|
974
|
-
|
|
975
|
-
// src/TriggerGaugeHost.tsx
|
|
976
|
-
var import_react5 = require("react");
|
|
977
|
-
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
978
|
-
var LazyTriggerGauge = (0, import_react5.lazy)(() => loadSkiaWeb().then(() => Promise.resolve().then(() => (init_TriggerGauge(), TriggerGauge_exports)).then((m) => ({ default: m.TriggerGauge }))));
|
|
979
|
-
function TriggerGaugeHost(props) {
|
|
980
|
-
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react5.Suspense, { fallback: null, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(LazyTriggerGauge, { ...props }) });
|
|
981
|
-
}
|
|
982
|
-
|
|
983
|
-
// src/SectionedDropdown.tsx
|
|
984
|
-
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
985
|
-
var MENU_BORDER_WIDTH = 1;
|
|
986
|
-
var TRIGGER_SIZE = 44;
|
|
987
|
-
var MENU_MIN_WIDTH = 200;
|
|
988
|
-
var MENU_MAX_WIDTH = 220;
|
|
989
|
-
var MENU_ITEM_ICON_SIZE = 18;
|
|
990
|
-
var MENU_ITEM_LABEL_MAX_WIDTH = 150;
|
|
991
|
-
var MENU_ITEM_HEIGHT = 40;
|
|
992
|
-
var MENU_ITEM_HEIGHT_WITH_DESCRIPTION = 58;
|
|
993
|
-
var MENU_DIVIDER_HEIGHT = 9;
|
|
994
|
-
var MENU_VERTICAL_PADDING = 12;
|
|
995
|
-
function SectionedDropdown({ id, host, icon, accessibilityLabel, sections, accentColor, mutedColor, onAccentColor, dark, align: alignOverride, autoDismiss = true, labelFontFamily = MONO_FONT, allClearLabels = { all: "All", clear: "Clear" } }) {
|
|
996
|
-
const menuBg = dark ? "#000000" : "#FFFFFF";
|
|
997
|
-
const menuBorderColor = (0, import_auto_paper6.getBlendedColor)(mutedColor, menuBg, 0.5);
|
|
998
|
-
const resolvedOnAccentColor = onAccentColor ?? (0, import_auto_paper6.getColorRoles)(accentColor, menuBg).onColor;
|
|
999
|
-
const fg = dark ? "#FFFFFF" : "#000000";
|
|
1000
|
-
const open = host.openId === id;
|
|
1001
|
-
const estimatedHeight = MENU_VERTICAL_PADDING + sections.reduce((sum, section, sectionIndex) => {
|
|
1002
|
-
const rows = section.options.reduce((rowSum, option) => rowSum + (option.description ? MENU_ITEM_HEIGHT_WITH_DESCRIPTION : MENU_ITEM_HEIGHT), 0);
|
|
1003
|
-
const footer = section.kind === "multi" && section.allClear ? MENU_ITEM_HEIGHT : 0;
|
|
1004
|
-
const divider = sectionIndex > 0 ? MENU_DIVIDER_HEIGHT : 0;
|
|
1005
|
-
return sum + rows + footer + divider;
|
|
1006
|
-
}, 0);
|
|
1007
|
-
const { align: autoAlign, maxHeight, measured, triggerRef, verticalAlign } = useAutoAlign(open, MENU_MAX_WIDTH, estimatedHeight);
|
|
1008
|
-
const align = alignOverride ?? autoAlign;
|
|
1009
|
-
const onlySection = sections.length === 1 ? sections[0] : null;
|
|
1010
|
-
const selectedOption = onlySection?.kind === "single" ? onlySection.options.find((o) => o.value === onlySection.value) : void 0;
|
|
1011
|
-
const triggerIcon = selectedOption?.icon ?? icon;
|
|
1012
|
-
const triggerIconSize = selectedOption?.iconSize ?? 22;
|
|
1013
|
-
const hasMultiSection = sections.some((s) => s.kind === "multi");
|
|
1014
|
-
const anyMultiSelected = sections.some((s) => s.kind === "multi" && s.value.length > 0);
|
|
1015
|
-
const triggerIconColor = hasMultiSection ? anyMultiSelected ? accentColor : fg : fg;
|
|
1016
|
-
const gaugeSegments = sections.reduce((sum, section) => sum + section.options.length, 0);
|
|
1017
|
-
const gaugeLitIndices = [];
|
|
1018
|
-
let gaugeOffset = 0;
|
|
1019
|
-
for (const section of sections) {
|
|
1020
|
-
if (section.kind === "single") {
|
|
1021
|
-
const index = section.options.findIndex((o) => o.value === section.value);
|
|
1022
|
-
if (index >= 0) gaugeLitIndices.push(gaugeOffset + index);
|
|
1023
|
-
} else {
|
|
1024
|
-
section.options.forEach((o, i) => {
|
|
1025
|
-
if (section.value.includes(o.value)) gaugeLitIndices.push(gaugeOffset + i);
|
|
1026
|
-
});
|
|
1027
|
-
}
|
|
1028
|
-
gaugeOffset += section.options.length;
|
|
1029
|
-
}
|
|
1030
|
-
const anchorStyle = [styles11.anchor, open && styles11.anchorOpen];
|
|
1031
|
-
const menuStyle = { backgroundColor: menuBg, borderColor: menuBorderColor, maxHeight };
|
|
1032
|
-
const dividerStyle = { backgroundColor: menuBorderColor };
|
|
1033
|
-
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_react_native14.View, { style: anchorStyle, children: [
|
|
1034
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_react_native14.View, { ref: triggerRef, collapsable: false, style: styles11.triggerBox, children: [
|
|
1035
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(TriggerGaugeHost, { segments: gaugeSegments, litIndices: gaugeLitIndices, size: TRIGGER_SIZE, accentColor, mutedColor }),
|
|
1036
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_feedback_press7.IconButton, { icon: triggerIcon, iconColor: triggerIconColor, size: triggerIconSize, accessibilityLabel, onPress: () => host.toggle(id) })
|
|
1037
|
-
] }),
|
|
1038
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: menuBorderColor, caretBorderWidth: MENU_BORDER_WIDTH, triggerSize: TRIGGER_SIZE, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native14.ScrollView, { style: [styles11.menu, menuStyle], contentContainerStyle: styles11.menuContent, showsVerticalScrollIndicator: false, children: sections.map((section, sectionIndex) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_react_native14.View, { children: [
|
|
1039
|
-
sectionIndex > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native14.View, { style: [styles11.divider, dividerStyle] }),
|
|
1040
|
-
section.kind === "single" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1041
|
-
SingleSection,
|
|
1042
|
-
{
|
|
1043
|
-
section,
|
|
1044
|
-
accentColor,
|
|
1045
|
-
onAccentColor: resolvedOnAccentColor,
|
|
1046
|
-
mutedColor,
|
|
1047
|
-
labelFontFamily,
|
|
1048
|
-
onSelect: (value) => {
|
|
1049
|
-
section.onChange(value);
|
|
1050
|
-
if (autoDismiss) host.close();
|
|
1051
|
-
}
|
|
1052
|
-
}
|
|
1053
|
-
) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(MultiSection, { section, accentColor, onAccentColor: resolvedOnAccentColor, mutedColor, labelFontFamily, allClearLabels })
|
|
1054
|
-
] }, section.id)) }) })
|
|
1055
|
-
] });
|
|
1056
|
-
}
|
|
1057
|
-
function SingleSection({
|
|
1058
|
-
section,
|
|
1059
|
-
accentColor,
|
|
1060
|
-
onAccentColor,
|
|
1061
|
-
mutedColor,
|
|
1062
|
-
labelFontFamily,
|
|
1063
|
-
onSelect
|
|
1064
|
-
}) {
|
|
1065
|
-
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_jsx_runtime13.Fragment, { children: section.options.map((option) => {
|
|
1066
|
-
const selected = option.value === section.value;
|
|
1067
|
-
const taken = !selected && option.value === section.takenValue;
|
|
1068
|
-
const rowColor = selected ? onAccentColor : mutedColor;
|
|
1069
|
-
const itemStyle = [styles11.item, selected && { backgroundColor: accentColor }, taken && styles11.itemTaken];
|
|
1070
|
-
const labelStyle = { fontFamily: labelFontFamily, color: rowColor, fontWeight: selected ? "bold" : "normal" };
|
|
1071
|
-
const descriptionStyle = { fontFamily: labelFontFamily, color: rowColor };
|
|
1072
|
-
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_feedback_press7.TouchableRipple, { disabled: taken, onPress: () => onSelect(option.value), style: itemStyle, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_react_native14.View, { style: styles11.itemRow, children: [
|
|
1073
|
-
option.icon && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native_paper7.Icon, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
|
|
1074
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_react_native14.View, { style: styles11.itemLabelColumn, children: [
|
|
1075
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native_paper7.Text, { variant: "labelLarge", style: labelStyle, children: option.label }),
|
|
1076
|
-
option.description && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native_paper7.Text, { variant: "labelSmall", style: descriptionStyle, children: option.description })
|
|
1077
|
-
] })
|
|
1078
|
-
] }) }, option.value);
|
|
1079
|
-
}) });
|
|
1080
|
-
}
|
|
1081
|
-
function MultiSection({
|
|
1082
|
-
section,
|
|
1083
|
-
accentColor,
|
|
1084
|
-
onAccentColor,
|
|
1085
|
-
mutedColor,
|
|
1086
|
-
labelFontFamily,
|
|
1087
|
-
allClearLabels
|
|
1088
|
-
}) {
|
|
1089
|
-
const allSelected = section.value.length === section.options.length;
|
|
1090
|
-
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
1091
|
-
section.options.map((option, i) => {
|
|
1092
|
-
const selected = section.value.includes(option.value);
|
|
1093
|
-
const rowColor = selected ? onAccentColor : mutedColor;
|
|
1094
|
-
const prevSelected = selected && i > 0 && section.value.includes(section.options[i - 1].value);
|
|
1095
|
-
const nextSelected = selected && i < section.options.length - 1 && section.value.includes(section.options[i + 1].value);
|
|
1096
|
-
const itemStyle = [styles11.item, selected && { backgroundColor: accentColor }, prevSelected && { borderTopLeftRadius: 0, borderTopRightRadius: 0 }, nextSelected && { borderBottomLeftRadius: 0, borderBottomRightRadius: 0 }];
|
|
1097
|
-
const labelStyle = { fontFamily: labelFontFamily, color: rowColor, fontWeight: selected ? "bold" : "normal" };
|
|
1098
|
-
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_feedback_press7.TouchableRipple, { onPress: () => section.onChange(selected ? section.value.filter((v) => v !== option.value) : [...section.value, option.value]), style: itemStyle, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_react_native14.View, { style: styles11.itemRow, children: [
|
|
1099
|
-
option.icon && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native_paper7.Icon, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
|
|
1100
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native_paper7.Text, { variant: "labelLarge", style: [styles11.itemLabelFlex, labelStyle], children: option.label })
|
|
1101
|
-
] }) }, option.value);
|
|
1102
|
-
}),
|
|
1103
|
-
section.allClear && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_feedback_press7.TouchableRipple, { onPress: () => section.onChange(allSelected ? [] : section.options.map((o) => o.value)), style: styles11.item, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native_paper7.Text, { variant: "labelLarge", style: [styles11.allClearLabel, { fontFamily: labelFontFamily, color: accentColor }], children: allSelected ? allClearLabels.clear : allClearLabels.all }) })
|
|
1104
|
-
] });
|
|
1105
|
-
}
|
|
1106
|
-
var styles11 = import_react_native14.StyleSheet.create({
|
|
1107
|
-
allClearLabel: {
|
|
1108
|
-
fontWeight: "bold",
|
|
1109
|
-
textAlign: "center"
|
|
1110
|
-
},
|
|
1111
|
-
anchor: {
|
|
1112
|
-
position: "relative"
|
|
1113
|
-
},
|
|
1114
|
-
// React Native Web gives every position:'relative' view an explicit zIndex (0, not 'auto'),
|
|
1115
|
-
// which makes each one its own stacking context — so a zIndex set only on the popover content
|
|
1116
|
-
// below only wins comparisons within this anchor's own box, not against this anchor's own later
|
|
1117
|
-
// siblings (e.g. a Ready button), which are otherwise painted on top by DOM-order tiebreak.
|
|
1118
|
-
// Elevating the anchor itself, only while its popover is open, fixes that at the right level.
|
|
1119
|
-
anchorOpen: {
|
|
1120
|
-
zIndex: 100
|
|
1121
|
-
},
|
|
1122
|
-
divider: {
|
|
1123
|
-
height: import_react_native14.StyleSheet.hairlineWidth,
|
|
1124
|
-
marginVertical: 4
|
|
1125
|
-
},
|
|
1126
|
-
item: {
|
|
1127
|
-
borderRadius: 8,
|
|
1128
|
-
paddingHorizontal: 12,
|
|
1129
|
-
paddingVertical: 8
|
|
1130
|
-
},
|
|
1131
|
-
itemLabelColumn: {
|
|
1132
|
-
maxWidth: MENU_ITEM_LABEL_MAX_WIDTH
|
|
1133
|
-
},
|
|
1134
|
-
itemLabelFlex: {
|
|
1135
|
-
flex: 1
|
|
1136
|
-
},
|
|
1137
|
-
itemRow: {
|
|
1138
|
-
alignItems: "center",
|
|
1139
|
-
flexDirection: "row",
|
|
1140
|
-
gap: 8
|
|
1141
|
-
},
|
|
1142
|
-
// Same opacity as ProfilePicker's rowDisabled / InlineColorPicker's swatchTaken — the fleet's
|
|
1143
|
-
// established "shown, not removed" treatment for another seat's own current pick.
|
|
1144
|
-
itemTaken: {
|
|
1145
|
-
opacity: 0.35
|
|
1146
|
-
},
|
|
1147
|
-
menu: {
|
|
1148
|
-
borderRadius: 12,
|
|
1149
|
-
borderWidth: MENU_BORDER_WIDTH,
|
|
1150
|
-
elevation: 8,
|
|
1151
|
-
maxWidth: MENU_MAX_WIDTH,
|
|
1152
|
-
minWidth: MENU_MIN_WIDTH,
|
|
1153
|
-
shadowColor: "#000000",
|
|
1154
|
-
shadowOffset: { height: 2, width: 0 },
|
|
1155
|
-
shadowOpacity: 0.3,
|
|
1156
|
-
shadowRadius: 8
|
|
1157
|
-
},
|
|
1158
|
-
// Separate from `menu` itself — a ScrollView's own style sets the scrolling frame's bounds
|
|
1159
|
-
// (including the maxHeight that actually caps it), while padding/gap belong to its
|
|
1160
|
-
// contentContainerStyle, which sizes to the *unclamped* content instead of the frame.
|
|
1161
|
-
menuContent: {
|
|
1162
|
-
gap: 4,
|
|
1163
|
-
padding: 6
|
|
1164
|
-
},
|
|
1165
|
-
// Fixed hit-area regardless of the current option's iconSize, so a small-vs-large trigger icon
|
|
1166
|
-
// doesn't shift this picker's position within its row.
|
|
1167
|
-
triggerBox: {
|
|
1168
|
-
alignItems: "center",
|
|
1169
|
-
height: TRIGGER_SIZE,
|
|
1170
|
-
justifyContent: "center",
|
|
1171
|
-
width: TRIGGER_SIZE
|
|
1172
|
-
}
|
|
1173
|
-
});
|
|
1174
|
-
|
|
1175
1283
|
// src/SharedActionBand.tsx
|
|
1176
|
-
var
|
|
1177
|
-
var
|
|
1178
|
-
var
|
|
1284
|
+
var import_feedback_press9 = require("@rific/feedback-press");
|
|
1285
|
+
var import_react_native18 = require("react-native");
|
|
1286
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
1179
1287
|
function SharedActionBand({ onBack, onSettings, onRandomize, onReset, fg, popoverOpen, children }) {
|
|
1180
|
-
return /* @__PURE__ */ (0,
|
|
1181
|
-
/* @__PURE__ */ (0,
|
|
1182
|
-
/* @__PURE__ */ (0,
|
|
1183
|
-
onRandomize && /* @__PURE__ */ (0,
|
|
1184
|
-
onReset && /* @__PURE__ */ (0,
|
|
1185
|
-
/* @__PURE__ */ (0,
|
|
1288
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_react_native18.View, { style: [styles14.column, popoverOpen && styles14.columnOpen], children: [
|
|
1289
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_react_native18.View, { style: styles14.actionsRow, children: [
|
|
1290
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_feedback_press9.IconButton, { icon: "arrow-left", iconColor: fg, size: 20, onPress: onBack, accessibilityLabel: "Back" }),
|
|
1291
|
+
onRandomize && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_feedback_press9.IconButton, { icon: "dice-multiple", iconColor: fg, size: 18, onPress: onRandomize, accessibilityLabel: "Randomize match settings" }),
|
|
1292
|
+
onReset && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_feedback_press9.IconButton, { icon: "restore", iconColor: fg, size: 18, onPress: onReset, accessibilityLabel: "Reset match settings to defaults" }),
|
|
1293
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_feedback_press9.IconButton, { icon: "cog", iconColor: fg, size: 20, onPress: onSettings, accessibilityLabel: "Settings" })
|
|
1186
1294
|
] }),
|
|
1187
1295
|
children
|
|
1188
1296
|
] });
|
|
1189
1297
|
}
|
|
1190
|
-
var
|
|
1298
|
+
var styles14 = import_react_native18.StyleSheet.create({
|
|
1191
1299
|
actionsRow: {
|
|
1192
1300
|
alignItems: "center",
|
|
1193
1301
|
flexDirection: "row",
|
|
@@ -1203,20 +1311,20 @@ var styles12 = import_react_native15.StyleSheet.create({
|
|
|
1203
1311
|
});
|
|
1204
1312
|
|
|
1205
1313
|
// src/StatRow.tsx
|
|
1206
|
-
var
|
|
1207
|
-
var
|
|
1208
|
-
var
|
|
1209
|
-
var
|
|
1314
|
+
var import_auto_paper8 = require("@rific/auto-paper");
|
|
1315
|
+
var import_react_native19 = require("react-native");
|
|
1316
|
+
var import_react_native_paper10 = require("react-native-paper");
|
|
1317
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
1210
1318
|
function StatRow({ label, value, fg: fgOverride, fgMuted: fgMutedOverride }) {
|
|
1211
|
-
const { dark } = (0,
|
|
1319
|
+
const { dark } = (0, import_auto_paper8.useAutoPaperTheme)();
|
|
1212
1320
|
const fg = fgOverride ?? (dark ? "#FFFFFF" : "#000000");
|
|
1213
1321
|
const fgMuted = fgMutedOverride ?? (dark ? "rgba(255,255,255,0.5)" : "rgba(0,0,0,0.5)");
|
|
1214
|
-
return /* @__PURE__ */ (0,
|
|
1215
|
-
/* @__PURE__ */ (0,
|
|
1216
|
-
/* @__PURE__ */ (0,
|
|
1322
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native19.View, { style: styles15.row, children: [
|
|
1323
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native_paper10.Text, { variant: "bodyMedium", style: { color: fgMuted }, children: label }),
|
|
1324
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native_paper10.Text, { variant: "bodyMedium", style: [styles15.value, { color: fg }], children: value })
|
|
1217
1325
|
] });
|
|
1218
1326
|
}
|
|
1219
|
-
var
|
|
1327
|
+
var styles15 = import_react_native19.StyleSheet.create({
|
|
1220
1328
|
row: {
|
|
1221
1329
|
alignItems: "center",
|
|
1222
1330
|
flexDirection: "row",
|
|
@@ -1228,20 +1336,20 @@ var styles13 = import_react_native16.StyleSheet.create({
|
|
|
1228
1336
|
});
|
|
1229
1337
|
|
|
1230
1338
|
// src/StatSection.tsx
|
|
1231
|
-
var
|
|
1232
|
-
var
|
|
1233
|
-
var
|
|
1234
|
-
var
|
|
1339
|
+
var import_auto_paper9 = require("@rific/auto-paper");
|
|
1340
|
+
var import_react_native20 = require("react-native");
|
|
1341
|
+
var import_react_native_paper11 = require("react-native-paper");
|
|
1342
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
1235
1343
|
function StatSection({ label, fg: fgOverride, sectionBg: sectionBgOverride, children }) {
|
|
1236
|
-
const { dark } = (0,
|
|
1344
|
+
const { dark } = (0, import_auto_paper9.useAutoPaperTheme)();
|
|
1237
1345
|
const fg = fgOverride ?? (dark ? "#FFFFFF" : "#000000");
|
|
1238
1346
|
const sectionBg = sectionBgOverride ?? (dark ? "rgba(255,255,255,0.06)" : "rgba(0,0,0,0.04)");
|
|
1239
|
-
return /* @__PURE__ */ (0,
|
|
1240
|
-
/* @__PURE__ */ (0,
|
|
1347
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_react_native20.View, { style: [styles16.section, { backgroundColor: sectionBg }], children: [
|
|
1348
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_native_paper11.Text, { variant: "labelMedium", style: [styles16.label, { color: fg }], children: label }),
|
|
1241
1349
|
children
|
|
1242
1350
|
] });
|
|
1243
1351
|
}
|
|
1244
|
-
var
|
|
1352
|
+
var styles16 = import_react_native20.StyleSheet.create({
|
|
1245
1353
|
// Bold and full-contrast (fg), not the original fontless/fgMuted treatment — that read at the
|
|
1246
1354
|
// same visual weight as StatRow's own row labels below it (both used the identical muted color;
|
|
1247
1355
|
// letterSpacing/variant alone didn't separate them enough to read as "this is the group header"
|
|
@@ -1272,8 +1380,11 @@ function usePopoverHost() {
|
|
|
1272
1380
|
AchievementRow,
|
|
1273
1381
|
BaseSettingsDialog,
|
|
1274
1382
|
BaseStatsScreen,
|
|
1383
|
+
ConfirmDialog,
|
|
1275
1384
|
ContentGutter,
|
|
1385
|
+
ControlSchemePicker,
|
|
1276
1386
|
CornerActionButtons,
|
|
1387
|
+
CornerStatusBadges,
|
|
1277
1388
|
InlineColorPicker,
|
|
1278
1389
|
LABELED_DROPDOWN_POPOVER_WIDTH,
|
|
1279
1390
|
LOCKED_BADGE_COLOR,
|