@tastic/hud 0.1.5 → 0.2.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.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, import_react2.useLayoutEffect)(() => {
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, import_react2.useCallback)((i) => startDeg + (i + 0.5) * step, [startDeg, step]);
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, import_react2.useState)(litIndices);
41
+ const [transitionFrom, setTransitionFrom] = (0, import_react3.useState)(litIndices);
42
42
  const transitionFromKey = [...transitionFrom].sort((a, b) => a - b).join(",");
43
- const lastKeyRef = (0, import_react2.useRef)(litIndicesKey);
44
- const lastIndicesRef = (0, import_react2.useRef)(litIndices);
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, import_react2.useLayoutEffect)(() => {
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, import_core2.clamp)((mountProgress.value - startFrac) / (endFrac - startFrac), 0, 1);
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, import_core2.clamp)((mountProgress.value - startFrac) / (endFrac - startFrac), 0, 1);
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, import_jsx_runtime5.jsx)(import_react_native7.View, { style: [styles4.container, gaugeSizeStyle], pointerEvents: "none", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native_skia.Canvas, { style: canvasSizeStyle, children: [
124
- /* @__PURE__ */ (0, import_jsx_runtime5.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_runtime5.jsx)(import_react_native_skia.Path, { path: litPath, style: "stroke", strokeWidth: LIT_THICKNESS, strokeCap: "round", color: accentColor, opacity: 1 })
123
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native8.View, { style: [styles5.container, gaugeSizeStyle], pointerEvents: "none", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_native_skia.Canvas, { style: canvasSizeStyle, children: [
124
+ /* @__PURE__ */ (0, import_jsx_runtime6.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_runtime6.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, import_core2, import_react2, import_react_native7, import_react_native_reanimated, import_jsx_runtime5, 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, styles4;
128
+ var import_react_native_skia, import_core3, import_react3, import_react_native8, import_react_native_reanimated, import_jsx_runtime6, 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, styles5;
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
- import_core2 = require("@tastic/core");
134
- import_react2 = require("react");
135
- import_react_native7 = require("react-native");
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
- import_jsx_runtime5 = require("react/jsx-runtime");
137
+ import_jsx_runtime6 = 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
- styles4 = import_react_native7.StyleSheet.create({
147
+ styles5 = import_react_native8.StyleSheet.create({
148
148
  container: {
149
149
  alignItems: "center",
150
150
  justifyContent: "center",
@@ -157,6 +157,7 @@ var init_TriggerGauge = __esm({
157
157
  // src/index.ts
158
158
  var index_exports = {};
159
159
  __export(index_exports, {
160
+ BaseSettingsDialog: () => BaseSettingsDialog,
160
161
  InlineColorPicker: () => InlineColorPicker,
161
162
  MONO_FONT: () => MONO_FONT,
162
163
  PopoverBody: () => PopoverBody,
@@ -170,42 +171,244 @@ __export(index_exports, {
170
171
  });
171
172
  module.exports = __toCommonJS(index_exports);
172
173
 
173
- // src/fonts.ts
174
- var import_react_native = require("react-native");
175
- var MONO_FONT = import_react_native.Platform.select({ ios: "Menlo", android: "monospace", default: "monospace" });
176
-
177
- // src/InlineColorPicker.tsx
174
+ // src/BaseSettingsDialog.tsx
178
175
  var import_auto_paper = require("@rific/auto-paper");
179
176
  var import_feedback_press = require("@rific/feedback-press");
177
+ var import_updater = require("@rific/updater");
180
178
  var import_core = require("@tastic/core");
181
- var import_react_native4 = require("react-native");
179
+ var import_react = require("react");
180
+ var import_react_native = require("react-native");
182
181
  var import_react_native_paper = require("react-native-paper");
182
+ var import_jsx_runtime = require("react/jsx-runtime");
183
+ function SettingIcon({ source, color, containerColor }) {
184
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.View, { style: [styles.iconBadge, { backgroundColor: containerColor }], children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native_paper.Icon, { source, size: 18, color }) });
185
+ }
186
+ function BaseSettingsDialog({ visible, onDismiss, rotation = 0, version, lockOrientation, onLockOrientationChange, deferBottomEdgeGestures, onDeferBottomEdgeGestures, hideSound = false, hideHaptics = false, hideAppearance = false, hideUpdateCheck = false, onUpdateError, children }) {
187
+ const { dark, colors } = (0, import_auto_paper.useAutoPaperTheme)();
188
+ const isTouchPrimary = (0, import_core.useIsTouchPrimaryDevice)();
189
+ const { settings: hapticSettings, set: setHapticSettings } = (0, import_feedback_press.useHapticSettings)();
190
+ const { settings: soundSettings, set: setSoundSettings } = (0, import_feedback_press.useSoundSettings)();
191
+ const sound = (0, import_react.useContext)(import_feedback_press.SoundContext);
192
+ const { forceShort: forceHapticFeedback } = (0, import_feedback_press.useVibration)();
193
+ const [infoMessage, setInfoMessage] = (0, import_react.useState)(null);
194
+ const { check, checking, updateReady } = (0, import_updater.useUpdater)({
195
+ autoCheck: false,
196
+ autoPrompt: false,
197
+ onError: onUpdateError,
198
+ onInfo: (title, message) => setInfoMessage({ title, message })
199
+ });
200
+ const showLockOrientation = isTouchPrimary && lockOrientation !== void 0 && onLockOrientationChange !== void 0;
201
+ const showEdgeGuard = import_react_native.Platform.OS === "ios" && deferBottomEdgeGestures !== void 0 && onDeferBottomEdgeGestures !== void 0;
202
+ const showHaptics = import_react_native.Platform.OS !== "web" && !hideHaptics;
203
+ const showSound = !hideSound;
204
+ const showAppearance = !hideAppearance;
205
+ const showUpdateCheck = import_react_native.Platform.OS !== "web" && !hideUpdateCheck;
206
+ const fg = dark ? "#FFFFFF" : "#000000";
207
+ const cardBg = dark ? "#111111" : "#F2F2F2";
208
+ const cardBorder = dark ? "rgba(255,255,255,0.2)" : "rgba(0,0,0,0.2)";
209
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
210
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_auto_paper.Dialog, { visible, onDismiss, style: [styles.dialog, rotation % 360 !== 0 && { transform: [{ rotate: `${rotation}deg` }] }], children: [
211
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_auto_paper.Dialog.Title, { children: "Settings" }),
212
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_auto_paper.Dialog.ScrollArea, { style: styles.scrollArea, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native.ScrollView, { contentContainerStyle: styles.content, showsVerticalScrollIndicator: false, children: [
213
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native.View, { style: styles.toggleGroup, children: [
214
+ showLockOrientation && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_feedback_press.TouchableRipple, { onPress: () => onLockOrientationChange(!lockOrientation), style: styles.toggleButton, accessibilityLabel: `Lock orientation ${lockOrientation ? "on" : "off"}`, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native.View, { style: styles.toggleContent, children: [
215
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SettingIcon, { source: lockOrientation ? "lock" : "lock-open-variant-outline", color: lockOrientation ? colors.secondary : colors.onSurfaceVariant, containerColor: lockOrientation ? colors.secondaryContainer : colors.surfaceVariant }),
216
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native.View, { style: styles.flexShrink, children: [
217
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native_paper.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Lock Orientation" }),
218
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native_paper.Text, { variant: "bodySmall", numberOfLines: 1, style: { color: colors.onSurfaceVariant }, children: "Pins the current layout" })
219
+ ] })
220
+ ] }) }),
221
+ showEdgeGuard && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_feedback_press.TouchableRipple, { onPress: () => onDeferBottomEdgeGestures(!deferBottomEdgeGestures), style: styles.toggleButton, accessibilityLabel: `Edge guard ${deferBottomEdgeGestures ? "on" : "off"}`, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native.View, { style: styles.toggleContent, children: [
222
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SettingIcon, { source: deferBottomEdgeGestures ? "shield-check-outline" : "shield-off-outline", color: deferBottomEdgeGestures ? colors.secondary : colors.onSurfaceVariant, containerColor: deferBottomEdgeGestures ? colors.secondaryContainer : colors.surfaceVariant }),
223
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native.View, { style: styles.flexShrink, children: [
224
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native_paper.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Edge Guard" }),
225
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native_paper.Text, { variant: "bodySmall", numberOfLines: 1, style: { color: colors.onSurfaceVariant }, children: "Requires a second swipe" })
226
+ ] })
227
+ ] }) }),
228
+ (showSound || showHaptics) && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native.View, { style: styles.toggleRow, children: [
229
+ showSound && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
230
+ import_feedback_press.TouchableRipple,
231
+ {
232
+ soundDisabled: true,
233
+ onPress: () => {
234
+ const enabled = !soundSettings.enabled;
235
+ setSoundSettings({ enabled });
236
+ if (enabled) sound.selection?.();
237
+ },
238
+ style: styles.toggleButtonInRow,
239
+ accessibilityLabel: `Sound ${soundSettings.enabled ? "on" : "off"}`,
240
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native.View, { style: styles.toggleContent, children: [
241
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SettingIcon, { source: soundSettings.enabled ? "volume-high" : "volume-off", color: soundSettings.enabled ? colors.tertiary : colors.onSurfaceVariant, containerColor: soundSettings.enabled ? colors.tertiaryContainer : colors.surfaceVariant }),
242
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native_paper.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Sound" })
243
+ ] })
244
+ }
245
+ ),
246
+ showHaptics && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
247
+ import_feedback_press.TouchableRipple,
248
+ {
249
+ hapticDisabled: true,
250
+ onPress: () => {
251
+ const vibrate = !hapticSettings.vibrate;
252
+ setHapticSettings({ vibrate });
253
+ if (vibrate) forceHapticFeedback();
254
+ },
255
+ style: styles.toggleButtonInRow,
256
+ accessibilityLabel: `Haptics ${hapticSettings.vibrate ? "on" : "off"}`,
257
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native.View, { style: styles.toggleContent, children: [
258
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SettingIcon, { source: hapticSettings.vibrate ? "vibrate" : "vibrate-off", color: hapticSettings.vibrate ? colors.tertiary : colors.onSurfaceVariant, containerColor: hapticSettings.vibrate ? colors.tertiaryContainer : colors.surfaceVariant }),
259
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native_paper.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Haptics" })
260
+ ] })
261
+ }
262
+ )
263
+ ] })
264
+ ] }),
265
+ showAppearance && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native.View, { style: styles.section, children: [
266
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native_paper.Text, { variant: "labelMedium", style: [styles.sectionLabel, { color: colors.onSurfaceVariant }], children: "APPEARANCE" }),
267
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_auto_paper.AutoAppearancePicker, { showLabels: false })
268
+ ] }),
269
+ children,
270
+ showUpdateCheck && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native.View, { style: styles.section, children: [
271
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native_paper.Text, { variant: "labelSmall", style: [styles.sectionLabel, { color: colors.onSurfaceVariant }], children: [
272
+ "VERSION ",
273
+ version,
274
+ updateReady ? " \xB7 UPDATE READY" : ""
275
+ ] }),
276
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_feedback_press.Button, { mode: "outlined", onPress: check, loading: checking, disabled: checking, children: "Check for Updates" })
277
+ ] })
278
+ ] }) })
279
+ ] }),
280
+ infoMessage && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native_paper.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.View, { style: styles.overlay, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native.View, { style: [styles.overlayCard, { backgroundColor: cardBg, borderColor: cardBorder }, rotation % 360 !== 0 && { transform: [{ rotate: `${rotation}deg` }] }], children: [
281
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native_paper.Icon, { source: "information-outline", size: 64, color: colors.secondary }),
282
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native_paper.Text, { variant: "headlineLarge", style: [styles.overlayTitle, { color: colors.secondary }], children: infoMessage.title }),
283
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native_paper.Text, { variant: "bodyLarge", style: [styles.overlayBody, { color: fg }], children: infoMessage.message }),
284
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_feedback_press.Button, { mode: "contained", onPress: () => setInfoMessage(null), style: styles.overlayButton, buttonColor: colors.primary, textColor: colors.onPrimary, children: "OK" })
285
+ ] }) }) })
286
+ ] });
287
+ }
288
+ var styles = import_react_native.StyleSheet.create({
289
+ content: {
290
+ gap: 24,
291
+ paddingVertical: 20
292
+ },
293
+ // Caps the card so it never grows past the screen — without this the dialog just keeps
294
+ // growing to fit its content and the overflow gets clipped by the screen edge, which is
295
+ // what happened in landscape where there's less height to work with. Dialog.ScrollArea +
296
+ // ScrollView below then take over and let the content scroll within that bound.
297
+ dialog: {
298
+ maxHeight: "90%"
299
+ },
300
+ flexShrink: {
301
+ flexShrink: 1
302
+ },
303
+ iconBadge: {
304
+ alignItems: "center",
305
+ borderRadius: 10,
306
+ height: 36,
307
+ justifyContent: "center",
308
+ width: 36
309
+ },
310
+ overlay: {
311
+ alignItems: "center",
312
+ backgroundColor: "rgba(0,0,0,0.72)",
313
+ bottom: 0,
314
+ justifyContent: "center",
315
+ left: 0,
316
+ position: "absolute",
317
+ right: 0,
318
+ top: 0
319
+ },
320
+ overlayBody: { textAlign: "center" },
321
+ overlayButton: { width: 160 },
322
+ overlayCard: {
323
+ alignItems: "center",
324
+ borderRadius: 20,
325
+ borderWidth: 1,
326
+ gap: 16,
327
+ maxWidth: 360,
328
+ padding: 32
329
+ },
330
+ overlayTitle: { fontWeight: "bold" },
331
+ scrollArea: {
332
+ marginBottom: 0
333
+ },
334
+ section: {
335
+ gap: 12
336
+ },
337
+ sectionLabel: {
338
+ letterSpacing: 2
339
+ },
340
+ // Negative margin cancels the padding so the icon still lines up with APPEARANCE/SOUND &
341
+ // HAPTICS below, while the ripple/hover highlight itself gets room to breathe on both sides
342
+ // instead of a flush edge-to-edge slab. overflow: 'hidden' makes sure that highlight actually
343
+ // clips to borderRadius instead of drawing as a plain rectangle.
344
+ toggleButton: {
345
+ borderRadius: 12,
346
+ marginHorizontal: -12,
347
+ overflow: "hidden",
348
+ paddingHorizontal: 12,
349
+ paddingVertical: 10
350
+ },
351
+ // Same shape as toggleButton but `flex: 1` instead of its own `marginHorizontal: -12` — two of
352
+ // these side by side in toggleRow would otherwise both pull inward and collide in the middle.
353
+ // toggleRow carries that edge-alignment margin once, for the row as a whole, instead.
354
+ toggleButtonInRow: {
355
+ borderRadius: 12,
356
+ flex: 1,
357
+ overflow: "hidden",
358
+ paddingHorizontal: 12,
359
+ paddingVertical: 10
360
+ },
361
+ toggleContent: {
362
+ alignItems: "center",
363
+ flexDirection: "row",
364
+ gap: 12
365
+ },
366
+ toggleGroup: {
367
+ gap: 4
368
+ },
369
+ toggleRow: {
370
+ flexDirection: "row",
371
+ gap: 4,
372
+ marginHorizontal: -12
373
+ }
374
+ });
183
375
 
184
- // src/PopoverBody.tsx
376
+ // src/fonts.ts
185
377
  var import_react_native2 = require("react-native");
186
- var import_jsx_runtime = require("react/jsx-runtime");
378
+ var MONO_FONT = import_react_native2.Platform.select({ ios: "Menlo", android: "monospace", default: "monospace" });
379
+
380
+ // src/InlineColorPicker.tsx
381
+ var import_auto_paper2 = require("@rific/auto-paper");
382
+ var import_feedback_press2 = require("@rific/feedback-press");
383
+ var import_core2 = require("@tastic/core");
384
+ var import_react_native5 = require("react-native");
385
+ var import_react_native_paper2 = require("react-native-paper");
386
+
387
+ // src/PopoverBody.tsx
388
+ var import_react_native3 = require("react-native");
389
+ var import_jsx_runtime2 = require("react/jsx-runtime");
187
390
  var CARET_SIZE = 7;
188
391
  var CARET_RING_OFFSET = 2;
189
392
  var CARET_DIP = 1;
190
393
  function PopoverBody({ visible, children, align = "center", verticalAlign = "below", caretColor, caretBorderColor, caretBorderWidth = 1, triggerSize = 0 }) {
191
394
  if (!visible) return null;
192
395
  const above = verticalAlign === "above";
193
- const alignStyle = align === "left" ? styles.contentLeft : align === "right" ? styles.contentRight : styles.contentCenter;
194
- const verticalStyle = above ? styles.contentAbove : styles.contentBelow;
396
+ const alignStyle = align === "left" ? styles2.contentLeft : align === "right" ? styles2.contentRight : styles2.contentCenter;
397
+ const verticalStyle = above ? styles2.contentAbove : styles2.contentBelow;
195
398
  const ringSize = CARET_SIZE + caretBorderWidth;
196
399
  const caretOffset = (halfFootprint) => align === "right" ? { right: triggerSize / 2 - halfFootprint } : { left: triggerSize / 2 - halfFootprint };
197
400
  const caretFill = above ? "borderTopColor" : "borderBottomColor";
198
401
  const caretWidthProp = above ? "borderTopWidth" : "borderBottomWidth";
199
402
  const caretEdge = (size) => above ? { bottom: -size + CARET_DIP } : { top: -size + CARET_DIP };
200
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: [styles.content, alignStyle, verticalStyle], children: [
403
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native3.View, { style: [styles2.content, alignStyle, verticalStyle], children: [
201
404
  children,
202
- caretColor && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
203
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.View, { style: [styles.caret, caretOffset(ringSize), caretEdge(ringSize), { [caretFill]: caretBorderColor ?? caretColor, [caretWidthProp]: ringSize, borderLeftWidth: ringSize, borderRightWidth: ringSize }] }),
204
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.View, { style: [styles.caret, caretOffset(CARET_SIZE), caretEdge(CARET_SIZE - CARET_RING_OFFSET), { [caretFill]: caretColor, [caretWidthProp]: CARET_SIZE, borderLeftWidth: CARET_SIZE, borderRightWidth: CARET_SIZE }] })
405
+ caretColor && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
406
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.View, { style: [styles2.caret, caretOffset(ringSize), caretEdge(ringSize), { [caretFill]: caretBorderColor ?? caretColor, [caretWidthProp]: ringSize, borderLeftWidth: ringSize, borderRightWidth: ringSize }] }),
407
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.View, { style: [styles2.caret, caretOffset(CARET_SIZE), caretEdge(CARET_SIZE - CARET_RING_OFFSET), { [caretFill]: caretColor, [caretWidthProp]: CARET_SIZE, borderLeftWidth: CARET_SIZE, borderRightWidth: CARET_SIZE }] })
205
408
  ] })
206
409
  ] });
207
410
  }
208
- var styles = import_react_native2.StyleSheet.create({
411
+ var styles2 = import_react_native3.StyleSheet.create({
209
412
  caret: {
210
413
  borderLeftColor: "transparent",
211
414
  borderRightColor: "transparent",
@@ -248,22 +451,22 @@ var styles = import_react_native2.StyleSheet.create({
248
451
  });
249
452
 
250
453
  // src/useAutoAlign.ts
251
- var import_react = require("react");
252
- var import_react_native3 = require("react-native");
454
+ var import_react2 = require("react");
455
+ var import_react_native4 = require("react-native");
253
456
  var EDGE_MARGIN = 12;
254
457
  function useAutoAlign(open, contentWidth, contentHeight) {
255
- const triggerRef = (0, import_react.useRef)(null);
256
- const { width: windowWidth, height: windowHeight } = (0, import_react_native3.useWindowDimensions)();
257
- const [align, setAlign] = (0, import_react.useState)("center");
258
- const [verticalAlign, setVerticalAlign] = (0, import_react.useState)("below");
259
- const [maxHeight, setMaxHeight] = (0, import_react.useState)(contentHeight);
260
- const [measured, setMeasured] = (0, import_react.useState)(false);
261
- const [prevOpen, setPrevOpen] = (0, import_react.useState)(open);
458
+ const triggerRef = (0, import_react2.useRef)(null);
459
+ const { width: windowWidth, height: windowHeight } = (0, import_react_native4.useWindowDimensions)();
460
+ const [align, setAlign] = (0, import_react2.useState)("center");
461
+ const [verticalAlign, setVerticalAlign] = (0, import_react2.useState)("below");
462
+ const [maxHeight, setMaxHeight] = (0, import_react2.useState)(contentHeight);
463
+ const [measured, setMeasured] = (0, import_react2.useState)(false);
464
+ const [prevOpen, setPrevOpen] = (0, import_react2.useState)(open);
262
465
  if (open !== prevOpen) {
263
466
  setPrevOpen(open);
264
467
  if (open) setMeasured(false);
265
468
  }
266
- const measure = (0, import_react.useCallback)(() => {
469
+ const measure = (0, import_react2.useCallback)(() => {
267
470
  triggerRef.current?.measureInWindow((x, y, triggerWidth, triggerHeight) => {
268
471
  const centerX = x + triggerWidth / 2;
269
472
  const overflowsRight = centerX + contentWidth / 2 > windowWidth - EDGE_MARGIN;
@@ -279,14 +482,14 @@ function useAutoAlign(open, contentWidth, contentHeight) {
279
482
  setMeasured(true);
280
483
  });
281
484
  }, [contentWidth, contentHeight, windowWidth, windowHeight]);
282
- (0, import_react.useEffect)(() => {
485
+ (0, import_react2.useEffect)(() => {
283
486
  if (open) measure();
284
487
  }, [open, measure]);
285
488
  return { align, maxHeight, measured, triggerRef, verticalAlign };
286
489
  }
287
490
 
288
491
  // src/InlineColorPicker.tsx
289
- var import_jsx_runtime2 = require("react/jsx-runtime");
492
+ var import_jsx_runtime3 = require("react/jsx-runtime");
290
493
  var EMOJI_PATTERN = /\p{Extended_Pictographic}/u;
291
494
  var DEFAULT_SIZE = 48;
292
495
  var SWATCH_SIZE = 28;
@@ -299,10 +502,10 @@ var SCREEN_MARGIN = 40;
299
502
  function widthForColumns(columns) {
300
503
  return SWATCHES_BORDER_WIDTH * 2 + SWATCHES_PADDING * 2 + SWATCH_SIZE * columns + SWATCHES_GAP * (columns - 1);
301
504
  }
302
- function InlineColorPicker({ id, host, value, onChange, swatches = import_auto_paper.defaultColors, takenValue, allowSwapTaken, dark, align: alignOverride, icon = "palette", tag, labelFontFamily = MONO_FONT, autoDismiss = true, columns, size = DEFAULT_SIZE }) {
505
+ function InlineColorPicker({ id, host, value, onChange, swatches = import_auto_paper2.defaultColors, takenValue, allowSwapTaken, dark, align: alignOverride, icon = "palette", tag, labelFontFamily = MONO_FONT, autoDismiss = true, columns, size = DEFAULT_SIZE }) {
303
506
  const menuBg = dark ? "#000000" : "#FFFFFF";
304
- const { width: windowWidth } = (0, import_react_native4.useWindowDimensions)();
305
- const autoColumns = (0, import_core.clamp)(Math.floor((windowWidth - 2 * SCREEN_MARGIN + SWATCHES_GAP) / (SWATCH_SIZE + SWATCHES_GAP)), MIN_COLUMNS, MAX_COLUMNS);
507
+ const { width: windowWidth } = (0, import_react_native5.useWindowDimensions)();
508
+ const autoColumns = (0, import_core2.clamp)(Math.floor((windowWidth - 2 * SCREEN_MARGIN + SWATCHES_GAP) / (SWATCH_SIZE + SWATCHES_GAP)), MIN_COLUMNS, MAX_COLUMNS);
306
509
  const resolvedColumns = columns ?? autoColumns;
307
510
  const swatchesWidth = widthForColumns(resolvedColumns);
308
511
  const swatchRows = Math.ceil(swatches.length / resolvedColumns);
@@ -310,16 +513,16 @@ function InlineColorPicker({ id, host, value, onChange, swatches = import_auto_p
310
513
  const open = host.openId === id;
311
514
  const { align: autoAlign, maxHeight, measured, triggerRef, verticalAlign } = useAutoAlign(open, swatchesWidth, swatchesHeight);
312
515
  const align = alignOverride ?? autoAlign;
313
- const contrastColor = (0, import_auto_paper.getContrastColor)(value);
516
+ const contrastColor = (0, import_auto_paper2.getContrastColor)(value);
314
517
  const tagFontSize = size * (tag && EMOJI_PATTERN.test(tag) ? 0.6 : 0.4);
315
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { style: [styles2.anchor, open && styles2.anchorOpen], children: [
316
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_feedback_press.TouchableRipple, { onPress: () => host.toggle(id), borderless: true, style: [styles2.trigger, { backgroundColor: value, borderRadius: size / 2, height: size, width: size }], children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.View, { ref: triggerRef, collapsable: false, style: styles2.triggerMeasure, children: tag ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_paper.Text, { style: [styles2.tagLabel, { color: contrastColor, fontFamily: labelFontFamily, fontSize: tagFontSize }], numberOfLines: 1, adjustsFontSizeToFit: true, children: tag }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_paper.Icon, { source: icon, size: size * 0.6, color: contrastColor }) }) }),
317
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: value, caretBorderWidth: SWATCHES_BORDER_WIDTH, triggerSize: size, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.ScrollView, { style: [styles2.swatches, { backgroundColor: menuBg, borderColor: value, width: swatchesWidth, maxHeight }], contentContainerStyle: styles2.swatchesContent, showsVerticalScrollIndicator: false, children: swatches.map((swatch) => {
518
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native5.View, { style: [styles3.anchor, open && styles3.anchorOpen], children: [
519
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_feedback_press2.TouchableRipple, { onPress: () => host.toggle(id), borderless: true, style: [styles3.trigger, { backgroundColor: value, borderRadius: size / 2, height: size, width: size }], children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.View, { ref: triggerRef, collapsable: false, style: styles3.triggerMeasure, children: tag ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper2.Text, { style: [styles3.tagLabel, { color: contrastColor, fontFamily: labelFontFamily, fontSize: tagFontSize }], numberOfLines: 1, adjustsFontSizeToFit: true, children: tag }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper2.Icon, { source: icon, size: size * 0.6, color: contrastColor }) }) }),
520
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: value, caretBorderWidth: SWATCHES_BORDER_WIDTH, triggerSize: size, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.ScrollView, { style: [styles3.swatches, { backgroundColor: menuBg, borderColor: value, width: swatchesWidth, maxHeight }], contentContainerStyle: styles3.swatchesContent, showsVerticalScrollIndicator: false, children: swatches.map((swatch) => {
318
521
  const selected = swatch.value.toLowerCase() === value.toLowerCase();
319
522
  const taken = !selected && !!takenValue && swatch.value.toLowerCase() === takenValue.toLowerCase();
320
523
  const swappable = taken && allowSwapTaken;
321
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
322
- import_feedback_press.TouchableRipple,
524
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
525
+ import_feedback_press2.TouchableRipple,
323
526
  {
324
527
  disabled: taken && !swappable,
325
528
  onPress: () => {
@@ -327,15 +530,15 @@ function InlineColorPicker({ id, host, value, onChange, swatches = import_auto_p
327
530
  if (autoDismiss) host.close();
328
531
  },
329
532
  borderless: true,
330
- style: [styles2.swatch, { backgroundColor: swatch.value }, selected && styles2.swatchSelected, taken && !swappable && styles2.swatchTaken],
331
- children: selected ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_paper.Icon, { source: "check", size: 16, color: (0, import_auto_paper.getContrastColor)(swatch.value) }) : swappable ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_paper.Icon, { source: "swap-horizontal", size: 16, color: (0, import_auto_paper.getContrastColor)(swatch.value) }) : taken ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_paper.Icon, { source: "close", size: 16, color: (0, import_auto_paper.getContrastColor)(swatch.value) }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.View, {})
533
+ style: [styles3.swatch, { backgroundColor: swatch.value }, selected && styles3.swatchSelected, taken && !swappable && styles3.swatchTaken],
534
+ children: selected ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper2.Icon, { source: "check", size: 16, color: (0, import_auto_paper2.getContrastColor)(swatch.value) }) : swappable ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper2.Icon, { source: "swap-horizontal", size: 16, color: (0, import_auto_paper2.getContrastColor)(swatch.value) }) : taken ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper2.Icon, { source: "close", size: 16, color: (0, import_auto_paper2.getContrastColor)(swatch.value) }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.View, {})
332
535
  },
333
536
  swatch.value
334
537
  );
335
538
  }) }) })
336
539
  ] });
337
540
  }
338
- var styles2 = import_react_native4.StyleSheet.create({
541
+ var styles3 = import_react_native5.StyleSheet.create({
339
542
  anchor: {
340
543
  position: "relative"
341
544
  },
@@ -412,25 +615,25 @@ function loadSkiaWeb() {
412
615
  }
413
616
 
414
617
  // src/PressAwayOverlay.tsx
415
- var import_react_native5 = require("react-native");
416
- var import_jsx_runtime3 = require("react/jsx-runtime");
618
+ var import_react_native6 = require("react-native");
619
+ var import_jsx_runtime4 = require("react/jsx-runtime");
417
620
  function PressAwayOverlay({ active, onPress, style }) {
418
621
  if (!active) return null;
419
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.Pressable, { accessibilityLabel: "Dismiss", accessibilityRole: "button", onPress, style: [import_react_native5.StyleSheet.absoluteFill, style] });
622
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native6.Pressable, { accessibilityLabel: "Dismiss", accessibilityRole: "button", onPress, style: [import_react_native6.StyleSheet.absoluteFill, style] });
420
623
  }
421
624
 
422
625
  // src/ReadyButton.tsx
423
- var import_feedback_press2 = require("@rific/feedback-press");
424
- var import_react_native6 = require("react-native");
425
- var import_react_native_paper2 = require("react-native-paper");
426
- var import_jsx_runtime4 = require("react/jsx-runtime");
626
+ var import_feedback_press3 = require("@rific/feedback-press");
627
+ var import_react_native7 = require("react-native");
628
+ var import_react_native_paper3 = require("react-native-paper");
629
+ var import_jsx_runtime5 = require("react/jsx-runtime");
427
630
  function ReadyButton({ color, ready, onToggleReady, style, labelFontFamily = MONO_FONT }) {
428
- const readyButtonStyle = [styles3.readyButton, { borderColor: color }, ready && { backgroundColor: color }, style];
631
+ const readyButtonStyle = [styles4.readyButton, { borderColor: color }, ready && { backgroundColor: color }, style];
429
632
  const labelTextStyle = { fontFamily: labelFontFamily, fontWeight: "bold" };
430
633
  const labelColorStyle = { color: ready ? "#000000" : color };
431
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_feedback_press2.TouchableRipple, { onPress: onToggleReady, borderless: true, style: readyButtonStyle, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native_paper2.Text, { variant: "labelLarge", style: [labelTextStyle, labelColorStyle], children: ready ? "READY \u2713" : "READY?" }) });
634
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_feedback_press3.TouchableRipple, { onPress: onToggleReady, borderless: true, style: readyButtonStyle, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native_paper3.Text, { variant: "labelLarge", style: [labelTextStyle, labelColorStyle], children: ready ? "READY \u2713" : "READY?" }) });
432
635
  }
433
- var styles3 = import_react_native6.StyleSheet.create({
636
+ var styles4 = import_react_native7.StyleSheet.create({
434
637
  readyButton: {
435
638
  alignItems: "center",
436
639
  borderRadius: 12,
@@ -443,21 +646,21 @@ var styles3 = import_react_native6.StyleSheet.create({
443
646
  });
444
647
 
445
648
  // src/SectionedDropdown.tsx
446
- var import_auto_paper2 = require("@rific/auto-paper");
447
- var import_feedback_press3 = require("@rific/feedback-press");
448
- var import_react_native8 = require("react-native");
449
- var import_react_native_paper3 = require("react-native-paper");
649
+ var import_auto_paper3 = require("@rific/auto-paper");
650
+ var import_feedback_press4 = require("@rific/feedback-press");
651
+ var import_react_native9 = require("react-native");
652
+ var import_react_native_paper4 = require("react-native-paper");
450
653
 
451
654
  // src/TriggerGaugeHost.tsx
452
- var import_react3 = require("react");
453
- var import_jsx_runtime6 = require("react/jsx-runtime");
454
- var LazyTriggerGauge = (0, import_react3.lazy)(() => loadSkiaWeb().then(() => Promise.resolve().then(() => (init_TriggerGauge(), TriggerGauge_exports)).then((m) => ({ default: m.TriggerGauge }))));
655
+ var import_react4 = require("react");
656
+ var import_jsx_runtime7 = require("react/jsx-runtime");
657
+ var LazyTriggerGauge = (0, import_react4.lazy)(() => loadSkiaWeb().then(() => Promise.resolve().then(() => (init_TriggerGauge(), TriggerGauge_exports)).then((m) => ({ default: m.TriggerGauge }))));
455
658
  function TriggerGaugeHost(props) {
456
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react3.Suspense, { fallback: null, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(LazyTriggerGauge, { ...props }) });
659
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react4.Suspense, { fallback: null, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(LazyTriggerGauge, { ...props }) });
457
660
  }
458
661
 
459
662
  // src/SectionedDropdown.tsx
460
- var import_jsx_runtime7 = require("react/jsx-runtime");
663
+ var import_jsx_runtime8 = require("react/jsx-runtime");
461
664
  var MENU_BORDER_WIDTH = 1;
462
665
  var TRIGGER_SIZE = 44;
463
666
  var MENU_MIN_WIDTH = 200;
@@ -470,8 +673,8 @@ var MENU_DIVIDER_HEIGHT = 9;
470
673
  var MENU_VERTICAL_PADDING = 12;
471
674
  function SectionedDropdown({ id, host, icon, accessibilityLabel, sections, accentColor, mutedColor, onAccentColor, dark, align: alignOverride, autoDismiss = true, labelFontFamily = MONO_FONT, allClearLabels = { all: "All", clear: "Clear" } }) {
472
675
  const menuBg = dark ? "#000000" : "#FFFFFF";
473
- const menuBorderColor = (0, import_auto_paper2.getBlendedColor)(mutedColor, menuBg, 0.5);
474
- const resolvedOnAccentColor = onAccentColor ?? (0, import_auto_paper2.getColorRoles)(accentColor, menuBg).onColor;
676
+ const menuBorderColor = (0, import_auto_paper3.getBlendedColor)(mutedColor, menuBg, 0.5);
677
+ const resolvedOnAccentColor = onAccentColor ?? (0, import_auto_paper3.getColorRoles)(accentColor, menuBg).onColor;
475
678
  const fg = dark ? "#FFFFFF" : "#000000";
476
679
  const open = host.openId === id;
477
680
  const estimatedHeight = MENU_VERTICAL_PADDING + sections.reduce((sum, section, sectionIndex) => {
@@ -503,17 +706,17 @@ function SectionedDropdown({ id, host, icon, accessibilityLabel, sections, accen
503
706
  }
504
707
  gaugeOffset += section.options.length;
505
708
  }
506
- const anchorStyle = [styles5.anchor, open && styles5.anchorOpen];
709
+ const anchorStyle = [styles6.anchor, open && styles6.anchorOpen];
507
710
  const menuStyle = { backgroundColor: menuBg, borderColor: menuBorderColor, maxHeight };
508
711
  const dividerStyle = { backgroundColor: menuBorderColor };
509
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_native8.View, { style: anchorStyle, children: [
510
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_native8.View, { ref: triggerRef, collapsable: false, style: styles5.triggerBox, children: [
511
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(TriggerGaugeHost, { segments: gaugeSegments, litIndices: gaugeLitIndices, size: TRIGGER_SIZE, accentColor, mutedColor }),
512
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_feedback_press3.IconButton, { icon: triggerIcon, iconColor: triggerIconColor, size: triggerIconSize, accessibilityLabel, onPress: () => host.toggle(id) })
712
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_react_native9.View, { style: anchorStyle, children: [
713
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_react_native9.View, { ref: triggerRef, collapsable: false, style: styles6.triggerBox, children: [
714
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(TriggerGaugeHost, { segments: gaugeSegments, litIndices: gaugeLitIndices, size: TRIGGER_SIZE, accentColor, mutedColor }),
715
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_feedback_press4.IconButton, { icon: triggerIcon, iconColor: triggerIconColor, size: triggerIconSize, accessibilityLabel, onPress: () => host.toggle(id) })
513
716
  ] }),
514
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: menuBorderColor, caretBorderWidth: MENU_BORDER_WIDTH, triggerSize: TRIGGER_SIZE, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native8.ScrollView, { style: [styles5.menu, menuStyle], contentContainerStyle: styles5.menuContent, showsVerticalScrollIndicator: false, children: sections.map((section, sectionIndex) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_native8.View, { children: [
515
- sectionIndex > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native8.View, { style: [styles5.divider, dividerStyle] }),
516
- section.kind === "single" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
717
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: menuBorderColor, caretBorderWidth: MENU_BORDER_WIDTH, triggerSize: TRIGGER_SIZE, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native9.ScrollView, { style: [styles6.menu, menuStyle], contentContainerStyle: styles6.menuContent, showsVerticalScrollIndicator: false, children: sections.map((section, sectionIndex) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_react_native9.View, { children: [
718
+ sectionIndex > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native9.View, { style: [styles6.divider, dividerStyle] }),
719
+ section.kind === "single" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
517
720
  SingleSection,
518
721
  {
519
722
  section,
@@ -526,7 +729,7 @@ function SectionedDropdown({ id, host, icon, accessibilityLabel, sections, accen
526
729
  if (autoDismiss) host.close();
527
730
  }
528
731
  }
529
- ) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(MultiSection, { section, accentColor, onAccentColor: resolvedOnAccentColor, mutedColor, labelFontFamily, allClearLabels })
732
+ ) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(MultiSection, { section, accentColor, onAccentColor: resolvedOnAccentColor, mutedColor, labelFontFamily, allClearLabels })
530
733
  ] }, section.id)) }) })
531
734
  ] });
532
735
  }
@@ -538,17 +741,17 @@ function SingleSection({
538
741
  labelFontFamily,
539
742
  onSelect
540
743
  }) {
541
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_jsx_runtime7.Fragment, { children: section.options.map((option) => {
744
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_jsx_runtime8.Fragment, { children: section.options.map((option) => {
542
745
  const selected = option.value === section.value;
543
746
  const rowColor = selected ? onAccentColor : mutedColor;
544
- const itemStyle = [styles5.item, selected && { backgroundColor: accentColor }];
747
+ const itemStyle = [styles6.item, selected && { backgroundColor: accentColor }];
545
748
  const labelStyle = { fontFamily: labelFontFamily, color: rowColor, fontWeight: selected ? "bold" : "normal" };
546
749
  const descriptionStyle = { fontFamily: labelFontFamily, color: rowColor };
547
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_feedback_press3.TouchableRipple, { onPress: () => onSelect(option.value), style: itemStyle, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_native8.View, { style: styles5.itemRow, children: [
548
- option.icon && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native_paper3.Icon, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
549
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_native8.View, { style: styles5.itemLabelColumn, children: [
550
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native_paper3.Text, { variant: "labelLarge", style: labelStyle, children: option.label }),
551
- option.description && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native_paper3.Text, { variant: "labelSmall", style: descriptionStyle, children: option.description })
750
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_feedback_press4.TouchableRipple, { onPress: () => onSelect(option.value), style: itemStyle, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_react_native9.View, { style: styles6.itemRow, children: [
751
+ option.icon && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native_paper4.Icon, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
752
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_react_native9.View, { style: styles6.itemLabelColumn, children: [
753
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native_paper4.Text, { variant: "labelLarge", style: labelStyle, children: option.label }),
754
+ option.description && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native_paper4.Text, { variant: "labelSmall", style: descriptionStyle, children: option.description })
552
755
  ] })
553
756
  ] }) }, option.value);
554
757
  }) });
@@ -562,23 +765,23 @@ function MultiSection({
562
765
  allClearLabels
563
766
  }) {
564
767
  const allSelected = section.value.length === section.options.length;
565
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
768
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
566
769
  section.options.map((option, i) => {
567
770
  const selected = section.value.includes(option.value);
568
771
  const rowColor = selected ? onAccentColor : mutedColor;
569
772
  const prevSelected = selected && i > 0 && section.value.includes(section.options[i - 1].value);
570
773
  const nextSelected = selected && i < section.options.length - 1 && section.value.includes(section.options[i + 1].value);
571
- const itemStyle = [styles5.item, selected && { backgroundColor: accentColor }, prevSelected && { borderTopLeftRadius: 0, borderTopRightRadius: 0 }, nextSelected && { borderBottomLeftRadius: 0, borderBottomRightRadius: 0 }];
774
+ const itemStyle = [styles6.item, selected && { backgroundColor: accentColor }, prevSelected && { borderTopLeftRadius: 0, borderTopRightRadius: 0 }, nextSelected && { borderBottomLeftRadius: 0, borderBottomRightRadius: 0 }];
572
775
  const labelStyle = { fontFamily: labelFontFamily, color: rowColor, fontWeight: selected ? "bold" : "normal" };
573
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_feedback_press3.TouchableRipple, { onPress: () => section.onChange(selected ? section.value.filter((v) => v !== option.value) : [...section.value, option.value]), style: itemStyle, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_native8.View, { style: styles5.itemRow, children: [
574
- option.icon && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native_paper3.Icon, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
575
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native_paper3.Text, { variant: "labelLarge", style: [styles5.itemLabelFlex, labelStyle], children: option.label })
776
+ return /* @__PURE__ */ (0, import_jsx_runtime8.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_runtime8.jsxs)(import_react_native9.View, { style: styles6.itemRow, children: [
777
+ option.icon && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native_paper4.Icon, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
778
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native_paper4.Text, { variant: "labelLarge", style: [styles6.itemLabelFlex, labelStyle], children: option.label })
576
779
  ] }) }, option.value);
577
780
  }),
578
- section.allClear && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_feedback_press3.TouchableRipple, { onPress: () => section.onChange(allSelected ? [] : section.options.map((o) => o.value)), style: styles5.item, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native_paper3.Text, { variant: "labelLarge", style: [styles5.allClearLabel, { fontFamily: labelFontFamily, color: accentColor }], children: allSelected ? allClearLabels.clear : allClearLabels.all }) })
781
+ section.allClear && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_feedback_press4.TouchableRipple, { onPress: () => section.onChange(allSelected ? [] : section.options.map((o) => o.value)), style: styles6.item, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native_paper4.Text, { variant: "labelLarge", style: [styles6.allClearLabel, { fontFamily: labelFontFamily, color: accentColor }], children: allSelected ? allClearLabels.clear : allClearLabels.all }) })
579
782
  ] });
580
783
  }
581
- var styles5 = import_react_native8.StyleSheet.create({
784
+ var styles6 = import_react_native9.StyleSheet.create({
582
785
  allClearLabel: {
583
786
  fontWeight: "bold",
584
787
  textAlign: "center"
@@ -595,7 +798,7 @@ var styles5 = import_react_native8.StyleSheet.create({
595
798
  zIndex: 100
596
799
  },
597
800
  divider: {
598
- height: import_react_native8.StyleSheet.hairlineWidth,
801
+ height: import_react_native9.StyleSheet.hairlineWidth,
599
802
  marginVertical: 4
600
803
  },
601
804
  item: {
@@ -643,17 +846,18 @@ var styles5 = import_react_native8.StyleSheet.create({
643
846
  });
644
847
 
645
848
  // src/usePopoverHost.ts
646
- var import_react4 = require("react");
849
+ var import_react5 = require("react");
647
850
  function usePopoverHost() {
648
- const [openId, setOpenId] = (0, import_react4.useState)(null);
649
- const toggle = (0, import_react4.useCallback)((id) => {
851
+ const [openId, setOpenId] = (0, import_react5.useState)(null);
852
+ const toggle = (0, import_react5.useCallback)((id) => {
650
853
  setOpenId((prev) => prev === id ? null : id);
651
854
  }, []);
652
- const close = (0, import_react4.useCallback)(() => setOpenId(null), []);
855
+ const close = (0, import_react5.useCallback)(() => setOpenId(null), []);
653
856
  return { openId, toggle, close };
654
857
  }
655
858
  // Annotate the CommonJS export names for ESM import in node:
656
859
  0 && (module.exports = {
860
+ BaseSettingsDialog,
657
861
  InlineColorPicker,
658
862
  MONO_FONT,
659
863
  PopoverBody,