@tastic/hud 0.21.0 → 0.23.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.mjs CHANGED
@@ -10,16 +10,24 @@ import {
10
10
  ConfirmDialog,
11
11
  ContentGutter,
12
12
  CornerActionButtons,
13
+ InlineColorPicker,
13
14
  LOCKED_BADGE_COLOR,
14
15
  MONO_FONT,
16
+ PopoverBody,
17
+ PressAwayOverlay,
15
18
  RotatedFrame,
16
19
  StaggeredWord,
17
20
  StatRow,
18
21
  StatSection,
19
22
  UpdateDialog,
23
+ WELL_SHADOW,
24
+ getInlineColorPickerContentSize,
20
25
  getStaggeredWordDuration,
21
- useCompactDialog
22
- } from "./chunk-UOA35OWJ.mjs";
26
+ useAutoAlign,
27
+ useCompactDialog,
28
+ usePopoverHost,
29
+ useWellColors
30
+ } from "./chunk-BXG44LIA.mjs";
23
31
  import {
24
32
  COMPACT_DIALOG_HEIGHT,
25
33
  DialogHeader,
@@ -83,132 +91,18 @@ import { Platform } from "react-native";
83
91
  import { getBlendedColor, getColorRoles } from "@rific/auto-paper";
84
92
  import { IconButton, TouchableRipple } from "@rific/feedback-press";
85
93
  import { useRotation } from "@tastic/core";
86
- import { ScrollView, StyleSheet as StyleSheet3, View as View4 } from "react-native";
94
+ import { ScrollView, StyleSheet as StyleSheet2, View as View2 } from "react-native";
87
95
  import { Icon as Icon2, Text as Text2 } from "react-native-paper";
88
96
 
89
- // src/PopoverBody.tsx
90
- import { StyleSheet as StyleSheet2, View as View2 } from "react-native";
91
- import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
92
- var CARET_SIZE = 7;
93
- var CARET_RING_OFFSET = 2;
94
- var CARET_DIP = 1;
95
- function PopoverBody({ visible, children, align = "center", verticalAlign = "below", caretColor, caretBorderColor, caretBorderWidth = 1, triggerSize = 0 }) {
96
- if (!visible) return null;
97
- const above = verticalAlign === "above";
98
- const alignStyle = align === "left" ? styles2.contentLeft : align === "right" ? styles2.contentRight : styles2.contentCenter;
99
- const verticalStyle = above ? styles2.contentAbove : styles2.contentBelow;
100
- const ringSize = CARET_SIZE + caretBorderWidth;
101
- const caretOffset = (halfFootprint) => align === "right" ? { right: triggerSize / 2 - halfFootprint } : { left: triggerSize / 2 - halfFootprint };
102
- const caretFill = above ? "borderTopColor" : "borderBottomColor";
103
- const caretWidthProp = above ? "borderTopWidth" : "borderBottomWidth";
104
- const caretEdge = (size) => above ? { bottom: -size + CARET_DIP } : { top: -size + CARET_DIP };
105
- return /* @__PURE__ */ jsxs2(View2, { style: [styles2.content, alignStyle, verticalStyle], children: [
106
- children,
107
- caretColor && /* @__PURE__ */ jsxs2(Fragment, { children: [
108
- /* @__PURE__ */ jsx2(View2, { style: [styles2.caret, caretOffset(ringSize), caretEdge(ringSize), { [caretFill]: caretBorderColor ?? caretColor, [caretWidthProp]: ringSize, borderLeftWidth: ringSize, borderRightWidth: ringSize }] }),
109
- /* @__PURE__ */ jsx2(View2, { style: [styles2.caret, caretOffset(CARET_SIZE), caretEdge(CARET_SIZE - CARET_RING_OFFSET), { [caretFill]: caretColor, [caretWidthProp]: CARET_SIZE, borderLeftWidth: CARET_SIZE, borderRightWidth: CARET_SIZE }] })
110
- ] })
111
- ] });
112
- }
113
- var styles2 = StyleSheet2.create({
114
- caret: {
115
- borderLeftColor: "transparent",
116
- borderRightColor: "transparent",
117
- height: 0,
118
- position: "absolute",
119
- width: 0,
120
- // Explicit, not left to DOM order - the box it dips into is itself a position:'relative' view,
121
- // which React Native Web always gives an implicit zIndex:0 (see PopoverBody's stacking-context
122
- // notes elsewhere in this codebase), so painting on top needs a real zIndex to beat that
123
- // reliably rather than relying on being the later sibling.
124
- zIndex: 1
125
- },
126
- content: {
127
- position: "absolute",
128
- zIndex: 50
129
- },
130
- contentAbove: {
131
- bottom: "100%",
132
- marginBottom: 8
133
- },
134
- contentBelow: {
135
- marginTop: 8,
136
- top: "100%"
137
- },
138
- // Stretched to the anchor's own (trigger) width, with alignItems centering the actual (usually
139
- // much wider) popover box inside via plain flexbox - not `left:'50%'` plus a percentage
140
- // `transform`, which depends on native resolving the box's own auto width before applying the
141
- // transform and has proven unreliable there, visibly shifting the box off-center.
142
- contentCenter: {
143
- alignItems: "center",
144
- left: 0,
145
- right: 0
146
- },
147
- contentLeft: {
148
- left: 0
149
- },
150
- contentRight: {
151
- right: 0
152
- }
153
- });
154
-
155
97
  // src/TriggerGaugeHost.tsx
156
- import { jsx as jsx3 } from "react/jsx-runtime";
98
+ import { jsx as jsx2 } from "react/jsx-runtime";
157
99
  var getTriggerGauge = () => import("./TriggerGauge-GIHKGAZE.mjs").then((mod) => ({ default: mod.TriggerGauge }));
158
100
  function TriggerGaugeHost(props) {
159
- return /* @__PURE__ */ jsx3(SkiaGate, { getComponent: getTriggerGauge, componentProps: props });
160
- }
161
-
162
- // src/useAutoAlign.ts
163
- import { useCallback, useEffect, useRef, useState } from "react";
164
- import { useWindowDimensions } from "react-native";
165
- var EDGE_MARGIN = 12;
166
- function rotateRect(x, y, width, height, rotation, windowWidth, windowHeight) {
167
- if (rotation === 0) return { x, y, width, height };
168
- const cx = windowWidth / 2;
169
- const cy = windowHeight / 2;
170
- const dx = x + width / 2 - cx;
171
- const dy = y + height / 2 - cy;
172
- const [newDx, newDy, newWidth, newHeight] = rotation === 180 ? [-dx, -dy, width, height] : rotation === 90 ? [-dy, dx, height, width] : [dy, -dx, height, width];
173
- return { x: cx + newDx - newWidth / 2, y: cy + newDy - newHeight / 2, width: newWidth, height: newHeight };
174
- }
175
- function useAutoAlign(open, contentWidth, contentHeight, rotation = 0) {
176
- const triggerRef = useRef(null);
177
- const { width: windowWidth, height: windowHeight } = useWindowDimensions();
178
- const [align, setAlign] = useState("center");
179
- const [verticalAlign, setVerticalAlign] = useState("below");
180
- const [maxHeight, setMaxHeight] = useState(contentHeight);
181
- const [measured, setMeasured] = useState(false);
182
- const [prevOpen, setPrevOpen] = useState(open);
183
- if (open !== prevOpen) {
184
- setPrevOpen(open);
185
- if (open) setMeasured(false);
186
- }
187
- const measure = useCallback(() => {
188
- triggerRef.current?.measureInWindow((rawX, rawY, rawWidth, rawHeight) => {
189
- const { x, y, width: triggerWidth, height: triggerHeight } = rotateRect(rawX, rawY, rawWidth, rawHeight, rotation, windowWidth, windowHeight);
190
- const centerX = x + triggerWidth / 2;
191
- const overflowsRight = centerX + contentWidth / 2 > windowWidth - EDGE_MARGIN;
192
- const overflowsLeft = centerX - contentWidth / 2 < EDGE_MARGIN;
193
- if (overflowsRight && !overflowsLeft) setAlign("right");
194
- else if (overflowsLeft && !overflowsRight) setAlign("left");
195
- else setAlign("center");
196
- const roomBelow = windowHeight - (y + triggerHeight) - EDGE_MARGIN;
197
- const roomAbove = y - EDGE_MARGIN;
198
- const above = contentHeight > roomBelow && roomAbove > roomBelow;
199
- setVerticalAlign(above ? "above" : "below");
200
- setMaxHeight(Math.max(above ? roomAbove : roomBelow, 0));
201
- setMeasured(true);
202
- });
203
- }, [contentWidth, contentHeight, windowWidth, windowHeight, rotation]);
204
- useEffect(() => {
205
- if (open) measure();
206
- }, [open, measure]);
207
- return { align, maxHeight, measured, triggerRef, verticalAlign };
101
+ return /* @__PURE__ */ jsx2(SkiaGate, { getComponent: getTriggerGauge, componentProps: props });
208
102
  }
209
103
 
210
104
  // src/SectionedDropdown.tsx
211
- import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
105
+ import { Fragment, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
212
106
  var MENU_BORDER_WIDTH = 1;
213
107
  var TRIGGER_SIZE = 44;
214
108
  var MENU_MIN_WIDTH = 200;
@@ -258,17 +152,17 @@ function SectionedDropdown({ id, host, icon, accessibilityLabel, sections, accen
258
152
  }
259
153
  gaugeOffset += section.options.length;
260
154
  }
261
- const anchorStyle = [styles3.anchor, open && styles3.anchorOpen];
155
+ const anchorStyle = [styles2.anchor, open && styles2.anchorOpen];
262
156
  const menuStyle = { backgroundColor: menuBg, borderColor: menuBorderColor, maxHeight };
263
157
  const dividerStyle = { backgroundColor: menuBorderColor };
264
- return /* @__PURE__ */ jsxs3(View4, { style: anchorStyle, children: [
265
- /* @__PURE__ */ jsxs3(View4, { ref: triggerRef, collapsable: false, style: styles3.triggerBox, children: [
266
- /* @__PURE__ */ jsx4(TriggerGaugeHost, { segments: gaugeSegments, litIndices: gaugeLitIndices, size: TRIGGER_SIZE, accentColor, mutedColor }),
267
- /* @__PURE__ */ jsx4(IconButton, { icon: triggerIcon, iconColor: triggerIconColor, size: triggerIconSize, accessibilityLabel, onPress: () => host.toggle(id) })
158
+ return /* @__PURE__ */ jsxs2(View2, { style: anchorStyle, children: [
159
+ /* @__PURE__ */ jsxs2(View2, { ref: triggerRef, collapsable: false, style: styles2.triggerBox, children: [
160
+ /* @__PURE__ */ jsx3(TriggerGaugeHost, { segments: gaugeSegments, litIndices: gaugeLitIndices, size: TRIGGER_SIZE, accentColor, mutedColor }),
161
+ /* @__PURE__ */ jsx3(IconButton, { icon: triggerIcon, iconColor: triggerIconColor, size: triggerIconSize, accessibilityLabel, onPress: () => host.toggle(id) })
268
162
  ] }),
269
- /* @__PURE__ */ jsx4(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: menuBorderColor, caretBorderWidth: MENU_BORDER_WIDTH, triggerSize: TRIGGER_SIZE, children: /* @__PURE__ */ jsx4(ScrollView, { style: [styles3.menu, menuStyle], contentContainerStyle: styles3.menuContent, showsVerticalScrollIndicator: false, children: sections.map((section, sectionIndex) => /* @__PURE__ */ jsxs3(View4, { children: [
270
- sectionIndex > 0 && /* @__PURE__ */ jsx4(View4, { style: [styles3.divider, dividerStyle] }),
271
- section.kind === "single" ? /* @__PURE__ */ jsx4(
163
+ /* @__PURE__ */ jsx3(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: menuBorderColor, caretBorderWidth: MENU_BORDER_WIDTH, triggerSize: TRIGGER_SIZE, children: /* @__PURE__ */ jsx3(ScrollView, { style: [styles2.menu, menuStyle], contentContainerStyle: styles2.menuContent, showsVerticalScrollIndicator: false, children: sections.map((section, sectionIndex) => /* @__PURE__ */ jsxs2(View2, { children: [
164
+ sectionIndex > 0 && /* @__PURE__ */ jsx3(View2, { style: [styles2.divider, dividerStyle] }),
165
+ section.kind === "single" ? /* @__PURE__ */ jsx3(
272
166
  SingleSection,
273
167
  {
274
168
  section,
@@ -281,7 +175,7 @@ function SectionedDropdown({ id, host, icon, accessibilityLabel, sections, accen
281
175
  if (autoDismiss) host.close();
282
176
  }
283
177
  }
284
- ) : /* @__PURE__ */ jsx4(MultiSection, { section, accentColor, onAccentColor: resolvedOnAccentColor, mutedColor, labelFontFamily, allClearLabels })
178
+ ) : /* @__PURE__ */ jsx3(MultiSection, { section, accentColor, onAccentColor: resolvedOnAccentColor, mutedColor, labelFontFamily, allClearLabels })
285
179
  ] }, section.id)) }) })
286
180
  ] });
287
181
  }
@@ -293,18 +187,18 @@ function SingleSection({
293
187
  labelFontFamily,
294
188
  onSelect
295
189
  }) {
296
- return /* @__PURE__ */ jsx4(Fragment2, { children: section.options.map((option) => {
190
+ return /* @__PURE__ */ jsx3(Fragment, { children: section.options.map((option) => {
297
191
  const selected = option.value === section.value;
298
192
  const taken = !selected && option.value === section.takenValue;
299
193
  const rowColor = selected ? onAccentColor : mutedColor;
300
- const itemStyle = [styles3.item, selected && { backgroundColor: accentColor }, taken && styles3.itemTaken];
194
+ const itemStyle = [styles2.item, selected && { backgroundColor: accentColor }, taken && styles2.itemTaken];
301
195
  const labelStyle = { fontFamily: labelFontFamily, color: rowColor, fontWeight: selected ? "bold" : "normal" };
302
196
  const descriptionStyle = { fontFamily: labelFontFamily, color: rowColor };
303
- return /* @__PURE__ */ jsx4(TouchableRipple, { disabled: taken, onPress: () => onSelect(option.value), style: itemStyle, children: /* @__PURE__ */ jsxs3(View4, { style: styles3.itemRow, children: [
304
- option.icon && /* @__PURE__ */ jsx4(Icon2, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
305
- /* @__PURE__ */ jsxs3(View4, { style: styles3.itemLabelColumn, children: [
306
- /* @__PURE__ */ jsx4(Text2, { variant: "labelLarge", style: labelStyle, children: option.label }),
307
- option.description && /* @__PURE__ */ jsx4(Text2, { variant: "labelSmall", style: descriptionStyle, children: option.description })
197
+ return /* @__PURE__ */ jsx3(TouchableRipple, { disabled: taken, onPress: () => onSelect(option.value), style: itemStyle, children: /* @__PURE__ */ jsxs2(View2, { style: styles2.itemRow, children: [
198
+ option.icon && /* @__PURE__ */ jsx3(Icon2, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
199
+ /* @__PURE__ */ jsxs2(View2, { style: styles2.itemLabelColumn, children: [
200
+ /* @__PURE__ */ jsx3(Text2, { variant: "labelLarge", style: labelStyle, children: option.label }),
201
+ option.description && /* @__PURE__ */ jsx3(Text2, { variant: "labelSmall", style: descriptionStyle, children: option.description })
308
202
  ] })
309
203
  ] }) }, option.value);
310
204
  }) });
@@ -318,23 +212,23 @@ function MultiSection({
318
212
  allClearLabels
319
213
  }) {
320
214
  const allSelected = section.value.length === section.options.length;
321
- return /* @__PURE__ */ jsxs3(Fragment2, { children: [
215
+ return /* @__PURE__ */ jsxs2(Fragment, { children: [
322
216
  section.options.map((option, i) => {
323
217
  const selected = section.value.includes(option.value);
324
218
  const rowColor = selected ? onAccentColor : mutedColor;
325
219
  const prevSelected = selected && i > 0 && section.value.includes(section.options[i - 1].value);
326
220
  const nextSelected = selected && i < section.options.length - 1 && section.value.includes(section.options[i + 1].value);
327
- const itemStyle = [styles3.item, selected && { backgroundColor: accentColor }, prevSelected && { borderTopLeftRadius: 0, borderTopRightRadius: 0 }, nextSelected && { borderBottomLeftRadius: 0, borderBottomRightRadius: 0 }];
221
+ const itemStyle = [styles2.item, selected && { backgroundColor: accentColor }, prevSelected && { borderTopLeftRadius: 0, borderTopRightRadius: 0 }, nextSelected && { borderBottomLeftRadius: 0, borderBottomRightRadius: 0 }];
328
222
  const labelStyle = { fontFamily: labelFontFamily, color: rowColor, fontWeight: selected ? "bold" : "normal" };
329
- return /* @__PURE__ */ jsx4(TouchableRipple, { onPress: () => section.onChange(selected ? section.value.filter((v) => v !== option.value) : [...section.value, option.value]), style: itemStyle, children: /* @__PURE__ */ jsxs3(View4, { style: styles3.itemRow, children: [
330
- option.icon && /* @__PURE__ */ jsx4(Icon2, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
331
- /* @__PURE__ */ jsx4(Text2, { variant: "labelLarge", style: [styles3.itemLabelFlex, labelStyle], children: option.label })
223
+ return /* @__PURE__ */ jsx3(TouchableRipple, { onPress: () => section.onChange(selected ? section.value.filter((v) => v !== option.value) : [...section.value, option.value]), style: itemStyle, children: /* @__PURE__ */ jsxs2(View2, { style: styles2.itemRow, children: [
224
+ option.icon && /* @__PURE__ */ jsx3(Icon2, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
225
+ /* @__PURE__ */ jsx3(Text2, { variant: "labelLarge", style: [styles2.itemLabelFlex, labelStyle], children: option.label })
332
226
  ] }) }, option.value);
333
227
  }),
334
- section.allClear && /* @__PURE__ */ jsx4(TouchableRipple, { onPress: () => section.onChange(allSelected ? [] : section.options.map((o) => o.value)), style: styles3.item, children: /* @__PURE__ */ jsx4(Text2, { variant: "labelLarge", style: [styles3.allClearLabel, { fontFamily: labelFontFamily, color: accentColor }], children: allSelected ? allClearLabels.clear : allClearLabels.all }) })
228
+ section.allClear && /* @__PURE__ */ jsx3(TouchableRipple, { onPress: () => section.onChange(allSelected ? [] : section.options.map((o) => o.value)), style: styles2.item, children: /* @__PURE__ */ jsx3(Text2, { variant: "labelLarge", style: [styles2.allClearLabel, { fontFamily: labelFontFamily, color: accentColor }], children: allSelected ? allClearLabels.clear : allClearLabels.all }) })
335
229
  ] });
336
230
  }
337
- var styles3 = StyleSheet3.create({
231
+ var styles2 = StyleSheet2.create({
338
232
  allClearLabel: {
339
233
  fontWeight: "bold",
340
234
  textAlign: "center"
@@ -351,7 +245,7 @@ var styles3 = StyleSheet3.create({
351
245
  zIndex: 100
352
246
  },
353
247
  divider: {
354
- height: StyleSheet3.hairlineWidth,
248
+ height: StyleSheet2.hairlineWidth,
355
249
  marginVertical: 4
356
250
  },
357
251
  item: {
@@ -404,30 +298,30 @@ var styles3 = StyleSheet3.create({
404
298
  });
405
299
 
406
300
  // src/ControlSchemePicker.tsx
407
- import { jsx as jsx5 } from "react/jsx-runtime";
301
+ import { jsx as jsx4 } from "react/jsx-runtime";
408
302
  function ControlSchemePicker({ id, host, value, onChange, options, takenValue, accentColor, mutedColor, onAccentColor, dark, align, alignOverride, rotation, labelFontFamily }) {
409
303
  const isTouchPrimary = useIsTouchPrimaryDevice();
410
304
  if (Platform.OS !== "web" || isTouchPrimary) return null;
411
- return /* @__PURE__ */ jsx5(SectionedDropdown, { id, host, icon: "keyboard-outline", accessibilityLabel: "Control scheme", sections: [{ kind: "single", id: "controls", options, value, onChange, takenValue }], accentColor, mutedColor, onAccentColor, dark, align, alignOverride, rotation, labelFontFamily });
305
+ return /* @__PURE__ */ jsx4(SectionedDropdown, { id, host, icon: "keyboard-outline", accessibilityLabel: "Control scheme", sections: [{ kind: "single", id: "controls", options, value, onChange, takenValue }], accentColor, mutedColor, onAccentColor, dark, align, alignOverride, rotation, labelFontFamily });
412
306
  }
413
307
 
414
308
  // src/CornerStatusBadges.tsx
415
- import { StyleSheet as StyleSheet4, View as View5 } from "react-native";
309
+ import { StyleSheet as StyleSheet3, View as View3 } from "react-native";
416
310
  import { Icon as Icon3 } from "react-native-paper";
417
- import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
311
+ import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
418
312
  var BADGE_SIZE = 30;
419
313
  function StatusBadge({ icon }) {
420
- return /* @__PURE__ */ jsx6(View5, { style: styles4.badge, children: icon && /* @__PURE__ */ jsx6(Icon3, { source: icon, size: 16, color: "rgba(255,255,255,0.85)" }) });
314
+ return /* @__PURE__ */ jsx5(View3, { style: styles3.badge, children: icon && /* @__PURE__ */ jsx5(Icon3, { source: icon, size: 16, color: "rgba(255,255,255,0.85)" }) });
421
315
  }
422
316
  function CornerStatusBadges({ orientationMode, p1OnRight, p1, p2 }) {
423
317
  const p1OnRightSide = orientationMode === "sideBySide" && p1OnRight;
424
318
  const p2OnLeftSide = orientationMode === "sideBySide" && !p1OnRight;
425
- return /* @__PURE__ */ jsxs4(Fragment3, { children: [
426
- p1 && /* @__PURE__ */ jsx6(View5, { pointerEvents: "none", style: p1OnRightSide ? styles4.bottomRight : styles4.bottomLeft, children: /* @__PURE__ */ jsx6(StatusBadge, { icon: p1.icon }) }),
427
- p2 && /* @__PURE__ */ jsx6(View5, { pointerEvents: "none", style: p2OnLeftSide ? styles4.topLeft : styles4.topRight, children: /* @__PURE__ */ jsx6(StatusBadge, { icon: p2.icon }) })
319
+ return /* @__PURE__ */ jsxs3(Fragment2, { children: [
320
+ p1 && /* @__PURE__ */ jsx5(View3, { pointerEvents: "none", style: p1OnRightSide ? styles3.bottomRight : styles3.bottomLeft, children: /* @__PURE__ */ jsx5(StatusBadge, { icon: p1.icon }) }),
321
+ p2 && /* @__PURE__ */ jsx5(View3, { pointerEvents: "none", style: p2OnLeftSide ? styles3.topLeft : styles3.topRight, children: /* @__PURE__ */ jsx5(StatusBadge, { icon: p2.icon }) })
428
322
  ] });
429
323
  }
430
- var styles4 = StyleSheet4.create({
324
+ var styles3 = StyleSheet3.create({
431
325
  badge: {
432
326
  alignItems: "center",
433
327
  backgroundColor: "rgba(0,0,0,0.28)",
@@ -445,149 +339,12 @@ var styles4 = StyleSheet4.create({
445
339
  topRight: { position: "absolute", right: 12, top: 12 }
446
340
  });
447
341
 
448
- // src/InlineColorPicker.tsx
449
- import { defaultColors, getContrastColor as getContrastColor2 } from "@rific/auto-paper";
342
+ // src/LabeledDropdown.tsx
343
+ import { getContrastColor as getContrastColor2 } from "@rific/auto-paper";
450
344
  import { TouchableRipple as TouchableRipple2 } from "@rific/feedback-press";
451
- import { clamp, useRotation as useRotation2 } from "@tastic/core";
452
- import { ScrollView as ScrollView2, StyleSheet as StyleSheet5, useWindowDimensions as useWindowDimensions2, View as View6 } from "react-native";
345
+ import { ScrollView as ScrollView2, StyleSheet as StyleSheet4, View as View4 } from "react-native";
453
346
  import { Icon as Icon4, Text as Text3 } from "react-native-paper";
454
- import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
455
- var EMOJI_PATTERN = /\p{Extended_Pictographic}/u;
456
- var DEFAULT_SIZE = 48;
457
- var SWATCH_SIZE = 28;
458
- var SWATCHES_PADDING = 8;
459
- var SWATCHES_GAP = 6;
460
- var SWATCHES_BORDER_WIDTH = 2;
461
- var MIN_COLUMNS = 4;
462
- var MAX_COLUMNS = 5;
463
- var SCREEN_MARGIN = 40;
464
- function widthForColumns(columns) {
465
- return SWATCHES_BORDER_WIDTH * 2 + SWATCHES_PADDING * 2 + SWATCH_SIZE * columns + SWATCHES_GAP * (columns - 1);
466
- }
467
- function getInlineColorPickerContentSize(swatchCount, windowWidth, columns) {
468
- const autoColumns = clamp(Math.floor((windowWidth - 2 * SCREEN_MARGIN + SWATCHES_GAP) / (SWATCH_SIZE + SWATCHES_GAP)), MIN_COLUMNS, MAX_COLUMNS);
469
- const resolvedColumns = columns ?? autoColumns;
470
- const width = widthForColumns(resolvedColumns);
471
- const rows = Math.ceil(swatchCount / resolvedColumns);
472
- const height = SWATCHES_BORDER_WIDTH * 2 + SWATCHES_PADDING * 2 + SWATCH_SIZE * rows + SWATCHES_GAP * (rows - 1);
473
- return { width, height };
474
- }
475
- function InlineColorPicker({ id, host, value, onChange, previewValue, swatches = defaultColors, takenValue, allowSwapTaken, dark, align: forcedAlign, alignOverride, rotation: rotationOverride, icon = "palette", tag, labelFontFamily = MONO_FONT, autoDismiss = true, columns, size = DEFAULT_SIZE }) {
476
- const ambientRotation = useRotation2();
477
- const rotation = rotationOverride ?? ambientRotation;
478
- const menuBg = dark ? "#000000" : "#FFFFFF";
479
- const { width: windowWidth } = useWindowDimensions2();
480
- const { width: swatchesWidth, height: swatchesHeight } = getInlineColorPickerContentSize(swatches.length, windowWidth, columns);
481
- const open = host.openId === id;
482
- const auto = useAutoAlign(open, swatchesWidth, swatchesHeight, rotation);
483
- const placement = alignOverride ?? auto;
484
- const { maxHeight, measured, triggerRef, verticalAlign } = placement;
485
- const align = forcedAlign ?? placement.align;
486
- const displayFor = previewValue ?? ((hex) => hex);
487
- const displayValue = displayFor(value);
488
- const contrastColor = getContrastColor2(displayValue);
489
- const tagFontSize = size * (tag && EMOJI_PATTERN.test(tag) ? 0.6 : 0.4);
490
- return /* @__PURE__ */ jsxs5(View6, { style: [styles5.anchor, open && styles5.anchorOpen], children: [
491
- /* @__PURE__ */ jsx7(TouchableRipple2, { onPress: () => host.toggle(id), borderless: true, style: [styles5.trigger, { backgroundColor: displayValue, borderRadius: size / 2, height: size, width: size }], children: /* @__PURE__ */ jsx7(View6, { ref: triggerRef, collapsable: false, style: styles5.triggerMeasure, children: tag ? /* @__PURE__ */ jsx7(Text3, { style: [styles5.tagLabel, { color: contrastColor, fontFamily: labelFontFamily, fontSize: tagFontSize }], numberOfLines: 1, adjustsFontSizeToFit: true, children: tag }) : /* @__PURE__ */ jsx7(Icon4, { source: icon, size: size * 0.6, color: contrastColor }) }) }),
492
- /* @__PURE__ */ jsx7(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: displayValue, caretBorderWidth: SWATCHES_BORDER_WIDTH, triggerSize: size, children: /* @__PURE__ */ jsx7(ScrollView2, { style: [styles5.swatches, { backgroundColor: menuBg, borderColor: displayValue, width: swatchesWidth, maxHeight }], contentContainerStyle: styles5.swatchesContent, showsVerticalScrollIndicator: false, children: swatches.map((swatch) => {
493
- const selected = swatch.value.toLowerCase() === value.toLowerCase();
494
- const taken = !selected && !!takenValue && swatch.value.toLowerCase() === takenValue.toLowerCase();
495
- const swappable = taken && allowSwapTaken;
496
- const swatchDisplay = displayFor(swatch.value);
497
- return /* @__PURE__ */ jsx7(
498
- TouchableRipple2,
499
- {
500
- disabled: taken && !swappable,
501
- onPress: () => {
502
- onChange(swatch.value);
503
- if (autoDismiss) host.close();
504
- },
505
- borderless: true,
506
- style: [styles5.swatch, { backgroundColor: swatchDisplay }, selected && styles5.swatchSelected, taken && !swappable && styles5.swatchTaken],
507
- children: selected ? /* @__PURE__ */ jsx7(Icon4, { source: "check", size: 16, color: getContrastColor2(swatchDisplay) }) : swappable ? /* @__PURE__ */ jsx7(Icon4, { source: "swap-horizontal", size: 16, color: getContrastColor2(swatchDisplay) }) : taken ? /* @__PURE__ */ jsx7(Icon4, { source: "close", size: 16, color: getContrastColor2(swatchDisplay) }) : /* @__PURE__ */ jsx7(View6, {})
508
- },
509
- swatch.value
510
- );
511
- }) }) })
512
- ] });
513
- }
514
- var styles5 = StyleSheet5.create({
515
- anchor: {
516
- position: "relative"
517
- },
518
- // See SectionedDropdown's identical comment - React Native Web gives every position:'relative' view
519
- // its own stacking context, so the elevation has to live on the anchor itself, not just the
520
- // popover content nested inside it, to correctly paint above this anchor's own later siblings.
521
- anchorOpen: {
522
- zIndex: 100
523
- },
524
- swatch: {
525
- alignItems: "center",
526
- borderRadius: SWATCH_SIZE / 2,
527
- height: SWATCH_SIZE,
528
- justifyContent: "center",
529
- width: SWATCH_SIZE
530
- },
531
- swatchSelected: {
532
- borderColor: "#ffffff",
533
- borderWidth: 2
534
- },
535
- swatchTaken: {
536
- opacity: 0.35
537
- },
538
- swatches: {
539
- borderRadius: 12,
540
- borderWidth: SWATCHES_BORDER_WIDTH,
541
- elevation: 8,
542
- shadowColor: "#000000",
543
- shadowOffset: { height: 2, width: 0 },
544
- shadowOpacity: 0.3,
545
- shadowRadius: 8
546
- // width is set inline above - border-box sizing means it has to include the border too
547
- // (2*SWATCHES_BORDER_WIDTH), not just padding+content, or exactly enough room goes missing that
548
- // the last column silently wraps to a new row. Anything wider than the exact sum just shows as
549
- // dead space on the right edge of each row instead.
550
- },
551
- // Separate from `swatches` itself - see SectionedDropdown's identical menu/menuContent split.
552
- // The scroll frame's own bounds (including maxHeight) live on the ScrollView; the actual grid
553
- // wrapping belongs to its contentContainerStyle, which sizes to the unclamped content instead.
554
- swatchesContent: {
555
- flexDirection: "row",
556
- flexWrap: "wrap",
557
- gap: SWATCHES_GAP,
558
- padding: SWATCHES_PADDING
559
- },
560
- tagLabel: {
561
- fontWeight: "700",
562
- letterSpacing: 0.5
563
- },
564
- // borderRadius/height/width come from the `size` prop instead (see render-site override) - no
565
- // fixed default here, since this style object is shared by every caller regardless of size.
566
- trigger: {
567
- alignItems: "center",
568
- alignSelf: "flex-start",
569
- justifyContent: "center"
570
- },
571
- // Wraps just the icon/tag, inside the TouchableRipple, purely so useAutoAlign has a plain View
572
- // to attach its measurement ref to - TouchableRipple itself doesn't forward a ref to a
573
- // measurable native node. Padded horizontally so a multi-character tag doesn't butt right up
574
- // against the trigger's own circular edge (an icon alone doesn't need it, but this style is
575
- // shared by both).
576
- triggerMeasure: {
577
- alignItems: "center",
578
- height: "100%",
579
- justifyContent: "center",
580
- paddingHorizontal: 4,
581
- width: "100%"
582
- }
583
- });
584
-
585
- // src/LabeledDropdown.tsx
586
- import { getContrastColor as getContrastColor3 } from "@rific/auto-paper";
587
- import { TouchableRipple as TouchableRipple3 } from "@rific/feedback-press";
588
- import { ScrollView as ScrollView3, StyleSheet as StyleSheet6, View as View7 } from "react-native";
589
- import { Icon as Icon5, Text as Text4 } from "react-native-paper";
590
- import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
347
+ import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
591
348
  var TRIGGER_HEIGHT = 28;
592
349
  var POPOVER_WIDTH = 180;
593
350
  var ROW_HEIGHT = 36;
@@ -610,22 +367,22 @@ function LabeledDropdown({ id, host, options, value, onChange, color, dark, alig
610
367
  onChange(option.value);
611
368
  host.close();
612
369
  };
613
- return /* @__PURE__ */ jsxs6(View7, { style: [styles6.anchor, open && styles6.anchorOpen], children: [
614
- /* @__PURE__ */ jsx8(TouchableRipple3, { onPress: () => host.toggle(id), style: styles6.trigger, children: /* @__PURE__ */ jsxs6(View7, { ref: triggerRef, collapsable: false, style: styles6.triggerInner, children: [
615
- /* @__PURE__ */ jsx8(Text4, { style: [styles6.triggerLabel, { color }], numberOfLines: 1, children: (selected?.label ?? "").toUpperCase() }),
616
- /* @__PURE__ */ jsx8(Icon5, { source: "menu-down", size: 16, color })
370
+ return /* @__PURE__ */ jsxs4(View4, { style: [styles4.anchor, open && styles4.anchorOpen], children: [
371
+ /* @__PURE__ */ jsx6(TouchableRipple2, { onPress: () => host.toggle(id), style: styles4.trigger, children: /* @__PURE__ */ jsxs4(View4, { ref: triggerRef, collapsable: false, style: styles4.triggerInner, children: [
372
+ /* @__PURE__ */ jsx6(Text3, { style: [styles4.triggerLabel, { color }], numberOfLines: 1, children: (selected?.label ?? "").toUpperCase() }),
373
+ /* @__PURE__ */ jsx6(Icon4, { source: "menu-down", size: 16, color })
617
374
  ] }) }),
618
- /* @__PURE__ */ jsx8(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: color, caretBorderWidth: 2, triggerSize: TRIGGER_HEIGHT, children: /* @__PURE__ */ jsx8(ScrollView3, { style: [styles6.menu, { backgroundColor: menuBg, borderColor: color, width: POPOVER_WIDTH, maxHeight }], contentContainerStyle: styles6.menuContent, showsVerticalScrollIndicator: false, children: options.map((option) => {
375
+ /* @__PURE__ */ jsx6(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: color, caretBorderWidth: 2, triggerSize: TRIGGER_HEIGHT, children: /* @__PURE__ */ jsx6(ScrollView2, { style: [styles4.menu, { backgroundColor: menuBg, borderColor: color, width: POPOVER_WIDTH, maxHeight }], contentContainerStyle: styles4.menuContent, showsVerticalScrollIndicator: false, children: options.map((option) => {
619
376
  const isSelected = option.value === value;
620
- const onColor = getContrastColor3(color);
621
- return /* @__PURE__ */ jsx8(TouchableRipple3, { onPress: () => handleSelect(option), style: [styles6.row, isSelected && { backgroundColor: color }], children: /* @__PURE__ */ jsxs6(View7, { style: styles6.rowInner, children: [
622
- option.icon && /* @__PURE__ */ jsx8(Icon5, { source: option.icon, size: 18, color: isSelected ? onColor : fg }),
623
- /* @__PURE__ */ jsx8(Text4, { style: [styles6.rowLabel, { color: isSelected ? onColor : fg }], numberOfLines: 1, children: option.label })
377
+ const onColor = getContrastColor2(color);
378
+ return /* @__PURE__ */ jsx6(TouchableRipple2, { onPress: () => handleSelect(option), style: [styles4.row, isSelected && { backgroundColor: color }], children: /* @__PURE__ */ jsxs4(View4, { style: styles4.rowInner, children: [
379
+ option.icon && /* @__PURE__ */ jsx6(Icon4, { source: option.icon, size: 18, color: isSelected ? onColor : fg }),
380
+ /* @__PURE__ */ jsx6(Text3, { style: [styles4.rowLabel, { color: isSelected ? onColor : fg }], numberOfLines: 1, children: option.label })
624
381
  ] }) }, option.value);
625
382
  }) }) })
626
383
  ] });
627
384
  }
628
- var styles6 = StyleSheet6.create({
385
+ var styles4 = StyleSheet4.create({
629
386
  anchor: {
630
387
  position: "relative"
631
388
  },
@@ -684,21 +441,21 @@ function loadSkiaWeb() {
684
441
 
685
442
  // src/PlayerSetupPanel.tsx
686
443
  import { getOptionPickerContentSize, getProfilePickerContentSize, OptionPicker, ProfilePicker } from "@tastic/profile";
687
- import { StyleSheet as StyleSheet8, View as View8 } from "react-native";
688
- import { Text as Text6 } from "react-native-paper";
444
+ import { StyleSheet as StyleSheet6, View as View5 } from "react-native";
445
+ import { Text as Text5 } from "react-native-paper";
689
446
 
690
447
  // src/ReadyButton.tsx
691
- import { TouchableRipple as TouchableRipple4 } from "@rific/feedback-press";
692
- import { StyleSheet as StyleSheet7 } from "react-native";
693
- import { Text as Text5 } from "react-native-paper";
694
- import { jsx as jsx9 } from "react/jsx-runtime";
448
+ import { TouchableRipple as TouchableRipple3 } from "@rific/feedback-press";
449
+ import { StyleSheet as StyleSheet5 } from "react-native";
450
+ import { Text as Text4 } from "react-native-paper";
451
+ import { jsx as jsx7 } from "react/jsx-runtime";
695
452
  function ReadyButton({ color, ready, onToggleReady, style, labelFontFamily = MONO_FONT }) {
696
- const readyButtonStyle = [styles7.readyButton, { borderColor: color }, ready && { backgroundColor: color }, style];
453
+ const readyButtonStyle = [styles5.readyButton, { borderColor: color }, ready && { backgroundColor: color }, style];
697
454
  const labelTextStyle = { fontFamily: labelFontFamily, fontWeight: "bold" };
698
455
  const labelColorStyle = { color: ready ? "#000000" : color };
699
- return /* @__PURE__ */ jsx9(TouchableRipple4, { onPress: onToggleReady, borderless: true, style: readyButtonStyle, children: /* @__PURE__ */ jsx9(Text5, { variant: "labelLarge", style: [labelTextStyle, labelColorStyle], children: ready ? "READY \u2713" : "READY?" }) });
456
+ return /* @__PURE__ */ jsx7(TouchableRipple3, { onPress: onToggleReady, borderless: true, style: readyButtonStyle, children: /* @__PURE__ */ jsx7(Text4, { variant: "labelLarge", style: [labelTextStyle, labelColorStyle], children: ready ? "READY \u2713" : "READY?" }) });
700
457
  }
701
- var styles7 = StyleSheet7.create({
458
+ var styles5 = StyleSheet5.create({
702
459
  readyButton: {
703
460
  alignItems: "center",
704
461
  borderRadius: 12,
@@ -710,41 +467,30 @@ var styles7 = StyleSheet7.create({
710
467
  }
711
468
  });
712
469
 
713
- // src/usePopoverHost.ts
714
- import { useCallback as useCallback2, useState as useState2 } from "react";
715
- function usePopoverHost() {
716
- const [openId, setOpenId] = useState2(null);
717
- const toggle = useCallback2((id) => {
718
- setOpenId((prev) => prev === id ? null : id);
719
- }, []);
720
- const close = useCallback2(() => setOpenId(null), []);
721
- return { openId, toggle, close };
722
- }
723
-
724
470
  // src/useZoneClampedAlign.ts
725
471
  import { useZoneBounds } from "@tastic/split-screen";
726
- import { useEffect as useEffect2, useState as useState3 } from "react";
727
- import { useWindowDimensions as useWindowDimensions3 } from "react-native";
472
+ import { useEffect, useState } from "react";
473
+ import { useWindowDimensions } from "react-native";
728
474
  import { useSafeAreaInsets } from "react-native-safe-area-context";
729
- var EDGE_MARGIN2 = 12;
475
+ var EDGE_MARGIN = 12;
730
476
  function useZoneClampedAlign(open, contentWidth, contentHeight, rotation = 0) {
731
477
  const auto = useAutoAlign(open, contentWidth, contentHeight, rotation);
732
478
  const zone = useZoneBounds();
733
- const { height: windowHeight } = useWindowDimensions3();
479
+ const { height: windowHeight } = useWindowDimensions();
734
480
  const insets = useSafeAreaInsets();
735
481
  const shouldMeasure = open && auto.measured && zone !== null;
736
- const [ownBounds, setOwnBounds] = useState3(null);
737
- const [prevShouldMeasure, setPrevShouldMeasure] = useState3(shouldMeasure);
482
+ const [ownBounds, setOwnBounds] = useState(null);
483
+ const [prevShouldMeasure, setPrevShouldMeasure] = useState(shouldMeasure);
738
484
  if (shouldMeasure !== prevShouldMeasure) {
739
485
  setPrevShouldMeasure(shouldMeasure);
740
486
  setOwnBounds(null);
741
487
  }
742
- useEffect2(() => {
488
+ useEffect(() => {
743
489
  if (!shouldMeasure) return;
744
490
  auto.triggerRef.current?.measureInWindow((_x, y, _width, height) => {
745
491
  const belowShared = zone.zoneSide === "belowShared";
746
- const awayRoom = belowShared ? windowHeight - insets.bottom - (y + height) - EDGE_MARGIN2 : y - insets.top - EDGE_MARGIN2;
747
- const towardRoom = belowShared ? y - zone.sharedEdgeY - EDGE_MARGIN2 : zone.sharedEdgeY - (y + height) - EDGE_MARGIN2;
492
+ const awayRoom = belowShared ? windowHeight - insets.bottom - (y + height) - EDGE_MARGIN : y - insets.top - EDGE_MARGIN;
493
+ const towardRoom = belowShared ? y - zone.sharedEdgeY - EDGE_MARGIN : zone.sharedEdgeY - (y + height) - EDGE_MARGIN;
748
494
  const useToward = contentHeight > awayRoom && towardRoom > awayRoom;
749
495
  let awaySide = belowShared ? "below" : "above";
750
496
  let towardSide = belowShared ? "above" : "below";
@@ -761,7 +507,7 @@ function useZoneClampedAlign(open, contentWidth, contentHeight, rotation = 0) {
761
507
  }
762
508
 
763
509
  // src/PlayerSetupPanel.tsx
764
- import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
510
+ import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
765
511
  function getColorPopoverId(idPrefix) {
766
512
  return `${idPrefix}-color`;
767
513
  }
@@ -784,16 +530,16 @@ function PlayerSetupPanel({ idPrefix, host, label, labelFontFamily, color, onCol
784
530
  const seatPickerId = showProfilePicker ? getProfilePopoverId(idPrefix) : getCpuDifficultyPopoverId(idPrefix);
785
531
  const seatPickerSize = showProfilePicker ? getProfilePickerContentSize(profiles.length, !!onManageProfiles, colorSection) : getOptionPickerContentSize(cpuDifficultyOptions?.length ?? 0, colorSection);
786
532
  const seatPickerAlign = useZoneClampedAlign(seatButton && popover.openId === seatPickerId, seatPickerSize.width, seatPickerSize.height);
787
- return /* @__PURE__ */ jsxs7(View8, { style: [styles8.panel, ownPopoverOpen && styles8.panelOpen], children: [
788
- showProfilePicker ? /* @__PURE__ */ jsx10(ProfilePicker, { idPrefix, host: popover, profiles, selectedId: selectedProfileId ?? null, takenId: takenProfileId, color, dark, guestLabel: guestLabel ?? "GUEST", onSelect: (profile) => onProfileSelect?.(profile), onManage: onManageProfiles, colorSection, alignOverride: seatPickerAlign }) : showCpuDifficulty ? /* @__PURE__ */ jsx10(OptionPicker, { id: getCpuDifficultyPopoverId(idPrefix), host: popover, options: cpuDifficultyOptions, value: cpuDifficulty, onChange: onCpuDifficultyChange, color, dark, icon: cpuIcon, colorSection, alignOverride: seatPickerAlign }) : label && /* @__PURE__ */ jsx10(Text6, { variant: "labelSmall", style: { color, fontFamily: labelFontFamily }, children: label }),
789
- (!seatButton || secondPicker) && /* @__PURE__ */ jsxs7(View8, { style: [styles8.pickerRow, pickerRowPopoverOpen && styles8.pickerRowOpen], children: [
790
- !seatButton && /* @__PURE__ */ jsx10(InlineColorPicker, { id: getColorPopoverId(idPrefix), host: popover, value: color, onChange: onColorChange, swatches, takenValue: takenColor, allowSwapTaken, alignOverride: colorAlignOverride, rotation: colorRotation, dark, tag: isHuman ? selectedProfile?.tag : void 0, icon: isHuman ? humanIcon : cpuIcon }),
533
+ return /* @__PURE__ */ jsxs5(View5, { style: [styles6.panel, ownPopoverOpen && styles6.panelOpen], children: [
534
+ showProfilePicker ? /* @__PURE__ */ jsx8(ProfilePicker, { idPrefix, host: popover, profiles, selectedId: selectedProfileId ?? null, takenId: takenProfileId, color, dark, guestLabel: guestLabel ?? "GUEST", onSelect: (profile) => onProfileSelect?.(profile), onManage: onManageProfiles, colorSection, alignOverride: seatPickerAlign }) : showCpuDifficulty ? /* @__PURE__ */ jsx8(OptionPicker, { id: getCpuDifficultyPopoverId(idPrefix), host: popover, options: cpuDifficultyOptions, value: cpuDifficulty, onChange: onCpuDifficultyChange, color, dark, icon: cpuIcon, colorSection, alignOverride: seatPickerAlign }) : label && /* @__PURE__ */ jsx8(Text5, { variant: "labelSmall", style: { color, fontFamily: labelFontFamily }, children: label }),
535
+ (!seatButton || secondPicker) && /* @__PURE__ */ jsxs5(View5, { style: [styles6.pickerRow, pickerRowPopoverOpen && styles6.pickerRowOpen], children: [
536
+ !seatButton && /* @__PURE__ */ jsx8(InlineColorPicker, { id: getColorPopoverId(idPrefix), host: popover, value: color, onChange: onColorChange, swatches, takenValue: takenColor, allowSwapTaken, alignOverride: colorAlignOverride, rotation: colorRotation, dark, tag: isHuman ? selectedProfile?.tag : void 0, icon: isHuman ? humanIcon : cpuIcon }),
791
537
  secondPicker
792
538
  ] }),
793
- isHuman && showReadyButton && onToggleReady && /* @__PURE__ */ jsx10(ReadyButton, { color, ready: ready ?? false, onToggleReady })
539
+ isHuman && showReadyButton && onToggleReady && /* @__PURE__ */ jsx8(ReadyButton, { color, ready: ready ?? false, onToggleReady })
794
540
  ] });
795
541
  }
796
- var styles8 = StyleSheet8.create({
542
+ var styles6 = StyleSheet6.create({
797
543
  panel: {
798
544
  alignItems: "center",
799
545
  gap: 12
@@ -824,30 +570,22 @@ var styles8 = StyleSheet8.create({
824
570
  }
825
571
  });
826
572
 
827
- // src/PressAwayOverlay.tsx
828
- import { Pressable, StyleSheet as StyleSheet9 } from "react-native";
829
- import { jsx as jsx11 } from "react/jsx-runtime";
830
- function PressAwayOverlay({ active, onPress, style }) {
831
- if (!active) return null;
832
- return /* @__PURE__ */ jsx11(Pressable, { accessibilityLabel: "Dismiss", accessibilityRole: "button", onPress, style: [StyleSheet9.absoluteFill, style] });
833
- }
834
-
835
573
  // src/SharedActionBand.tsx
836
574
  import { IconButton as IconButton2 } from "@rific/feedback-press";
837
- import { StyleSheet as StyleSheet10, View as View9 } from "react-native";
838
- import { jsx as jsx12, jsxs as jsxs8 } from "react/jsx-runtime";
575
+ import { StyleSheet as StyleSheet7, View as View6 } from "react-native";
576
+ import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
839
577
  function SharedActionBand({ onBack, onSettings, onRandomize, onReset, fg, popoverOpen, children }) {
840
- return /* @__PURE__ */ jsxs8(View9, { style: [styles9.column, popoverOpen && styles9.columnOpen], children: [
841
- /* @__PURE__ */ jsxs8(View9, { style: styles9.actionsRow, children: [
842
- /* @__PURE__ */ jsx12(IconButton2, { icon: "arrow-left", iconColor: fg, size: 20, onPress: onBack, accessibilityLabel: "Back" }),
843
- onRandomize && /* @__PURE__ */ jsx12(IconButton2, { icon: "dice-multiple", iconColor: fg, size: 18, onPress: onRandomize, accessibilityLabel: "Randomize match settings" }),
844
- onReset && /* @__PURE__ */ jsx12(IconButton2, { icon: "restore", iconColor: fg, size: 18, onPress: onReset, accessibilityLabel: "Reset match settings to defaults" }),
845
- /* @__PURE__ */ jsx12(IconButton2, { icon: "cog", iconColor: fg, size: 20, onPress: onSettings, accessibilityLabel: "Settings" })
578
+ return /* @__PURE__ */ jsxs6(View6, { style: [styles7.column, popoverOpen && styles7.columnOpen], children: [
579
+ /* @__PURE__ */ jsxs6(View6, { style: styles7.actionsRow, children: [
580
+ /* @__PURE__ */ jsx9(IconButton2, { icon: "arrow-left", iconColor: fg, size: 20, onPress: onBack, accessibilityLabel: "Back" }),
581
+ onRandomize && /* @__PURE__ */ jsx9(IconButton2, { icon: "dice-multiple", iconColor: fg, size: 18, onPress: onRandomize, accessibilityLabel: "Randomize match settings" }),
582
+ onReset && /* @__PURE__ */ jsx9(IconButton2, { icon: "restore", iconColor: fg, size: 18, onPress: onReset, accessibilityLabel: "Reset match settings to defaults" }),
583
+ /* @__PURE__ */ jsx9(IconButton2, { icon: "cog", iconColor: fg, size: 20, onPress: onSettings, accessibilityLabel: "Settings" })
846
584
  ] }),
847
585
  children
848
586
  ] });
849
587
  }
850
- var styles9 = StyleSheet10.create({
588
+ var styles7 = StyleSheet7.create({
851
589
  actionsRow: {
852
590
  alignItems: "center",
853
591
  flexDirection: "row",
@@ -863,22 +601,22 @@ var styles9 = StyleSheet10.create({
863
601
  });
864
602
 
865
603
  // src/useQuitConfirmation.ts
866
- import { useCallback as useCallback3, useEffect as useEffect3, useRef as useRef2, useState as useState4 } from "react";
604
+ import { useCallback, useEffect as useEffect2, useRef, useState as useState2 } from "react";
867
605
  function useQuitConfirmation(hasProgress, onConfirmedBack) {
868
- const [confirmVisible, setConfirmVisible] = useState4(false);
869
- const hasProgressRef = useRef2(hasProgress);
870
- useEffect3(() => {
606
+ const [confirmVisible, setConfirmVisible] = useState2(false);
607
+ const hasProgressRef = useRef(hasProgress);
608
+ useEffect2(() => {
871
609
  hasProgressRef.current = hasProgress;
872
610
  });
873
- const onConfirmedBackRef = useRef2(onConfirmedBack);
874
- useEffect3(() => {
611
+ const onConfirmedBackRef = useRef(onConfirmedBack);
612
+ useEffect2(() => {
875
613
  onConfirmedBackRef.current = onConfirmedBack;
876
614
  });
877
- const requestBack = useCallback3(() => {
615
+ const requestBack = useCallback(() => {
878
616
  if (hasProgressRef.current()) setConfirmVisible(true);
879
617
  else onConfirmedBackRef.current();
880
618
  }, []);
881
- const cancelBack = useCallback3(() => setConfirmVisible(false), []);
619
+ const cancelBack = useCallback(() => setConfirmVisible(false), []);
882
620
  return { confirmVisible, requestBack, cancelBack };
883
621
  }
884
622
  export {
@@ -915,6 +653,7 @@ export {
915
653
  StatSection,
916
654
  TriggerGaugeHost,
917
655
  UpdateDialog,
656
+ WELL_SHADOW,
918
657
  getColorPopoverId,
919
658
  getCpuDifficultyPopoverId,
920
659
  getInlineColorPickerContentSize,
@@ -930,5 +669,6 @@ export {
930
669
  useOverlayCardColors,
931
670
  usePopoverHost,
932
671
  useQuitConfirmation,
672
+ useWellColors,
933
673
  useZoneClampedAlign
934
674
  };