@buoy-gg/core 7.0.35 → 7.0.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +57 -66
- package/bin/buoy.js +71 -20
- package/lib/commonjs/Buoy.js +3 -16
- package/lib/commonjs/floatingMenu/AppHost.js +1 -1
- package/lib/commonjs/floatingMenu/AppHost.web.js +1 -1
- package/lib/commonjs/floatingMenu/AppIcon.web.js +53 -0
- package/lib/commonjs/floatingMenu/DevToolsSettingsModal.js +12 -5
- package/lib/commonjs/floatingMenu/DevToolsSettingsModal.web.js +14 -34
- package/lib/commonjs/floatingMenu/FloatingDevTools.js +32 -48
- package/lib/commonjs/floatingMenu/FloatingDevTools.web.js +24 -4
- package/lib/commonjs/floatingMenu/FloatingMenu.js +1 -1
- package/lib/commonjs/floatingMenu/MinimizedToolsStack.js +83 -4
- package/lib/commonjs/floatingMenu/MinimizedToolsStack.web.js +90 -6
- package/lib/commonjs/floatingMenu/ToolHost.js +1 -0
- package/lib/commonjs/floatingMenu/autoExternalSync.js +3 -2
- package/lib/commonjs/floatingMenu/dial/DialDevTools.js +43 -10
- package/lib/commonjs/floatingMenu/dial/DialDevTools.web.js +18 -5
- package/lib/commonjs/floatingMenu/dial/dialUsageStore.js +13 -17
- package/lib/commonjs/floatingMenu/dial/onboardingConstants.js +37 -65
- package/lib/commonjs/floatingMenu/dial/onboardingConstants.web.js +37 -29
- package/lib/commonjs/floatingMenu/floatingTools.js +23 -889
- package/lib/commonjs/floatingMenu/floatingTools.web.js +24 -514
- package/lib/commonjs/floatingMenu/optionalRequire.js +4 -0
- package/lib/commonjs/telemetry/installPing.js +7 -0
- package/lib/commonjs/version.js +1 -1
- package/lib/module/Buoy.js +3 -16
- package/lib/module/floatingMenu/AppHost.js +1 -1
- package/lib/module/floatingMenu/AppHost.web.js +1 -1
- package/lib/module/floatingMenu/AppIcon.web.js +47 -0
- package/lib/module/floatingMenu/DevToolsSettingsModal.js +13 -6
- package/lib/module/floatingMenu/DevToolsSettingsModal.web.js +15 -35
- package/lib/module/floatingMenu/FloatingDevTools.js +35 -49
- package/lib/module/floatingMenu/FloatingDevTools.web.js +24 -3
- package/lib/module/floatingMenu/FloatingMenu.js +1 -1
- package/lib/module/floatingMenu/MinimizedToolsStack.js +88 -8
- package/lib/module/floatingMenu/MinimizedToolsStack.web.js +92 -8
- package/lib/module/floatingMenu/ToolHost.js +1 -0
- package/lib/module/floatingMenu/autoExternalSync.js +3 -2
- package/lib/module/floatingMenu/dial/DialDevTools.js +43 -10
- package/lib/module/floatingMenu/dial/DialDevTools.web.js +18 -5
- package/lib/module/floatingMenu/dial/dialUsageStore.js +14 -18
- package/lib/module/floatingMenu/dial/onboardingConstants.js +1 -62
- package/lib/module/floatingMenu/dial/onboardingConstants.web.js +1 -25
- package/lib/module/floatingMenu/floatingTools.js +15 -890
- package/lib/module/floatingMenu/floatingTools.web.js +1 -517
- package/lib/module/floatingMenu/optionalRequire.js +4 -0
- package/lib/module/telemetry/installPing.js +7 -0
- package/lib/module/version.js +1 -1
- package/lib/typescript/commonjs/Buoy.d.ts +14 -3
- package/lib/typescript/commonjs/Buoy.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/AppIcon.web.d.ts +14 -0
- package/lib/typescript/commonjs/floatingMenu/AppIcon.web.d.ts.map +1 -0
- package/lib/typescript/commonjs/floatingMenu/DevToolsSettingsModal.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/DevToolsSettingsModal.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/FloatingDevTools.d.ts +4 -14
- package/lib/typescript/commonjs/floatingMenu/FloatingDevTools.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/FloatingDevTools.web.d.ts +4 -19
- package/lib/typescript/commonjs/floatingMenu/FloatingDevTools.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/MinimizedToolsStack.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/MinimizedToolsStack.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/ToolHost.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/autoExternalSync.d.ts +3 -4
- package/lib/typescript/commonjs/floatingMenu/autoExternalSync.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/dial/DialDevTools.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/dial/DialDevTools.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/dial/dialUsageStore.d.ts +3 -15
- package/lib/typescript/commonjs/floatingMenu/dial/dialUsageStore.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/dial/onboardingConstants.d.ts +1 -29
- package/lib/typescript/commonjs/floatingMenu/dial/onboardingConstants.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/dial/onboardingConstants.web.d.ts +1 -12
- package/lib/typescript/commonjs/floatingMenu/dial/onboardingConstants.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/floatingTools.d.ts +6 -55
- package/lib/typescript/commonjs/floatingMenu/floatingTools.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/floatingTools.web.d.ts +3 -53
- package/lib/typescript/commonjs/floatingMenu/floatingTools.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/optionalRequire.d.ts.map +1 -1
- package/lib/typescript/commonjs/telemetry/installPing.d.ts +8 -1
- package/lib/typescript/commonjs/telemetry/installPing.d.ts.map +1 -1
- package/lib/typescript/commonjs/version.d.ts +1 -1
- package/lib/typescript/module/Buoy.d.ts +14 -3
- package/lib/typescript/module/Buoy.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/AppIcon.web.d.ts +14 -0
- package/lib/typescript/module/floatingMenu/AppIcon.web.d.ts.map +1 -0
- package/lib/typescript/module/floatingMenu/DevToolsSettingsModal.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/DevToolsSettingsModal.web.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/FloatingDevTools.d.ts +4 -14
- package/lib/typescript/module/floatingMenu/FloatingDevTools.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/FloatingDevTools.web.d.ts +4 -19
- package/lib/typescript/module/floatingMenu/FloatingDevTools.web.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/MinimizedToolsStack.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/MinimizedToolsStack.web.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/ToolHost.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/autoExternalSync.d.ts +3 -4
- package/lib/typescript/module/floatingMenu/autoExternalSync.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/dial/DialDevTools.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/dial/DialDevTools.web.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/dial/dialUsageStore.d.ts +3 -15
- package/lib/typescript/module/floatingMenu/dial/dialUsageStore.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/dial/onboardingConstants.d.ts +1 -29
- package/lib/typescript/module/floatingMenu/dial/onboardingConstants.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/dial/onboardingConstants.web.d.ts +1 -12
- package/lib/typescript/module/floatingMenu/dial/onboardingConstants.web.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/floatingTools.d.ts +6 -55
- package/lib/typescript/module/floatingMenu/floatingTools.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/floatingTools.web.d.ts +3 -53
- package/lib/typescript/module/floatingMenu/floatingTools.web.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/optionalRequire.d.ts.map +1 -1
- package/lib/typescript/module/telemetry/installPing.d.ts +8 -1
- package/lib/typescript/module/telemetry/installPing.d.ts.map +1 -1
- package/lib/typescript/module/version.d.ts +1 -1
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -3,106 +3,97 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/@buoy-gg/core)
|
|
4
4
|
[](https://www.npmjs.com/package/@buoy-gg/core)
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
Buoy adds a floating developer-tools menu to your React Native app. Install the tools you need to inspect captured requests, app state, storage, and performance.
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
## Install and quick start
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
## Install
|
|
10
|
+
Install from your app’s directory, then sign in:
|
|
13
11
|
|
|
14
12
|
```bash
|
|
15
|
-
npm install @buoy-gg/core
|
|
13
|
+
npm install @buoy-gg/core @buoy-gg/network
|
|
14
|
+
npx --package=@buoy-gg/core buoy login
|
|
16
15
|
```
|
|
17
16
|
|
|
18
|
-
|
|
17
|
+
In an Expo Router project, keep your existing navigator and providers. For example:
|
|
19
18
|
|
|
20
19
|
```tsx
|
|
21
|
-
import {
|
|
20
|
+
import { Stack } from "expo-router";
|
|
21
|
+
import { Buoy, FloatingDevTools } from "@buoy-gg/core";
|
|
22
|
+
|
|
23
|
+
Buoy.init({ licenseKey: process.env.EXPO_PUBLIC_BUOY_KEY });
|
|
22
24
|
|
|
23
|
-
export default function
|
|
25
|
+
export default function RootLayout() {
|
|
24
26
|
return (
|
|
25
27
|
<>
|
|
26
|
-
|
|
28
|
+
<Stack />
|
|
27
29
|
<FloatingDevTools />
|
|
28
30
|
</>
|
|
29
31
|
);
|
|
30
32
|
}
|
|
31
33
|
```
|
|
32
34
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
## The 15 tools
|
|
36
|
-
|
|
37
|
-
| Tool | Package | What it does |
|
|
38
|
-
| --- | --- | --- |
|
|
39
|
-
| [Network](https://buoy.gg/buoy/latest/docs/tools/network) | `@buoy-gg/network` | Every request, response, timing & error — GraphQL operations extracted and named |
|
|
40
|
-
| [Storage](https://buoy.gg/buoy/latest/docs/tools/storage) | `@buoy-gg/storage` | Browse & edit AsyncStorage, MMKV & SecureStore with change history |
|
|
41
|
-
| [Env](https://buoy.gg/buoy/latest/docs/tools/env) | `@buoy-gg/env` | Auto-discovers `EXPO_PUBLIC_` vars, validates types, scores config health |
|
|
42
|
-
| [Query](https://buoy.gg/buoy/latest/docs/tools/react-query) | `@buoy-gg/react-query` | TanStack Query cache — refetch, invalidate, simulate loading & error states |
|
|
43
|
-
| [Routes](https://buoy.gg/buoy/latest/docs/tools/routes) | `@buoy-gg/route-events` | Navigation events, the live stack, and the full sitemap — jump to any screen |
|
|
44
|
-
| [Debug Borders](https://buoy.gg/buoy/latest/docs/tools/debug-borders) | `@buoy-gg/debug-borders` | Depth-colored layout borders — tap any label for testID, a11y props & styles |
|
|
45
|
-
| [Highlight Updates](https://buoy.gg/buoy/latest/docs/tools/highlight-updates) | `@buoy-gg/highlight-updates` | Every render, with the cause: mount, state, props, or parent |
|
|
46
|
-
| [Bench](https://buoy.gg/buoy/latest/docs/tools/perf-monitor) | `@buoy-gg/perf-monitor` | UI/JS FPS, CPU, memory & jank on a real device — batch benchmarks, ranked reports |
|
|
47
|
-
| [Events](https://buoy.gg/buoy/latest/docs/tools/events) | `@buoy-gg/events` | One timeline across every tool, with LLM-friendly export presets |
|
|
48
|
-
| [Console](https://buoy.gg/buoy/latest/docs/tools/console) | `@buoy-gg/console` | Chrome-DevTools console on device — read logs with no cable and no Metro |
|
|
49
|
-
| [Redux](https://buoy.gg/buoy/latest/docs/tools/redux) | `@buoy-gg/redux` | Inspect, dispatch & time travel — flags actions that blow the frame budget |
|
|
50
|
-
| [Zustand](https://buoy.gg/buoy/latest/docs/tools/zustand) | `@buoy-gg/zustand` | State, diffs, jump-to-state, one-tap reset — no middleware needed |
|
|
51
|
-
| [Jotai](https://buoy.gg/buoy/latest/docs/tools/jotai) | `@buoy-gg/jotai` | One `watchAtoms()` call — every event shows `prev → next` |
|
|
52
|
-
| [Impersonate](https://buoy.gg/buoy/latest/docs/tools/impersonate) | `@buoy-gg/impersonate` | Switch users, roles & flags without rebuilding |
|
|
53
|
-
| [Overlay](https://buoy.gg/buoy/latest/docs/tools/image-overlay) | `@buoy-gg/image-overlay` | Pin Figma mockups pixel-perfect over the app |
|
|
54
|
-
|
|
55
|
-
Grab everything in one line:
|
|
56
|
-
|
|
57
|
-
```bash
|
|
58
|
-
npm i @buoy-gg/{core,network,storage,env,react-query,route-events,debug-borders,highlight-updates,perf-monitor,events,console,redux,zustand,jotai,impersonate,image-overlay}
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
## Three surfaces, one live session
|
|
35
|
+
The login command writes the Expo key to `.env.local`. Keep the navigator and menu inside your existing providers. Without Expo Router, keep your app’s root content in place of `Stack`. For React Native CLI, load the key through your app’s environment configuration and pass it to `Buoy.init`; `.env.local` is not loaded automatically.
|
|
62
36
|
|
|
63
|
-
|
|
37
|
+
Restart the development server after installation. Open Buoy, complete any account prompt, and select Network. Trigger a new HTTP request in your app and check its URL and status. If no request appears, check whether the app used cached data or an unsupported transport.
|
|
64
38
|
|
|
65
|
-
-
|
|
66
|
-
- **On your desktop** — [Buoy Desktop](https://github.com/Buoy-gg/Buoy-Desktop) (free) mirrors the tools to full-screen panels on macOS, Windows & Linux, with a live FPS / CPU / memory HUD and remote control of the device. Devices connect automatically — physical phones included, no URLs to configure.
|
|
67
|
-
- **Through your agent** — the [Buoy MCP server](https://buoy.gg/buoy/latest/docs/mcp) gives Claude Code, Cursor, or any MCP editor structured tool calls into the running app: read live state, tap real buttons, run benchmarks on a physical device.
|
|
39
|
+
See the [Quick Start](https://buoy.gg/buoy/latest/docs/quick-start) for the full setup and [Installation](https://buoy.gg/buoy/latest/docs/installation) for requirements. Other tools may need store registration, provider context, or native dependencies.
|
|
68
40
|
|
|
69
|
-
|
|
41
|
+
The dial shows the most recently opened tool first. Tools you haven’t opened keep their registration order.
|
|
70
42
|
|
|
71
|
-
|
|
43
|
+
## Tools
|
|
72
44
|
|
|
73
|
-
|
|
45
|
+
| Tool | Package | What it does |
|
|
46
|
+
| --- | --- | --- |
|
|
47
|
+
| [Network](https://buoy.gg/buoy/latest/docs/tools/network) | `@buoy-gg/network` | Inspect HTTP requests captured through your React Native app’s global `fetch` and `XMLHttpRequest` hooks. Open a request to see its URL, status, headers, timing, and captured body. |
|
|
48
|
+
| [Storage](https://buoy.gg/buoy/latest/docs/tools/storage) | `@buoy-gg/storage` | Browse and edit supported AsyncStorage, registered MMKV instances, and registered SecureStore keys inside your app. |
|
|
49
|
+
| [Time Machine](https://buoy.gg/buoy/latest/docs/tools/time-machine) | `@buoy-gg/time-machine` | Save and restore supported client state; external side effects are not reversed. |
|
|
50
|
+
| [Ask Buoy](https://buoy.gg/buoy/latest/docs/tools/ask-buoy) | `@buoy-gg/ask-buoy` | Use an in-app assistant with your model endpoint and configured tools. |
|
|
51
|
+
| [Env](https://buoy.gg/buoy/latest/docs/tools/env) | `@buoy-gg/env` | Inspect runtime environment values and validate required variables. |
|
|
52
|
+
| [Query](https://buoy.gg/buoy/latest/docs/tools/react-query) | `@buoy-gg/react-query` | Inspect the TanStack Query cache used by your app. Refetch or invalidate a query and simulate states while checking the screen that consumes it. |
|
|
53
|
+
| [Routes](https://buoy.gg/buoy/latest/docs/tools/routes) | `@buoy-gg/route-events` | Inspect recorded navigation events and supported routes. |
|
|
54
|
+
| [Debug Borders](https://buoy.gg/buoy/latest/docs/tools/debug-borders) | `@buoy-gg/debug-borders` | Show layout borders and component labels over your React Native app. Tap a label to inspect the component’s available properties. |
|
|
55
|
+
| [Highlight Updates](https://buoy.gg/buoy/latest/docs/tools/highlight-updates) | `@buoy-gg/highlight-updates` | Highlight observed React component updates in development builds and inspect the available render details. |
|
|
56
|
+
| [Bench](https://buoy.gg/buoy/latest/docs/tools/perf-monitor) | `@buoy-gg/perf-monitor` | Measure available frame-rate, CPU, and memory metrics on a device. Record comparable runs to investigate performance changes. |
|
|
57
|
+
| [JS Top](https://buoy.gg/buoy/latest/docs/tools/js-top) | `@buoy-gg/js-top` | Task Manager for the JS thread — which timers, Promise chains & callbacks eat your JS FPS |
|
|
58
|
+
| [Images](https://buoy.gg/buoy/latest/docs/tools/images) | `@buoy-gg/images` | Inspect image loads observed by Buoy’s supported image hooks, including timing, dimensions, and estimated decoded memory. |
|
|
59
|
+
| [Assets](https://buoy.gg/buoy/latest/docs/tools/assets) | `@buoy-gg/assets` | Inspect assets visible to the runtime registry and, in development, the Metro dependency graph. Compare sizes and find possible duplicates. |
|
|
60
|
+
| [Events](https://buoy.gg/buoy/latest/docs/tools/events) | `@buoy-gg/events` | Review events from configured Buoy tools in one timeline. Filter by source, inspect an event, and export a selection for debugging. |
|
|
61
|
+
| [Console](https://buoy.gg/buoy/latest/docs/tools/console) | `@buoy-gg/console` | Read captured JavaScript console logs in your React Native app. Filter messages by level, search their contents, and inspect logged objects. |
|
|
62
|
+
| [Sentry](https://buoy.gg/buoy/latest/docs/tools/sentry) | `@buoy-gg/sentry` | Inspect captured Sentry envelopes and diagnostic estimates. |
|
|
63
|
+
| [Redux](https://buoy.gg/buoy/latest/docs/tools/redux) | `@buoy-gg/redux` | Inspect your connected Redux store, review captured actions and state changes, and dispatch actions from your device. |
|
|
64
|
+
| [Zustand](https://buoy.gg/buoy/latest/docs/tools/zustand) | `@buoy-gg/zustand` | Inspect the Zustand stores you register with Buoy. Review changes, edit state, and restore retained snapshots. |
|
|
65
|
+
| [Jotai](https://buoy.gg/buoy/latest/docs/tools/jotai) | `@buoy-gg/jotai` | Inspect registered Jotai atoms and their captured changes, with live values and per-atom history. |
|
|
66
|
+
| [Impersonate](https://buoy.gg/buoy/latest/docs/tools/impersonate) | `@buoy-gg/impersonate` | Connect your app’s user-switching flow to Buoy so testers can switch test accounts, roles, or flags without rebuilding. |
|
|
67
|
+
| [Overlay](https://buoy.gg/buoy/latest/docs/tools/image-overlay) | `@buoy-gg/image-overlay` | Place a reference image over your app to compare spacing, alignment, and sizing on the device. |
|
|
74
68
|
|
|
75
|
-
|
|
76
|
-
<FloatingDevTools licenseKey="YOUR_LICENSE_KEY" />
|
|
77
|
-
```
|
|
69
|
+
TV tools and the iOS Simulator camera have separate [platform requirements](https://buoy.gg/buoy/latest/docs/overview).
|
|
78
70
|
|
|
79
|
-
|
|
71
|
+
## Desktop and AI
|
|
80
72
|
|
|
81
|
-
|
|
73
|
+
Inspect configured tools in the floating menu on your device. You can also connect them to:
|
|
82
74
|
|
|
83
|
-
|
|
75
|
+
- [Buoy Desktop](https://github.com/Buoy-gg/Buoy-Desktop), for desktop panels and remote actions. React Native apps need `@buoy-gg/external-sync`; follow the [connection guide](https://buoy.gg/buoy/latest/docs/desktop) and sign in to Desktop separately.
|
|
76
|
+
- [MCP](https://buoy.gg/buoy/latest/docs/mcp), for an AI editor to inspect and act on the app. Configure both process and device accounts; data and action tools require Pro.
|
|
77
|
+
- [Ask Buoy](https://buoy.gg/buoy/latest/docs/tools/ask-buoy), for an in-app assistant. It requires Pro, a model endpoint you configure, and the tool integrations its tasks depend on.
|
|
84
78
|
|
|
85
|
-
|
|
86
|
-
{isInternalUser && <FloatingDevTools />}
|
|
87
|
-
```
|
|
79
|
+
Supported features vary by platform, build, and installed tools. [Flutter](https://buoy.gg/buoy/latest/docs/flutter/quick-start) has a separate debug-build setup.
|
|
88
80
|
|
|
89
|
-
|
|
81
|
+
## Account and plan requirements
|
|
90
82
|
|
|
91
|
-
|
|
83
|
+
Use a Free or Pro Buoy account. History limits and paid features vary by tool; see [pricing](https://buoy.gg/pricing). Production access requires Pro where supported. Development-only hooks and actions remain unavailable in release builds.
|
|
92
84
|
|
|
93
|
-
|
|
94
|
-
<FloatingDevTools headless />
|
|
95
|
-
```
|
|
85
|
+
## Production and connections
|
|
96
86
|
|
|
97
|
-
|
|
87
|
+
Start with a development build. Before enabling Buoy in a shipped app, restrict access using your app’s authorization checks and review the [component reference](https://buoy.gg/buoy/latest/docs/floating-devtools). Production access requires Pro, and development-only capabilities remain unavailable.
|
|
98
88
|
|
|
99
|
-
-
|
|
100
|
-
- [GitHub](https://github.com/Buoy-gg/buoy)
|
|
101
|
-
- [Buoy Desktop](https://github.com/Buoy-gg/Buoy-Desktop)
|
|
102
|
-
- [Pricing](https://buoy.gg/pricing)
|
|
89
|
+
Hiding the menu is not a substitute for backend authorization. Headless mode hides the on-device UI; it still requires account admission and sync configuration. Release sync is disabled by default and must be explicitly enabled.
|
|
103
90
|
|
|
104
|
-
|
|
91
|
+
Device sessions can travel over your LAN to the configured broker. Buoy also makes account and license requests; development telemetry is described in [Telemetry](https://buoy.gg/buoy/latest/docs/telemetry). Ask Buoy sends model requests to the endpoint you configure.
|
|
105
92
|
|
|
106
93
|
## License
|
|
107
94
|
|
|
108
95
|
Proprietary software. © Buoy LLC. All rights reserved. See the [Terms of Service](https://buoy.gg/terms).
|
|
96
|
+
|
|
97
|
+
### Custom floating controls
|
|
98
|
+
|
|
99
|
+
The DevTools bubble uses the shared `FloatingTool` shell. Custom tools can use the same shell with `openFloatingTool`; `FloatingDevTools` already mounts the host. See the [integration guide](https://buoy.gg/buoy/latest/docs/custom-tools/floating-tools).
|
package/bin/buoy.js
CHANGED
|
@@ -93,9 +93,43 @@ function detectEnvVarName(root) {
|
|
|
93
93
|
return 'BUOY_KEY';
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
/**
|
|
97
|
-
|
|
98
|
-
|
|
96
|
+
/**
|
|
97
|
+
* Which env file the key belongs in.
|
|
98
|
+
*
|
|
99
|
+
* Expo inlines `.env.local` into EVERY bundle, release builds included, and
|
|
100
|
+
* `npx expo export` forces NODE_ENV=production — so a free key written there
|
|
101
|
+
* ships inside the app to every phone that installs it. Each of those phones
|
|
102
|
+
* then validates against the license server, which is how one free account
|
|
103
|
+
* spent the whole daily quota in a morning. `.env.development.local` is only
|
|
104
|
+
* loaded under NODE_ENV=development, so a free key there can only ever reach
|
|
105
|
+
* a developer's own device.
|
|
106
|
+
*
|
|
107
|
+
* Paid keys keep `.env.local`: a Pro customer may want the tools in a
|
|
108
|
+
* TestFlight or QA build, and that is their call to make.
|
|
109
|
+
*/
|
|
110
|
+
function envFileFor(varName, tier) {
|
|
111
|
+
if (varName !== 'EXPO_PUBLIC_BUOY_KEY') return '.env.local';
|
|
112
|
+
return tier === 'pro' || tier === 'business' ? '.env.local' : '.env.development.local';
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** Drop `NAME=...` from an env file if present. True when a line was removed. */
|
|
116
|
+
function removeEnvVar(root, name, fileName) {
|
|
117
|
+
const file = path.join(root, fileName);
|
|
118
|
+
let contents;
|
|
119
|
+
try {
|
|
120
|
+
contents = fs.readFileSync(file, 'utf8');
|
|
121
|
+
} catch {
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
const pattern = new RegExp('^' + name + '=.*\\n?', 'm');
|
|
125
|
+
if (!pattern.test(contents)) return false;
|
|
126
|
+
fs.writeFileSync(file, contents.replace(pattern, ''), { mode: 0o600 });
|
|
127
|
+
return true;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/** Upsert `NAME=value` in an env file, preserving everything else in the file. */
|
|
131
|
+
function writeEnvVar(root, name, value, fileName = '.env.local') {
|
|
132
|
+
const file = path.join(root, fileName);
|
|
99
133
|
let contents = '';
|
|
100
134
|
try {
|
|
101
135
|
contents = fs.readFileSync(file, 'utf8');
|
|
@@ -118,13 +152,13 @@ function writeEnvVar(root, name, value) {
|
|
|
118
152
|
}
|
|
119
153
|
|
|
120
154
|
/**
|
|
121
|
-
* Make sure
|
|
155
|
+
* Make sure the env file is ignored.
|
|
122
156
|
*
|
|
123
157
|
* The whole point of a per-developer key is that it identifies one person; a
|
|
124
158
|
* key committed to a shared repo turns the count back into "repos", which is
|
|
125
159
|
* exactly what this flow exists to avoid.
|
|
126
160
|
*/
|
|
127
|
-
function ensureGitignored(root) {
|
|
161
|
+
function ensureGitignored(root, fileName = '.env.local') {
|
|
128
162
|
const file = path.join(root, '.gitignore');
|
|
129
163
|
let contents = '';
|
|
130
164
|
try {
|
|
@@ -132,10 +166,12 @@ function ensureGitignored(root) {
|
|
|
132
166
|
} catch {
|
|
133
167
|
return false;
|
|
134
168
|
}
|
|
135
|
-
|
|
169
|
+
const exact = new RegExp('^' + fileName.replace(/\./g, '\\.') + '$', 'm');
|
|
170
|
+
// `.env*`, `*.local` and `.env*.local` all cover both files we might write.
|
|
171
|
+
if (exact.test(contents) || /^\.env\*|^\*\.local$|^\.env\*\.local$/m.test(contents)) return false;
|
|
136
172
|
|
|
137
173
|
if (contents && !contents.endsWith('\n')) contents += '\n';
|
|
138
|
-
contents +=
|
|
174
|
+
contents += `\n# Buoy license key (per developer - do not commit)\n${fileName}\n`;
|
|
139
175
|
fs.writeFileSync(file, contents);
|
|
140
176
|
return true;
|
|
141
177
|
}
|
|
@@ -219,7 +255,7 @@ function awaitKeyFromBrowser() {
|
|
|
219
255
|
|
|
220
256
|
log('');
|
|
221
257
|
log(` Opening ${cyan(url)}`);
|
|
222
|
-
log(dim(' If your browser did not open, paste that URL into
|
|
258
|
+
log(dim(' If your browser did not open, paste that URL into a browser on this computer.'));
|
|
223
259
|
log('');
|
|
224
260
|
log(dim(' Waiting for you to finish signing in...'));
|
|
225
261
|
|
|
@@ -245,23 +281,31 @@ async function login() {
|
|
|
245
281
|
}
|
|
246
282
|
|
|
247
283
|
const varName = detectEnvVarName(root);
|
|
248
|
-
const
|
|
249
|
-
const
|
|
250
|
-
|
|
284
|
+
const fileName = envFileFor(varName, result.tier);
|
|
285
|
+
const file = writeEnvVar(root, varName, result.key, fileName);
|
|
286
|
+
// An earlier login may have left the key in .env.local; a free key there
|
|
287
|
+
// would still ride along into release builds.
|
|
288
|
+
const moved = fileName !== '.env.local' && removeEnvVar(root, varName, '.env.local');
|
|
289
|
+
const addedIgnore = ensureGitignored(root, fileName);
|
|
290
|
+
const relative = path.relative(root, file) || fileName;
|
|
251
291
|
|
|
252
292
|
log('');
|
|
253
293
|
log(
|
|
254
294
|
`${green('OK')} Signed in${result.email ? ' as ' + bold(result.email) : ''} - ${bold(result.tier)} tier`
|
|
255
295
|
);
|
|
256
296
|
log(` Wrote ${cyan(varName)} to ${cyan(relative)}`);
|
|
257
|
-
if (
|
|
297
|
+
if (moved) log(dim(` Removed the old ${varName} line from .env.local`));
|
|
298
|
+
if (fileName === '.env.development.local') {
|
|
299
|
+
log(dim(' Expo loads this file for `expo start` only, so the key stays out of release builds.'));
|
|
300
|
+
}
|
|
301
|
+
if (addedIgnore) log(dim(` Added ${fileName} to .gitignore`));
|
|
258
302
|
log('');
|
|
259
303
|
log(' Use it in your app:');
|
|
260
304
|
log('');
|
|
261
|
-
log(cyan(` Buoy.init({ licenseKey:
|
|
305
|
+
log(cyan(` Buoy.init({ licenseKey: ${varName} });`));
|
|
262
306
|
log('');
|
|
263
|
-
log(dim('
|
|
264
|
-
log(dim('
|
|
307
|
+
log(dim(' Swift: pass the key through BuoyConfig.licenseKey in your development build.'));
|
|
308
|
+
log(dim(' Bare React Native does not load .env.local automatically; wire your existing env loader.'));
|
|
265
309
|
log('');
|
|
266
310
|
}
|
|
267
311
|
|
|
@@ -270,16 +314,21 @@ function help() {
|
|
|
270
314
|
${bold('buoy')} - React Buoy CLI
|
|
271
315
|
|
|
272
316
|
${bold('Usage')}
|
|
273
|
-
npx buoy <command>
|
|
274
|
-
|
|
317
|
+
npx --package=@buoy-gg/core buoy <command>
|
|
318
|
+
|
|
319
|
+
${dim('(if npx picks the wrong one)')}
|
|
275
320
|
|
|
276
321
|
${bold('Commands')}
|
|
277
|
-
login Sign in and write your license key to
|
|
322
|
+
login Sign in and write your license key to an env file
|
|
278
323
|
help Show this message
|
|
279
324
|
|
|
280
325
|
${bold('Notes')}
|
|
281
|
-
|
|
282
|
-
|
|
326
|
+
Run login from your app directory. Complete browser sign-in to receive
|
|
327
|
+
your account key. On Expo, a free key goes to .env.development.local so
|
|
328
|
+
it never ships in a release build; a paid key goes to .env.local. Other
|
|
329
|
+
projects receive BUOY_KEY in .env.local and must configure their own
|
|
330
|
+
environment loader and variable mapping.
|
|
331
|
+
This command does not install tools or verify a Desktop connection.
|
|
283
332
|
|
|
284
333
|
Docs: ${SITE}/buoy/latest/docs/installation
|
|
285
334
|
`);
|
|
@@ -301,7 +350,9 @@ if (require.main === module) {
|
|
|
301
350
|
|
|
302
351
|
module.exports = {
|
|
303
352
|
detectEnvVarName,
|
|
353
|
+
envFileFor,
|
|
304
354
|
writeEnvVar,
|
|
355
|
+
removeEnvVar,
|
|
305
356
|
ensureGitignored,
|
|
306
357
|
awaitKeyFromBrowser,
|
|
307
358
|
};
|
package/lib/commonjs/Buoy.js
CHANGED
|
@@ -61,16 +61,7 @@ const Buoy = exports.Buoy = {
|
|
|
61
61
|
*/
|
|
62
62
|
init(config) {
|
|
63
63
|
if (config.telemetry === false) telemetryEnabled = false;
|
|
64
|
-
|
|
65
|
-
// If no license key or empty string, clear any cached license
|
|
66
|
-
if (!config.licenseKey || config.licenseKey.trim() === "") {
|
|
67
|
-
_license.LicenseManager.initialize().then(() => _license.LicenseManager.clearLicense()).catch(() => {});
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Initialize the license manager and set the key
|
|
72
|
-
const key = config.licenseKey; // We've already checked it's not empty above
|
|
73
|
-
_license.LicenseManager.initialize().then(() => _license.LicenseManager.setLicenseKey(key)).catch(error => {
|
|
64
|
+
void _license.LicenseManager.configure(config.licenseKey).catch(error => {
|
|
74
65
|
console.warn("[Buoy] License initialization failed:", error);
|
|
75
66
|
});
|
|
76
67
|
},
|
|
@@ -88,12 +79,8 @@ const Buoy = exports.Buoy = {
|
|
|
88
79
|
* ```
|
|
89
80
|
*/
|
|
90
81
|
async initAsync(config) {
|
|
91
|
-
if (
|
|
92
|
-
|
|
93
|
-
return false;
|
|
94
|
-
}
|
|
95
|
-
await _license.LicenseManager.initialize();
|
|
96
|
-
return _license.LicenseManager.setLicenseKey(config.licenseKey);
|
|
82
|
+
if (config.telemetry === false) telemetryEnabled = false;
|
|
83
|
+
return _license.LicenseManager.configure(config.licenseKey);
|
|
97
84
|
},
|
|
98
85
|
/**
|
|
99
86
|
* Check if Buoy Pro is active
|
|
@@ -8,7 +8,7 @@ var _sharedUi = require("@buoy-gg/shared-ui");
|
|
|
8
8
|
var _react = _interopRequireWildcard(require("react"));
|
|
9
9
|
var _reactNative = require("react-native");
|
|
10
10
|
var _AppHostLogic = require("./AppHostLogic.js");
|
|
11
|
-
var _AppIcon = require("./AppIcon
|
|
11
|
+
var _AppIcon = require("./AppIcon");
|
|
12
12
|
var _MinimizedToolsContext = require("./MinimizedToolsContext.js");
|
|
13
13
|
var _ToolHost = require("./ToolHost.js");
|
|
14
14
|
var _DevToolsSettingsModal = require("./DevToolsSettingsModal");
|
|
@@ -7,7 +7,7 @@ exports.useAppHost = exports.AppOverlay = exports.AppHostProvider = void 0;
|
|
|
7
7
|
var _sharedUi = require("@buoy-gg/shared-ui");
|
|
8
8
|
var _react = require("react");
|
|
9
9
|
var _AppHostLogic = require("./AppHostLogic.js");
|
|
10
|
-
var _AppIcon = require("./AppIcon
|
|
10
|
+
var _AppIcon = require("./AppIcon");
|
|
11
11
|
var _floatingToolsWeb = require("./floatingTools.web.js");
|
|
12
12
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
13
13
|
/**
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.AppTextIcon = AppTextIcon;
|
|
7
|
+
exports.renderAppIcon = renderAppIcon;
|
|
8
|
+
var _react = _interopRequireDefault(require("react"));
|
|
9
|
+
var _sharedUi = require("@buoy-gg/shared-ui");
|
|
10
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
11
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
12
|
+
/** DOM twin of the native icon resolver; importing RN breaks pure web hosts. */
|
|
13
|
+
function AppTextIcon({
|
|
14
|
+
label,
|
|
15
|
+
size,
|
|
16
|
+
color = _sharedUi.toolTheme.colors.text
|
|
17
|
+
}) {
|
|
18
|
+
const chars = Math.max(Array.from(label.replace(/[\uFE00-\uFE0F\u200D]/g, "")).length, 1);
|
|
19
|
+
const maxWidth = chars <= 2 ? size : size * 1.6;
|
|
20
|
+
const fontSize = Math.max(7, Math.min(size * (chars === 1 ? 0.7 : 0.62), maxWidth / (0.62 * chars)));
|
|
21
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
|
|
22
|
+
style: {
|
|
23
|
+
display: "inline-flex",
|
|
24
|
+
minWidth: size,
|
|
25
|
+
maxWidth,
|
|
26
|
+
height: size,
|
|
27
|
+
alignItems: "center",
|
|
28
|
+
justifyContent: "center",
|
|
29
|
+
color,
|
|
30
|
+
fontSize,
|
|
31
|
+
fontWeight: 800,
|
|
32
|
+
letterSpacing: 0.5,
|
|
33
|
+
whiteSpace: "nowrap",
|
|
34
|
+
overflow: "hidden"
|
|
35
|
+
},
|
|
36
|
+
children: label
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
function renderAppIcon(icon, ctx) {
|
|
40
|
+
if (icon == null) return icon;
|
|
41
|
+
if (typeof icon === "function") return /*#__PURE__*/_react.default.createElement(icon, {
|
|
42
|
+
slot: ctx.slot,
|
|
43
|
+
size: ctx.size,
|
|
44
|
+
state: ctx.state,
|
|
45
|
+
actions: ctx.actions
|
|
46
|
+
});
|
|
47
|
+
if (typeof icon === "string" || typeof icon === "number") return /*#__PURE__*/(0, _jsxRuntime.jsx)(AppTextIcon, {
|
|
48
|
+
label: String(icon),
|
|
49
|
+
size: ctx.size,
|
|
50
|
+
color: ctx.color
|
|
51
|
+
});
|
|
52
|
+
return icon;
|
|
53
|
+
}
|
|
@@ -11,7 +11,7 @@ var _useDesktopSyncStatus = require("./useDesktopSyncStatus.js");
|
|
|
11
11
|
var _sharedUi = require("@buoy-gg/shared-ui");
|
|
12
12
|
var _floatingToolsCore = require("@buoy-gg/floating-tools-core");
|
|
13
13
|
var _DefaultConfigContext = require("./DefaultConfigContext.js");
|
|
14
|
-
var _AppIcon = require("./AppIcon
|
|
14
|
+
var _AppIcon = require("./AppIcon");
|
|
15
15
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
16
16
|
const STORAGE_KEY = "@react_buoy_dev_tools_settings";
|
|
17
17
|
const MAX_DIAL_SLOTS = 6;
|
|
@@ -376,10 +376,9 @@ const DevToolsSettingsModal = ({
|
|
|
376
376
|
size: 18
|
|
377
377
|
});
|
|
378
378
|
case "sentry":
|
|
379
|
-
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.
|
|
379
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.SentryIcon, {
|
|
380
380
|
size: 18,
|
|
381
|
-
|
|
382
|
-
noBackground: true
|
|
381
|
+
color: "#9945FF"
|
|
383
382
|
});
|
|
384
383
|
case "storage":
|
|
385
384
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_floatingToolsCore.StorageIcon, {
|
|
@@ -597,6 +596,7 @@ const DevToolsSettingsModal = ({
|
|
|
597
596
|
contentContainerStyle: styles.scrollContainer,
|
|
598
597
|
children: [activeTab === "floating" && /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
|
|
599
598
|
children: renderSection("Floating Tools", /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.NightCard, {
|
|
599
|
+
glass: true,
|
|
600
600
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.NightRows, {
|
|
601
601
|
children: Object.entries(settings.floatingTools).map(([key, value]) => renderToolRow(key, value, false, () => toggleFloatingTool(key)))
|
|
602
602
|
})
|
|
@@ -605,11 +605,13 @@ const DevToolsSettingsModal = ({
|
|
|
605
605
|
}))
|
|
606
606
|
}), activeTab === "settings" && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
607
607
|
children: [renderSection("Background", /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.NightCard, {
|
|
608
|
+
glass: true,
|
|
608
609
|
padded: true,
|
|
609
610
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.BackgroundSwitcher, {
|
|
610
611
|
embedded: true
|
|
611
612
|
})
|
|
612
613
|
})), renderSection("Storage", /*#__PURE__*/(0, _jsxRuntime.jsxs)(_sharedUi.NightCard, {
|
|
614
|
+
glass: true,
|
|
613
615
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
|
|
614
616
|
activeOpacity: 0.7,
|
|
615
617
|
onPress: () => setIsStorageExpanded(!isStorageExpanded),
|
|
@@ -690,6 +692,7 @@ const DevToolsSettingsModal = ({
|
|
|
690
692
|
})]
|
|
691
693
|
})]
|
|
692
694
|
})), desktopSyncStatus && desktopSyncStatus.state !== "idle" && renderSection("Desktop Sync", /*#__PURE__*/(0, _jsxRuntime.jsxs)(_sharedUi.NightCard, {
|
|
695
|
+
glass: true,
|
|
693
696
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
|
|
694
697
|
activeOpacity: 0.7,
|
|
695
698
|
onPress: () => toggleSettingExpanded("desktopSync"),
|
|
@@ -731,12 +734,14 @@ const DevToolsSettingsModal = ({
|
|
|
731
734
|
})]
|
|
732
735
|
})]
|
|
733
736
|
})), renderSection("Modal Behavior", /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.NightCard, {
|
|
737
|
+
glass: true,
|
|
734
738
|
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_sharedUi.NightRows, {
|
|
735
739
|
children: [renderGlobalSettingRow("enableSharedModalDimensions", "Shared Modal Size", "Sync dimensions across all tools", "When enabled, all tool modals will share the same size and position. Resizing one modal will affect all others. When disabled, each tool remembers its own size and position independently.", "Keep OFF for the best experience. This allows you to customize each tool's modal size separately."), _reactNative.Platform.OS !== "web" ? renderGlobalSettingRow("expandableWindowControls", "Expand Controls", "iPad-style expandable window buttons", "When enabled, the window control buttons (minimize, toggle mode, close) start as small dots and expand into larger, easy-to-tap buttons when pressed. When disabled, buttons are directly tappable at their small size.", "Keep ON for touch devices where the small buttons are hard to press. Turn OFF if you prefer direct single-tap access.") : null]
|
|
736
740
|
})
|
|
737
741
|
}))]
|
|
738
742
|
}), activeTab === "pro" && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
739
743
|
children: [renderSection("License", /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.NightCard, {
|
|
744
|
+
glass: true,
|
|
740
745
|
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
741
746
|
style: styles.settingRow,
|
|
742
747
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
@@ -757,6 +762,7 @@ const DevToolsSettingsModal = ({
|
|
|
757
762
|
children: isPro ? "You have full access to all Buoy DevTools features." : licenseError ? licenseErrorIsTransport ? `Couldn't reach the license server (${licenseError}). A VPN or corporate proxy can block api.keygen.sh — turn it off and reload. Your key hasn't been rejected.` : `License check failed: ${licenseError}.` : "Upgrade to Pro to unlock all features and support development."
|
|
758
763
|
})), !isPro && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
759
764
|
children: [renderSection("Pro Features", /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.NightCard, {
|
|
765
|
+
glass: true,
|
|
760
766
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.NightRows, {
|
|
761
767
|
children: ["Advanced Settings", "Priority Support"].map(feature => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
762
768
|
style: styles.featureRow,
|
|
@@ -792,6 +798,7 @@ const DevToolsSettingsModal = ({
|
|
|
792
798
|
customContent: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
793
799
|
style: styles.headerRow,
|
|
794
800
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.NightSegmented, {
|
|
801
|
+
glass: true,
|
|
795
802
|
tabs: [{
|
|
796
803
|
key: "floating",
|
|
797
804
|
label: "Floating"
|
|
@@ -1083,7 +1090,7 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
1083
1090
|
maxHeight: 150
|
|
1084
1091
|
},
|
|
1085
1092
|
storageKeyItem: {
|
|
1086
|
-
backgroundColor: _sharedUi.night.color.
|
|
1093
|
+
backgroundColor: _sharedUi.night.color.glassElevated,
|
|
1087
1094
|
borderRadius: _sharedUi.night.radius.segment,
|
|
1088
1095
|
paddingHorizontal: 10,
|
|
1089
1096
|
paddingVertical: 7,
|