@buoy-gg/core 7.0.26 → 7.0.28

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.
Files changed (48) hide show
  1. package/bin/buoy.js +6 -0
  2. package/lib/commonjs/floatingMenu/DevToolsSettingsModal.js +532 -1520
  3. package/lib/commonjs/floatingMenu/DevToolsSettingsModal.web.js +541 -566
  4. package/lib/commonjs/floatingMenu/FloatingDevTools.web.js +5 -1
  5. package/lib/commonjs/floatingMenu/ToolHost.js +2 -1
  6. package/lib/commonjs/floatingMenu/autoExternalSync.js +11 -8
  7. package/lib/commonjs/floatingMenu/dial/DialDevTools.js +50 -21
  8. package/lib/commonjs/floatingMenu/dial/DialHyperspace.js +177 -0
  9. package/lib/commonjs/floatingMenu/dial/DialIcon.js +31 -0
  10. package/lib/commonjs/floatingMenu/dial/DialSnow.js +92 -0
  11. package/lib/commonjs/version.js +1 -1
  12. package/lib/module/floatingMenu/DevToolsSettingsModal.js +533 -1524
  13. package/lib/module/floatingMenu/DevToolsSettingsModal.web.js +542 -569
  14. package/lib/module/floatingMenu/FloatingDevTools.web.js +5 -1
  15. package/lib/module/floatingMenu/ToolHost.js +2 -1
  16. package/lib/module/floatingMenu/autoExternalSync.js +11 -8
  17. package/lib/module/floatingMenu/dial/DialDevTools.js +52 -23
  18. package/lib/module/floatingMenu/dial/DialHyperspace.js +173 -0
  19. package/lib/module/floatingMenu/dial/DialIcon.js +33 -1
  20. package/lib/module/floatingMenu/dial/DialSnow.js +90 -0
  21. package/lib/module/version.js +1 -1
  22. package/lib/typescript/commonjs/floatingMenu/DevToolsSettingsModal.d.ts +19 -13
  23. package/lib/typescript/commonjs/floatingMenu/DevToolsSettingsModal.d.ts.map +1 -1
  24. package/lib/typescript/commonjs/floatingMenu/DevToolsSettingsModal.web.d.ts +3 -3
  25. package/lib/typescript/commonjs/floatingMenu/DevToolsSettingsModal.web.d.ts.map +1 -1
  26. package/lib/typescript/commonjs/floatingMenu/FloatingDevTools.web.d.ts.map +1 -1
  27. package/lib/typescript/commonjs/floatingMenu/autoExternalSync.d.ts.map +1 -1
  28. package/lib/typescript/commonjs/floatingMenu/dial/DialDevTools.d.ts.map +1 -1
  29. package/lib/typescript/commonjs/floatingMenu/dial/DialHyperspace.d.ts +24 -0
  30. package/lib/typescript/commonjs/floatingMenu/dial/DialHyperspace.d.ts.map +1 -0
  31. package/lib/typescript/commonjs/floatingMenu/dial/DialIcon.d.ts.map +1 -1
  32. package/lib/typescript/commonjs/floatingMenu/dial/DialSnow.d.ts +23 -0
  33. package/lib/typescript/commonjs/floatingMenu/dial/DialSnow.d.ts.map +1 -0
  34. package/lib/typescript/commonjs/version.d.ts +1 -1
  35. package/lib/typescript/module/floatingMenu/DevToolsSettingsModal.d.ts +19 -13
  36. package/lib/typescript/module/floatingMenu/DevToolsSettingsModal.d.ts.map +1 -1
  37. package/lib/typescript/module/floatingMenu/DevToolsSettingsModal.web.d.ts +3 -3
  38. package/lib/typescript/module/floatingMenu/DevToolsSettingsModal.web.d.ts.map +1 -1
  39. package/lib/typescript/module/floatingMenu/FloatingDevTools.web.d.ts.map +1 -1
  40. package/lib/typescript/module/floatingMenu/autoExternalSync.d.ts.map +1 -1
  41. package/lib/typescript/module/floatingMenu/dial/DialDevTools.d.ts.map +1 -1
  42. package/lib/typescript/module/floatingMenu/dial/DialHyperspace.d.ts +24 -0
  43. package/lib/typescript/module/floatingMenu/dial/DialHyperspace.d.ts.map +1 -0
  44. package/lib/typescript/module/floatingMenu/dial/DialIcon.d.ts.map +1 -1
  45. package/lib/typescript/module/floatingMenu/dial/DialSnow.d.ts +23 -0
  46. package/lib/typescript/module/floatingMenu/dial/DialSnow.d.ts.map +1 -0
  47. package/lib/typescript/module/version.d.ts +1 -1
  48. package/package.json +5 -5
@@ -237,7 +237,11 @@ function FloatingDevToolsInner({
237
237
  id: tool.id,
238
238
  name: tool.name || getToolLabel(tool.id),
239
239
  description: tool.description || getToolDescription(tool.id),
240
- slot: tool.slot
240
+ slot: tool.slot,
241
+ // Settings rows fall back to the tool's own icon when the modal has
242
+ // no hardcoded glyph for it (mirrors native DialDevTools).
243
+ icon: tool.icon,
244
+ color: tool.color
241
245
  })), [tools]);
242
246
 
243
247
  // Welcome tooltip — native FloatingMenu.tsx:134-157: 1000ms after mount,
@@ -233,7 +233,8 @@ const styles = StyleSheet.create({
233
233
  bodyRoot: {
234
234
  flex: 1,
235
235
  minHeight: 0,
236
- backgroundColor: buoyColors.base
236
+ // Transparent so JsModal's ToolBackground shows through (the modal paints opaque base beneath it).
237
+ backgroundColor: "transparent"
237
238
  },
238
239
  toast: {
239
240
  position: "absolute",
@@ -40,7 +40,6 @@ let zustandModule = null;
40
40
  let jotaiModule = null;
41
41
  let eventsModule = null;
42
42
  let consoleModule = null;
43
- let timeMachineModule = null;
44
43
  let envModule = null;
45
44
  let highlightUpdatesModule = null;
46
45
  let debugBordersModule = null;
@@ -104,11 +103,6 @@ try {
104
103
  } catch (e) {
105
104
  reportOptionalRequireError("@buoy-gg/console", e);
106
105
  }
107
- try {
108
- timeMachineModule = require("@buoy-gg/time-machine");
109
- } catch (e) {
110
- reportOptionalRequireError("@buoy-gg/time-machine", e);
111
- }
112
106
  try {
113
107
  envModule = require("@buoy-gg/env");
114
108
  } catch (e) {
@@ -268,8 +262,17 @@ export function AutoExternalSync({
268
262
  if (consoleModule?.consoleSyncAdapter) {
269
263
  map.console = consoleModule.consoleSyncAdapter;
270
264
  }
271
- if (timeMachineModule?.timeMachineSyncAdapter) {
272
- map["time-machine"] = timeMachineModule.timeMachineSyncAdapter;
265
+ // Lazy: time-machine imports `@buoy-gg/core` (useToolHost), and this file
266
+ // is loaded from core's index. Requiring it at module top-level is a
267
+ // require cycle (LogBox on every reload). Waiting until first render
268
+ // lets core finish evaluating first.
269
+ try {
270
+ const timeMachineModule = require("@buoy-gg/time-machine");
271
+ if (timeMachineModule?.timeMachineSyncAdapter) {
272
+ map["time-machine"] = timeMachineModule.timeMachineSyncAdapter;
273
+ }
274
+ } catch (e) {
275
+ reportOptionalRequireError("@buoy-gg/time-machine", e);
273
276
  }
274
277
  if (envModule?.createEnvSyncAdapter) {
275
278
  map.env = envModule.createEnvSyncAdapter(requiredEnvVars ?? []);
@@ -1,14 +1,15 @@
1
1
  "use strict";
2
2
 
3
3
  import { useEffect, useMemo, useRef, useState } from "react";
4
- import { Pressable, StyleSheet, View, useWindowDimensions, Text, Animated, Easing } from "react-native";
4
+ import { Pressable, StyleSheet, TouchableOpacity, View, useWindowDimensions, Text, Animated, Easing } from "react-native";
5
5
  import { absoluteFill } from "@buoy-gg/shared-ui";
6
6
  // Icons are provided by installedApps; no direct icon imports here.
7
7
  import { DialIcon } from "./DialIcon.js";
8
+ import { DialHyperspace } from "./DialHyperspace.js";
8
9
  import { ALL_TOOLS_REGISTRY } from "../allToolsRegistry.js";
9
10
  import { DialPagination } from "./DialPagination.js";
10
11
  import { getRankedToolIds, isDialUsageLoaded, loadDialUsage, recordToolUsage } from "./dialUsageStore.js";
11
- import { persistentStorage, useHintsDisabled, devToolsStorageKeys, buoyColors } from "@buoy-gg/shared-ui";
12
+ import { persistentStorage, useHintsDisabled, devToolsStorageKeys, buoyColors, ToolBackground, useToolBackground } from "@buoy-gg/shared-ui";
12
13
  import { DevToolsSettingsModal, useDevToolsSettings } from "../DevToolsSettingsModal";
13
14
  import { useProAccess } from "@buoy-gg/license";
14
15
  import { renderAppIcon } from "../AppIcon.js";
@@ -21,6 +22,19 @@ import { getDialLayout, MAX_DIAL_SLOTS, DIAL_BUTTON_SIZE, DIAL_ICON_GLYPH_SIZE,
21
22
  // snapshot goes stale when the window resizes after load (web/desktop).
22
23
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
23
24
  const BUTTON_SIZE = DIAL_BUTTON_SIZE;
25
+
26
+ /**
27
+ * The centre button's idle pulse, off by design.
28
+ *
29
+ * It is built as `Animated.loop(Animated.sequence([...]))`, and that pairing is
30
+ * NOT handed to the native driver even though every child sets
31
+ * `useNativeDriver: true` — so it ticked on the JS thread for as long as the
32
+ * dial stayed open, taxing every interaction launched from the dial.
33
+ *
34
+ * Re-enabling it means rewriting the loop so it genuinely runs natively;
35
+ * flipping this alone just puts the JS-thread cost back.
36
+ */
37
+ const DIAL_IDLE_PULSE = false;
24
38
  const ONBOARDING_STORAGE_KEY = "@react_buoy_settings_tooltip_shown";
25
39
  /** A non-interactive placeholder used to fill out the last dial page. */
26
40
  const createEmptySlot = slotIndex => ({
@@ -64,6 +78,11 @@ export const DialDevTools = ({
64
78
  const circleSize = getDialLayout({
65
79
  screenWidth
66
80
  }).circleSize;
81
+ // The dial face shows the same backdrop the tools use (persisted shared
82
+ // selection). Hyperspace keeps its hand-tuned dial port below.
83
+ const {
84
+ id: backgroundId
85
+ } = useToolBackground();
67
86
  const sizeStyles = useMemo(() => ({
68
87
  parent: {
69
88
  width: circleSize,
@@ -150,16 +169,35 @@ export const DialDevTools = ({
150
169
  id,
151
170
  name,
152
171
  slot,
153
- description
172
+ description,
173
+ icon,
174
+ color
154
175
  }) => ({
155
176
  id,
156
177
  name,
157
178
  slot,
158
- description
179
+ description,
180
+ // Settings rows fall back to the app's own icon when the modal has no
181
+ // hardcoded glyph for the tool.
182
+ icon,
183
+ color
159
184
  })), [apps]);
160
185
 
161
186
  // Animation tracking refs
162
187
  const pulseAnimationRef = useRef(null);
188
+ const toggleSettingsModal = () => {
189
+ if (isSettingsModalOpen) {
190
+ setIsSettingsModalOpen(false);
191
+ return;
192
+ }
193
+ setIsSettingsModalOpen(true);
194
+ // Dismiss onboarding tooltip when user opens settings
195
+ if (showOnboardingTooltip && !onboardingDismissedRef.current) {
196
+ handleOnboardingDismiss();
197
+ }
198
+ // Also call external handler if provided
199
+ onSettingsPress?.();
200
+ };
163
201
 
164
202
  // Dial-eligible apps: everything except row-only tools. All of them are
165
203
  // shown — paginated across pages of MAX_DIAL_SLOTS — so there is no longer
@@ -407,6 +445,7 @@ export const DialDevTools = ({
407
445
  })]).start();
408
446
 
409
447
  // Pulse animation - only continuous effect kept for performance
448
+ if (!DIAL_IDLE_PULSE) return;
410
449
  pulseAnimationRef.current = Animated.loop(Animated.sequence([Animated.timing(pulseScale, {
411
450
  toValue: continuous.pulse.maxScale,
412
451
  duration: continuous.pulse.duration,
@@ -595,7 +634,9 @@ export const DialDevTools = ({
595
634
  }]
596
635
  }]
597
636
  }, i))
598
- })]
637
+ }), backgroundId === "hyperspace" ? /*#__PURE__*/_jsx(DialHyperspace, {
638
+ size: circleSize
639
+ }) : /*#__PURE__*/_jsx(ToolBackground, {})]
599
640
  }), allDialIcons.filter(({
600
641
  page
601
642
  }) => page === safePage).map(({
@@ -630,26 +671,14 @@ export const DialDevTools = ({
630
671
  style: styles.buttonBorder,
631
672
  children: /*#__PURE__*/_jsx(Animated.View, {
632
673
  style: [styles.button, pulseAnimatedStyle],
633
- children: /*#__PURE__*/_jsx(Pressable, {
674
+ children: /*#__PURE__*/_jsx(TouchableOpacity, {
634
675
  accessibilityRole: "button",
635
676
  accessibilityLabel: isSettingsModalOpen ? "Close Settings" : "Open Dev Tools Settings",
636
- onPress: () => {
637
- if (isSettingsModalOpen) {
638
- // Close settings modal
639
- setIsSettingsModalOpen(false);
640
- } else {
641
- // Open internal settings modal
642
- setIsSettingsModalOpen(true);
643
- // Dismiss onboarding tooltip when user opens settings
644
- if (showOnboardingTooltip && !onboardingDismissedRef.current) {
645
- handleOnboardingDismiss();
646
- }
647
- // Also call external handler if provided
648
- if (onSettingsPress) {
649
- onSettingsPress();
650
- }
651
- }
652
- },
677
+ onPress: toggleSettingsModal
678
+ // Dims on touch-down so the press registers visually straight
679
+ // away, even though the panel only opens on release.
680
+ ,
681
+ activeOpacity: 0.5,
653
682
  style: styles.buttonPressable,
654
683
  children: isSettingsModalOpen ? /*#__PURE__*/_jsxs(_Fragment, {
655
684
  children: [/*#__PURE__*/_jsx(Text, {
@@ -0,0 +1,173 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * DialHyperspace — the Hyperspace backdrop's lightspeed starfield, scaled
5
+ * down to live inside the open dial's face. Replaces DialSnow (kept next
6
+ * door for an easy swap back) so the dial matches the tool background.
7
+ *
8
+ * Same construction as the full preset (shared-ui
9
+ * `backgrounds/variants/hyperspace.tsx`, see its header for the derivation):
10
+ * the Skia original's per-frame `screen = plane/z` projection becomes scale
11
+ * keyframes on phase-offset shells — a layer scaled by 1/z moves every star
12
+ * outward on the true hyperbolic curve — with each shell's wrap snap hidden
13
+ * inside the fade the original applies to the first/last 6% of a star's
14
+ * life. Dial tuning: fewer stars, a slightly gentler cycle and lower alpha
15
+ * so the field reads behind the icons instead of competing with them.
16
+ * Stars are round crisp points, as in the original — never streaks.
17
+ *
18
+ * Cost while the dial is open: 1 animated node, ~48 static views — the same
19
+ * budget DialSnow ran. The dial is fixed-size (never user-resized), so
20
+ * sizing geometry from the passed circle size is correct here, and the
21
+ * circle's `overflow: "hidden"` clips the streaks.
22
+ */
23
+
24
+ import { memo } from "react";
25
+ import { Animated, View } from "react-native";
26
+ import { RasterLayer, scatter, useLoop, withBgAlpha } from "@buoy-gg/shared-ui";
27
+ import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
28
+ const Z_SPAN = 0.94;
29
+ const MAX_SCALE = 6;
30
+ const CYCLE_MS = 2400;
31
+ const SHELLS = 3;
32
+ const STARS_PER_SHELL = 16;
33
+ /** Stride 4: angle, radius, size jitter, palette pick — fixed seeds so the
34
+ * field is identical every open. */
35
+ const SHELL_TABLES = Array.from({
36
+ length: SHELLS
37
+ }, (_, k) => scatter(0x5747 ^ k * 0x9e37, STARS_PER_SHELL * 4));
38
+ const STAR_COLORS = ["#FFFFFF", "#B3D9FF", "#8CB3FF"];
39
+
40
+ /** The dial face draws 6 grid spokes, one every 60° starting at 0°. Star
41
+ * motion is radial (uniform scale about the centre), so a star whose angle
42
+ * sits near a spoke rides that line for its entire life. Remap the uniform
43
+ * angle pick into the clear wedge between spokes, leaving `SPOKE_GAP` of
44
+ * clearance centred on each line. */
45
+ const SPOKE_STEP = Math.PI / 3;
46
+ const SPOKE_GAP = 14 * Math.PI / 180;
47
+ function spokeClearAngle(u) {
48
+ const sector = Math.min(5, Math.floor(u * 6));
49
+ const t = u * 6 - sector;
50
+ return sector * SPOKE_STEP + SPOKE_GAP / 2 + t * (SPOKE_STEP - SPOKE_GAP);
51
+ }
52
+ function scaleAt(p) {
53
+ return Math.min(MAX_SCALE, 1 / (1 - p * Z_SPAN));
54
+ }
55
+ function opacityAt(p) {
56
+ let bright = 0.15 + 0.85 * p * p;
57
+ // The original's 6% fade at both ends of a star's life.
58
+ if (p < 0.06) bright *= p / 0.06;else if (p > 0.94) bright *= (1 - p) / 0.06;
59
+ // Dial tuning: never brighter than 0.7 — the icons own the foreground.
60
+ return Math.min(0.7, bright);
61
+ }
62
+
63
+ /** Interpolate stops for shell k (phase = (v + k/K) mod 1), the wrap point
64
+ * double-sampled 1e-4 apart inside the zero-opacity sliver. */
65
+ function shellStops(k) {
66
+ const offset = k / SHELLS;
67
+ const vs = [];
68
+ const SEGMENTS = 12;
69
+ for (let i = 0; i <= SEGMENTS; i++) vs.push(i / SEGMENTS);
70
+ const vWrap = (1 - offset) % 1;
71
+ if (vWrap > 1e-3 && vWrap < 1 - 1e-3) vs.push(vWrap - 1e-4, vWrap + 1e-4);
72
+ vs.sort((a, b) => a - b);
73
+ const input = [];
74
+ const scale = [];
75
+ const opacity = [];
76
+ for (const v of vs) {
77
+ // At the loop boundary the offset-0 shell's phase must read as END of
78
+ // life (p=1, max scale, zero opacity), not wrap to 0 — otherwise the
79
+ // last segment lerps scale 6→1 at visible opacity and the stars
80
+ // retract to the centre once per cycle.
81
+ const p = offset === 0 && v === 1 ? 1 : (v + offset) % 1;
82
+ input.push(v);
83
+ scale.push(scaleAt(p));
84
+ opacity.push(opacityAt(p));
85
+ }
86
+ return {
87
+ input,
88
+ scale,
89
+ opacity
90
+ };
91
+ }
92
+ const SHELL_STOPS = Array.from({
93
+ length: SHELLS
94
+ }, (_, k) => shellStops(k));
95
+ export const DialHyperspace = /*#__PURE__*/memo(function DialHyperspace({
96
+ size
97
+ }) {
98
+ const drive = useLoop(CYCLE_MS);
99
+ const c = size / 2;
100
+ const shells = [];
101
+ for (let k = 0; k < SHELLS; k++) {
102
+ const table = SHELL_TABLES[k];
103
+ const stops = SHELL_STOPS[k];
104
+ const stars = [];
105
+ for (let i = 0; i < STARS_PER_SHELL; i++) {
106
+ const ang = spokeClearAngle(table[i * 4]);
107
+ // sqrt-biased outward, inner 15% clear of the vanishing point. Offsets
108
+ // scale with the HALF-extent, as in the original's projection.
109
+ const rad = (0.15 + 0.85 * Math.sqrt(table[i * 4 + 1])) * 0.5 * c;
110
+ const color = STAR_COLORS[Math.floor(table[i * 4 + 3] * STAR_COLORS.length) % 3];
111
+ const x = c + Math.cos(ang) * rad;
112
+ const y = c + Math.sin(ang) * rad;
113
+ // Round crisp points, as in the original — the visible star is the
114
+ // sprite's lit core (~12.5% of the stamp), so it starts sub-pixel and
115
+ // only reaches ~2-3px before the fade-out kills it. A soft halo disc
116
+ // at α0.3 stands in for the sprite's blur.
117
+ const core = 0.6;
118
+ const halo = core * 2.4;
119
+ stars.push(/*#__PURE__*/_jsx(View, {
120
+ style: {
121
+ position: "absolute",
122
+ left: x - halo / 2,
123
+ top: y - halo / 2,
124
+ width: halo,
125
+ height: halo,
126
+ borderRadius: halo / 2,
127
+ backgroundColor: withBgAlpha(color, 0.3)
128
+ }
129
+ }, `${i}-h`), /*#__PURE__*/_jsx(View, {
130
+ style: {
131
+ position: "absolute",
132
+ left: x - core / 2,
133
+ top: y - core / 2,
134
+ width: core,
135
+ height: core,
136
+ borderRadius: core / 2,
137
+ backgroundColor: color
138
+ }
139
+ }, i));
140
+ }
141
+ shells.push(/*#__PURE__*/_jsx(Animated.View, {
142
+ style: {
143
+ position: "absolute",
144
+ left: 0,
145
+ top: 0,
146
+ width: size,
147
+ height: size,
148
+ opacity: drive.interpolate({
149
+ inputRange: stops.input,
150
+ outputRange: stops.opacity
151
+ }),
152
+ transform: [{
153
+ scale: drive.interpolate({
154
+ inputRange: stops.input,
155
+ outputRange: stops.scale
156
+ })
157
+ }]
158
+ },
159
+ pointerEvents: "none",
160
+ children: /*#__PURE__*/_jsx(RasterLayer, {
161
+ style: {
162
+ width: size,
163
+ height: size
164
+ },
165
+ raster: false,
166
+ children: stars
167
+ })
168
+ }, k));
169
+ }
170
+ return /*#__PURE__*/_jsx(_Fragment, {
171
+ children: shells
172
+ });
173
+ });
@@ -4,9 +4,38 @@ import { useMemo, useRef } from "react";
4
4
  import { StyleSheet, Pressable, View, Text, useWindowDimensions, Animated } from "react-native";
5
5
  import { getDialLayout, getIconPosition, getIconStaggerInputRange, DIAL_START_ANGLE, DIAL_ICON_SIZE, DIAL_ICON_GLYPH_SIZE, dialColors, dialStyles, dialAnimationConfig, floatingToolsColors } from "@buoy-gg/floating-tools-core";
6
6
 
7
+ /** Full names agents wait for (`waitFor: "Network"`), not the truncated glyph. */
8
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
9
+ const DIAL_A11Y = {
10
+ network: "Network",
11
+ images: "Images",
12
+ "image-overlay": "Image Overlay",
13
+ assets: "Assets",
14
+ query: "React Query",
15
+ storage: "Storage",
16
+ env: "Env",
17
+ console: "Console",
18
+ events: "Events",
19
+ redux: "Redux",
20
+ zustand: "Zustand",
21
+ jotai: "Jotai",
22
+ "route-events": "Routes",
23
+ "time-machine": "Time Machine",
24
+ "highlight-updates": "Highlight Updates",
25
+ "debug-borders": "Debug Borders",
26
+ "perf-monitor": "Perf Monitor",
27
+ "js-top": "JS Top",
28
+ "js-top-modal": "JS Top",
29
+ impersonate: "Impersonate",
30
+ "perf-monitor-modal": "Perf Monitor"
31
+ };
32
+ function dialAccessibilityLabel(id, name) {
33
+ if (id && DIAL_A11Y[id]) return DIAL_A11Y[id];
34
+ return name;
35
+ }
36
+
7
37
  // The circle radius depends on the live window width and is computed inside
8
38
  // the component (must match DialDevTools' circle, which does the same).
9
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
10
39
  const VIEW_SIZE = DIAL_ICON_SIZE;
11
40
  export const DialIcon = ({
12
41
  index,
@@ -188,6 +217,9 @@ export const DialIcon = ({
188
217
  onPressIn: handlePressIn,
189
218
  onPressOut: handlePressOut,
190
219
  style: styles.pressable,
220
+ testID: icon.id ? `buoy-dial-${icon.id}` : undefined,
221
+ accessibilityLabel: dialAccessibilityLabel(icon.id, icon.name),
222
+ accessibilityRole: "button",
191
223
  children: [/*#__PURE__*/_jsx(View, {
192
224
  style: [styles.iconGradientBg, {
193
225
  backgroundColor: "rgba(0, 0, 0, 0.2)"
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * DialSnow — pale particles drifting down inside the open dial's face, built
5
+ * from the shared background primitives (packages/shared/src/ui/backgrounds).
6
+ *
7
+ * Same performance contract as the backgrounds: the loop is native-driven
8
+ * (useLoop hands the whole animation to the UI thread once — zero JS work per
9
+ * frame), the flakes are one rasterized texture, and the scatter table is
10
+ * generated at module load. Cost while the dial is open: 1 animated node and
11
+ * ~24 static views, mounted only for the dial's lifetime.
12
+ *
13
+ * Rendered inside the circle's `overflow: "hidden"` background. The dial is
14
+ * fixed-size (never user-resized), so sizing geometry from the passed circle
15
+ * size is correct here.
16
+ */
17
+
18
+ import { memo } from "react";
19
+ import { Animated, View } from "react-native";
20
+ import { RasterLayer, scatter, useLoop, withBgAlpha } from "@buoy-gg/shared-ui";
21
+
22
+ /** Pale mint-ice flake tint — sits quietly on the dial's dark face. */
23
+ import { jsx as _jsx } from "react/jsx-runtime";
24
+ const SNOW_COLOR = "#A8E0D2";
25
+
26
+ /** Stride 3: x, y, size — fixed seed so the flurry is identical every open. */
27
+ const SNOW_COUNT = 12;
28
+ const SNOW_TABLE = scatter(0x5ea1, SNOW_COUNT * 3);
29
+
30
+ /**
31
+ * The two-copy tiling trick from the backdrops: everything drawn twice one
32
+ * height apart, translated a full height per loop, so the seam never shows.
33
+ * Sway is keyframed onto the SAME loop value.
34
+ */
35
+ export const DialSnow = /*#__PURE__*/memo(function DialSnow({
36
+ size
37
+ }) {
38
+ const t = useLoop(26000);
39
+ const translateY = t.interpolate({
40
+ inputRange: [0, 1],
41
+ outputRange: [0, size]
42
+ });
43
+ const translateX = t.interpolate({
44
+ inputRange: [0, 0.25, 0.5, 0.75, 1],
45
+ outputRange: [0, 5, 0, -5, 0]
46
+ });
47
+ const flakes = [];
48
+ for (let i = 0; i < SNOW_COUNT; i++) {
49
+ const x = SNOW_TABLE[i * 3] * size;
50
+ const y = SNOW_TABLE[i * 3 + 1] * size;
51
+ // Bigger flakes read nearer, so they get more alpha too.
52
+ const dia = 1.4 + SNOW_TABLE[i * 3 + 2] * 1.2;
53
+ const alpha = 0.28 + SNOW_TABLE[i * 3 + 2] * 0.18;
54
+ for (let copy = 0; copy < 2; copy++) {
55
+ flakes.push(/*#__PURE__*/_jsx(View, {
56
+ style: {
57
+ position: "absolute",
58
+ left: x - dia / 2,
59
+ top: y + copy * size - dia / 2,
60
+ width: dia,
61
+ height: dia,
62
+ borderRadius: dia / 2,
63
+ backgroundColor: withBgAlpha(SNOW_COLOR, alpha)
64
+ }
65
+ }, `${i}-${copy}`));
66
+ }
67
+ }
68
+ return /*#__PURE__*/_jsx(Animated.View, {
69
+ style: {
70
+ position: "absolute",
71
+ left: 0,
72
+ top: -size,
73
+ width: size,
74
+ height: size * 2,
75
+ transform: [{
76
+ translateY
77
+ }, {
78
+ translateX
79
+ }]
80
+ },
81
+ pointerEvents: "none",
82
+ children: /*#__PURE__*/_jsx(RasterLayer, {
83
+ style: {
84
+ width: size,
85
+ height: size * 2
86
+ },
87
+ children: flakes
88
+ })
89
+ });
90
+ });
@@ -11,4 +11,4 @@
11
11
  * Drift is prevented by a test that fails when this disagrees with
12
12
  * package.json, so a version bump that forgets this file cannot ship.
13
13
  */
14
- export const SDK_VERSION = "7.0.26";
14
+ export const SDK_VERSION = "7.0.28";
@@ -1,4 +1,5 @@
1
1
  import { FC } from "react";
2
+ import type { InstalledApp } from "./types";
2
3
  /**
3
4
  * Global settings that apply to all dev tools.
4
5
  * These settings override individual tool configurations.
@@ -30,30 +31,35 @@ export interface DevToolsSettings {
30
31
  /** Global settings that apply to all dev tools */
31
32
  globalSettings?: GlobalDevToolsSettings;
32
33
  }
34
+ /**
35
+ * The subset of InstalledApp the settings modal needs per tool. `icon`/`color`
36
+ * let rows fall back to the tool's own glyph when getToolIcon() has no
37
+ * night-tuned override for it.
38
+ */
39
+ interface SettingsToolInfo {
40
+ id: string;
41
+ name: string;
42
+ description?: string;
43
+ slot?: "dial" | "row" | "both";
44
+ icon?: InstalledApp["icon"];
45
+ color?: string;
46
+ }
33
47
  interface DevToolsSettingsModalProps {
34
48
  visible: boolean;
35
49
  onClose: () => void;
36
50
  onSettingsChange?: (settings: DevToolsSettings) => void;
37
51
  initialSettings?: DevToolsSettings;
38
- availableApps?: {
39
- id: string;
40
- name: string;
41
- description?: string;
42
- slot?: "dial" | "row" | "both";
43
- }[];
52
+ availableApps?: SettingsToolInfo[];
44
53
  }
45
54
  /**
46
55
  * Configurable modal surface that lets engineers pick which dev tools appear in the dial and
47
56
  * floating row. Persists preferences and enforces slot limits for a consistent UX.
48
- */
49
- export declare const DevToolsSettingsModal: FC<DevToolsSettingsModalProps>;
50
- /**
51
- * Convenience hook for accessing persisted dev tools settings. Subscribes to the internal
52
- * event bus so all surfaces stay in sync when the modal saves new preferences.
53
57
  *
54
- * When no saved settings exist, the hook uses the default configuration from
55
- * the DefaultConfigProvider (if available) to determine initial tool states.
58
+ * Styled in the "night" language (Everlights port — see shared-ui's
59
+ * ui/night): section labels outside near-black cards, hairline-separated
60
+ * rows, real switches, and a transparent header the star field runs through.
56
61
  */
62
+ export declare const DevToolsSettingsModal: FC<DevToolsSettingsModalProps>;
57
63
  export declare const useDevToolsSettings: () => {
58
64
  settings: DevToolsSettings;
59
65
  refreshSettings: () => void;
@@ -1 +1 @@
1
- {"version":3,"file":"DevToolsSettingsModal.d.ts","sourceRoot":"","sources":["../../../../src/floatingMenu/DevToolsSettingsModal.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA6C,EAAE,EAAE,MAAM,OAAO,CAAC;AAuJtE;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;;OAIG;IACH,2BAA2B,CAAC,EAAE,OAAO,CAAC;IACtC;;;OAGG;IACH,wBAAwB,CAAC,EAAE,OAAO,CAAC;CACpC;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,4EAA4E;IAC5E,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,uFAAuF;IACvF,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;QACvC,WAAW,EAAE,OAAO,CAAC;KACtB,CAAC;IACF,kDAAkD;IAClD,cAAc,CAAC,EAAE,sBAAsB,CAAC;CACzC;AAED,UAAU,0BAA0B;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACxD,eAAe,CAAC,EAAE,gBAAgB,CAAC;IACnC,aAAa,CAAC,EAAE;QACd,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,IAAI,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;KAChC,EAAE,CAAC;CACL;AA2DD;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAE,EAAE,CAAC,0BAA0B,CAwiChE,CAAC;AAwDF;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB;;;CAuD/B,CAAC"}
1
+ {"version":3,"file":"DevToolsSettingsModal.d.ts","sourceRoot":"","sources":["../../../../src/floatingMenu/DevToolsSettingsModal.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA6C,EAAE,EAAa,MAAM,OAAO,CAAC;AA0CjF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AA6G5C;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;;OAIG;IACH,2BAA2B,CAAC,EAAE,OAAO,CAAC;IACtC;;;OAGG;IACH,wBAAwB,CAAC,EAAE,OAAO,CAAC;CACpC;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,4EAA4E;IAC5E,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,uFAAuF;IACvF,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;QACvC,WAAW,EAAE,OAAO,CAAC;KACtB,CAAC;IACF,kDAAkD;IAClD,cAAc,CAAC,EAAE,sBAAsB,CAAC;CACzC;AAED;;;;GAIG;AACH,UAAU,gBAAgB;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;IAC/B,IAAI,CAAC,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,0BAA0B;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACxD,eAAe,CAAC,EAAE,gBAAgB,CAAC;IACnC,aAAa,CAAC,EAAE,gBAAgB,EAAE,CAAC;CACpC;AAsDD;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,EAAE,EAAE,CAAC,0BAA0B,CAwxBhE,CAAC;AA8FF,eAAO,MAAM,mBAAmB;;;CAuD/B,CAAC"}
@@ -6,9 +6,9 @@
6
6
  *
7
7
  * VISUAL PARITY: styled 1:1 against the native reference
8
8
  * (devtools-floating-menu/src/floatingMenu/DevToolsSettingsModal.tsx, which
9
- * renders inside JsModal + ModalHeader + TabSelector from @buoy-gg/shared-ui).
10
- * shared-ui is RN-only, so its buoyColors palette and the native-only style
11
- * values are inlined below with provenance comments.
9
+ * renders in the "night" language — shared-ui's ui/night Everlights port —
10
+ * inside JsModal variant="night"). shared-ui is RN-only, so the night tokens
11
+ * and primitive styles are inlined below with provenance comments.
12
12
  *
13
13
  * @platform React DOM Web (Vite, CRA, Next.js, Electron)
14
14
  */
@@ -1 +1 @@
1
- {"version":3,"file":"DevToolsSettingsModal.web.d.ts","sourceRoot":"","sources":["../../../../src/floatingMenu/DevToolsSettingsModal.web.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,EAaL,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EAEpB,MAAM,+BAA+B,CAAC;AA6DvC,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,cAAc,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACvC,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,CAAC;CACzD;AAqdD,wBAAgB,aAAa,CAAC,EAC5B,OAAO,EACP,OAAO,EACP,cAAmB,EACnB,oBAAoB,EACpB,gBAAgB,EAChB,OAA2B,EAC3B,gBAAgB,GACjB,EAAE,kBAAkB,sCAoapB"}
1
+ {"version":3,"file":"DevToolsSettingsModal.web.d.ts","sourceRoot":"","sources":["../../../../src/floatingMenu/DevToolsSettingsModal.web.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,EAWL,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EAEpB,MAAM,+BAA+B,CAAC;AAyEvC,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,cAAc,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACvC,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,CAAC;CACzD;AAshBD,wBAAgB,aAAa,CAAC,EAC5B,OAAO,EACP,OAAO,EACP,cAAmB,EACnB,oBAAoB,EACpB,gBAAgB,EAChB,OAA2B,EAC3B,gBAAgB,GACjB,EAAE,kBAAkB,sCAkXpB"}
@@ -1 +1 @@
1
- {"version":3,"file":"FloatingDevTools.web.d.ts","sourceRoot":"","sources":["../../../../src/floatingMenu/FloatingDevTools.web.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,QAAQ,EAId,MAAM,+BAA+B,CAAC;AA+BvC,MAAM,WAAW,qBAAqB;IAEpC,0DAA0D;IAC1D,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,gDAAgD;IAChD,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,2CAA2C;IAC3C,qBAAqB,CAAC,EAAE,WAAW,EAAE,CAAC;IACtC,4CAA4C;IAC5C,mBAAmB,CAAC,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,IAAI,CAAC;IAGjD,gEAAgE;IAChE,IAAI,CAAC,EAAE,aAAa,EAAE,CAAC;IAEvB,kCAAkC;IAClC,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAmCD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,+BAQ5D;AAiWD,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC"}
1
+ {"version":3,"file":"FloatingDevTools.web.d.ts","sourceRoot":"","sources":["../../../../src/floatingMenu/FloatingDevTools.web.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,QAAQ,EAId,MAAM,+BAA+B,CAAC;AA+BvC,MAAM,WAAW,qBAAqB;IAEpC,0DAA0D;IAC1D,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,gDAAgD;IAChD,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,2CAA2C;IAC3C,qBAAqB,CAAC,EAAE,WAAW,EAAE,CAAC;IACtC,4CAA4C;IAC5C,mBAAmB,CAAC,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,IAAI,CAAC;IAGjD,gEAAgE;IAChE,IAAI,CAAC,EAAE,aAAa,EAAE,CAAC;IAEvB,kCAAkC;IAClC,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAmCD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,+BAQ5D;AAqWD,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"autoExternalSync.d.ts","sourceRoot":"","sources":["../../../../src/floatingMenu/autoExternalSync.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AA4IjD,iFAAiF;AACjF,wBAAgB,uBAAuB,IAAI,OAAO,CAEjD;AAED,MAAM,WAAW,mBAAmB;IAClC;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2EAA2E;IAC3E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;;;;;;;;;;;;OAiBG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,qBAAqB;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAuBD,UAAU,qBAAqB;IAC7B,OAAO,CAAC,EAAE,mBAAmB,CAAC;IAC9B,6EAA6E;IAC7E,eAAe,CAAC,EAAE,YAAY,EAAE,CAAC;IACjC,8EAA8E;IAC9E,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;OAIG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,mEAAmE;IACnE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B;;;;OAIG;IACH,UAAU,CAAC,EAAE,YAAY,EAAE,CAAC;CAC7B;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,OAAO,EACP,eAAe,EACf,KAAK,EACL,IAAI,EACJ,UAAU,EACV,UAAU,GACX,EAAE,qBAAqB,QAsIvB"}
1
+ {"version":3,"file":"autoExternalSync.d.ts","sourceRoot":"","sources":["../../../../src/floatingMenu/autoExternalSync.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAsIjD,iFAAiF;AACjF,wBAAgB,uBAAuB,IAAI,OAAO,CAEjD;AAED,MAAM,WAAW,mBAAmB;IAClC;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2EAA2E;IAC3E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;;;;;;;;;;;;OAiBG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,qBAAqB;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAuBD,UAAU,qBAAqB;IAC7B,OAAO,CAAC,EAAE,mBAAmB,CAAC;IAC9B,6EAA6E;IAC7E,eAAe,CAAC,EAAE,YAAY,EAAE,CAAC;IACjC,8EAA8E;IAC9E,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;OAIG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,mEAAmE;IACnE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B;;;;OAIG;IACH,UAAU,CAAC,EAAE,YAAY,EAAE,CAAC;CAC7B;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,OAAO,EACP,eAAe,EACf,KAAK,EACL,IAAI,EACJ,UAAU,EACV,UAAU,GACX,EAAE,qBAAqB,QA+IvB"}
@@ -1 +1 @@
1
- {"version":3,"file":"DialDevTools.d.ts","sourceRoot":"","sources":["../../../../../src/floatingMenu/dial/DialDevTools.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAwC,SAAS,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAgC5E,OAAO,KAAK,EACV,YAAY,EACZ,mBAAmB,EACnB,iBAAiB,EAClB,MAAM,UAAU,CAAC;AAsBlB,MAAM,MAAM,QAAQ,GAAG;IACrB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;IAChB;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,iBAAiB,CAAC;QAAC,OAAO,CAAC,EAAE,mBAAmB,CAAA;KAAE,KAAK,SAAS,CAAC;IAC/H,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAWF,UAAU,iBAAiB;IACzB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,IAAI,CAAC;IAC7B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,IAAI,EAAE,YAAY,EAAE,CAAC;IACrB,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAC1B,OAAO,CAAC,EAAE,mBAAmB,CAAC;CAC/B;AAED,eAAO,MAAM,YAAY,EAAE,EAAE,CAAC,iBAAiB,CAgsB9C,CAAC"}
1
+ {"version":3,"file":"DialDevTools.d.ts","sourceRoot":"","sources":["../../../../../src/floatingMenu/dial/DialDevTools.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAwC,SAAS,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAoC5E,OAAO,KAAK,EACV,YAAY,EACZ,mBAAmB,EACnB,iBAAiB,EAClB,MAAM,UAAU,CAAC;AAmClB,MAAM,MAAM,QAAQ,GAAG;IACrB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;IAChB;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,iBAAiB,CAAC;QAAC,OAAO,CAAC,EAAE,mBAAmB,CAAA;KAAE,KAAK,SAAS,CAAC;IAC/H,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAWF,UAAU,iBAAiB;IACzB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,IAAI,CAAC;IAC7B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,IAAI,EAAE,YAAY,EAAE,CAAC;IACrB,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAC1B,OAAO,CAAC,EAAE,mBAAmB,CAAC;CAC/B;AAED,eAAO,MAAM,YAAY,EAAE,EAAE,CAAC,iBAAiB,CAitB9C,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * DialHyperspace — the Hyperspace backdrop's lightspeed starfield, scaled
3
+ * down to live inside the open dial's face. Replaces DialSnow (kept next
4
+ * door for an easy swap back) so the dial matches the tool background.
5
+ *
6
+ * Same construction as the full preset (shared-ui
7
+ * `backgrounds/variants/hyperspace.tsx`, see its header for the derivation):
8
+ * the Skia original's per-frame `screen = plane/z` projection becomes scale
9
+ * keyframes on phase-offset shells — a layer scaled by 1/z moves every star
10
+ * outward on the true hyperbolic curve — with each shell's wrap snap hidden
11
+ * inside the fade the original applies to the first/last 6% of a star's
12
+ * life. Dial tuning: fewer stars, a slightly gentler cycle and lower alpha
13
+ * so the field reads behind the icons instead of competing with them.
14
+ * Stars are round crisp points, as in the original — never streaks.
15
+ *
16
+ * Cost while the dial is open: 1 animated node, ~48 static views — the same
17
+ * budget DialSnow ran. The dial is fixed-size (never user-resized), so
18
+ * sizing geometry from the passed circle size is correct here, and the
19
+ * circle's `overflow: "hidden"` clips the streaks.
20
+ */
21
+ export declare const DialHyperspace: import("react").NamedExoticComponent<{
22
+ size: number;
23
+ }>;
24
+ //# sourceMappingURL=DialHyperspace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DialHyperspace.d.ts","sourceRoot":"","sources":["../../../../../src/floatingMenu/dial/DialHyperspace.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AA4EH,eAAO,MAAM,cAAc;UAAkD,MAAM;EAqFjF,CAAC"}