@buoy-gg/core 7.0.15 → 7.0.17

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 (133) hide show
  1. package/lib/commonjs/floatingMenu/AppHost.js +18 -0
  2. package/lib/commonjs/floatingMenu/AppHost.web.js +359 -0
  3. package/lib/commonjs/floatingMenu/AppHostLogic.js +6 -0
  4. package/lib/commonjs/floatingMenu/DevToolsSettingsModal.web.js +787 -418
  5. package/lib/commonjs/floatingMenu/FloatingDevTools.js +1 -1
  6. package/lib/commonjs/floatingMenu/FloatingDevTools.web.js +244 -36
  7. package/lib/commonjs/floatingMenu/FloatingMenu.js +4 -3
  8. package/lib/commonjs/floatingMenu/MinimizedToolsContext.js +2 -3
  9. package/lib/commonjs/floatingMenu/MinimizedToolsStack.web.js +287 -0
  10. package/lib/commonjs/floatingMenu/ToolHost.js +264 -0
  11. package/lib/commonjs/floatingMenu/allToolsRegistry.js +7 -0
  12. package/lib/commonjs/floatingMenu/autoDiscoverPresets.js +32 -0
  13. package/lib/commonjs/floatingMenu/autoExternalSync.js +18 -0
  14. package/lib/commonjs/floatingMenu/dial/DialDevTools.js +9 -5
  15. package/lib/commonjs/floatingMenu/dial/DialDevTools.web.js +373 -231
  16. package/lib/commonjs/floatingMenu/dial/DialIcon.js +25 -3
  17. package/lib/commonjs/floatingMenu/dial/OnboardingTooltip.js +1 -1
  18. package/lib/commonjs/floatingMenu/dial/OnboardingTooltip.web.js +154 -0
  19. package/lib/commonjs/floatingMenu/dial/onboardingConstants.web.js +34 -0
  20. package/lib/commonjs/floatingMenu/floatingTools.js +3 -3
  21. package/lib/commonjs/floatingMenu/floatingTools.web.js +191 -28
  22. package/lib/commonjs/index.js +29 -2
  23. package/lib/commonjs/index.web.js +19 -0
  24. package/lib/commonjs/toolkit.js +427 -0
  25. package/lib/commonjs/utils/autoDiscoverPresets.web.js +50 -5
  26. package/lib/module/floatingMenu/AppHost.js +18 -0
  27. package/lib/module/floatingMenu/AppHost.web.js +351 -0
  28. package/lib/module/floatingMenu/AppHostLogic.js +6 -0
  29. package/lib/module/floatingMenu/DevToolsSettingsModal.web.js +792 -422
  30. package/lib/module/floatingMenu/FloatingDevTools.js +2 -2
  31. package/lib/module/floatingMenu/FloatingDevTools.web.js +247 -38
  32. package/lib/module/floatingMenu/FloatingMenu.js +4 -3
  33. package/lib/module/floatingMenu/MinimizedToolsContext.js +2 -3
  34. package/lib/module/floatingMenu/MinimizedToolsStack.web.js +284 -0
  35. package/lib/module/floatingMenu/ToolHost.js +256 -0
  36. package/lib/module/floatingMenu/allToolsRegistry.js +8 -1
  37. package/lib/module/floatingMenu/autoDiscoverPresets.js +32 -0
  38. package/lib/module/floatingMenu/autoExternalSync.js +18 -0
  39. package/lib/module/floatingMenu/dial/DialDevTools.js +10 -6
  40. package/lib/module/floatingMenu/dial/DialDevTools.web.js +375 -233
  41. package/lib/module/floatingMenu/dial/DialIcon.js +26 -4
  42. package/lib/module/floatingMenu/dial/OnboardingTooltip.js +1 -1
  43. package/lib/module/floatingMenu/dial/OnboardingTooltip.web.js +149 -0
  44. package/lib/module/floatingMenu/dial/onboardingConstants.web.js +27 -0
  45. package/lib/module/floatingMenu/floatingTools.js +3 -3
  46. package/lib/module/floatingMenu/floatingTools.web.js +190 -28
  47. package/lib/module/index.js +8 -2
  48. package/lib/module/index.web.js +5 -0
  49. package/lib/module/toolkit.js +45 -0
  50. package/lib/module/utils/autoDiscoverPresets.web.js +53 -7
  51. package/lib/typescript/commonjs/floatingMenu/AppHost.d.ts.map +1 -1
  52. package/lib/typescript/commonjs/floatingMenu/AppHost.web.d.ts +38 -0
  53. package/lib/typescript/commonjs/floatingMenu/AppHost.web.d.ts.map +1 -0
  54. package/lib/typescript/commonjs/floatingMenu/AppHostLogic.d.ts +24 -1
  55. package/lib/typescript/commonjs/floatingMenu/AppHostLogic.d.ts.map +1 -1
  56. package/lib/typescript/commonjs/floatingMenu/DevToolsSettingsModal.web.d.ts +5 -2
  57. package/lib/typescript/commonjs/floatingMenu/DevToolsSettingsModal.web.d.ts.map +1 -1
  58. package/lib/typescript/commonjs/floatingMenu/FloatingDevTools.web.d.ts +2 -14
  59. package/lib/typescript/commonjs/floatingMenu/FloatingDevTools.web.d.ts.map +1 -1
  60. package/lib/typescript/commonjs/floatingMenu/FloatingMenu.d.ts.map +1 -1
  61. package/lib/typescript/commonjs/floatingMenu/MinimizedToolsContext.d.ts +2 -20
  62. package/lib/typescript/commonjs/floatingMenu/MinimizedToolsContext.d.ts.map +1 -1
  63. package/lib/typescript/commonjs/floatingMenu/MinimizedToolsStack.web.d.ts +21 -0
  64. package/lib/typescript/commonjs/floatingMenu/MinimizedToolsStack.web.d.ts.map +1 -0
  65. package/lib/typescript/commonjs/floatingMenu/ToolHost.d.ts +72 -0
  66. package/lib/typescript/commonjs/floatingMenu/ToolHost.d.ts.map +1 -0
  67. package/lib/typescript/commonjs/floatingMenu/allToolsRegistry.d.ts.map +1 -1
  68. package/lib/typescript/commonjs/floatingMenu/autoDiscoverPresets.d.ts.map +1 -1
  69. package/lib/typescript/commonjs/floatingMenu/autoExternalSync.d.ts.map +1 -1
  70. package/lib/typescript/commonjs/floatingMenu/defaultConfig.d.ts +1 -1
  71. package/lib/typescript/commonjs/floatingMenu/defaultConfig.d.ts.map +1 -1
  72. package/lib/typescript/commonjs/floatingMenu/dial/DialDevTools.d.ts.map +1 -1
  73. package/lib/typescript/commonjs/floatingMenu/dial/DialDevTools.web.d.ts +16 -2
  74. package/lib/typescript/commonjs/floatingMenu/dial/DialDevTools.web.d.ts.map +1 -1
  75. package/lib/typescript/commonjs/floatingMenu/dial/DialIcon.d.ts.map +1 -1
  76. package/lib/typescript/commonjs/floatingMenu/dial/OnboardingTooltip.web.d.ts +9 -0
  77. package/lib/typescript/commonjs/floatingMenu/dial/OnboardingTooltip.web.d.ts.map +1 -0
  78. package/lib/typescript/commonjs/floatingMenu/dial/onboardingConstants.web.d.ts +13 -0
  79. package/lib/typescript/commonjs/floatingMenu/dial/onboardingConstants.web.d.ts.map +1 -0
  80. package/lib/typescript/commonjs/floatingMenu/floatingTools.web.d.ts +29 -2
  81. package/lib/typescript/commonjs/floatingMenu/floatingTools.web.d.ts.map +1 -1
  82. package/lib/typescript/commonjs/floatingMenu/types.d.ts +30 -1
  83. package/lib/typescript/commonjs/floatingMenu/types.d.ts.map +1 -1
  84. package/lib/typescript/commonjs/index.d.ts +2 -0
  85. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  86. package/lib/typescript/commonjs/index.web.d.ts +1 -0
  87. package/lib/typescript/commonjs/index.web.d.ts.map +1 -1
  88. package/lib/typescript/commonjs/toolkit.d.ts +22 -0
  89. package/lib/typescript/commonjs/toolkit.d.ts.map +1 -0
  90. package/lib/typescript/commonjs/utils/autoDiscoverPresets.web.d.ts +2 -0
  91. package/lib/typescript/commonjs/utils/autoDiscoverPresets.web.d.ts.map +1 -1
  92. package/lib/typescript/module/floatingMenu/AppHost.d.ts.map +1 -1
  93. package/lib/typescript/module/floatingMenu/AppHost.web.d.ts +38 -0
  94. package/lib/typescript/module/floatingMenu/AppHost.web.d.ts.map +1 -0
  95. package/lib/typescript/module/floatingMenu/AppHostLogic.d.ts +24 -1
  96. package/lib/typescript/module/floatingMenu/AppHostLogic.d.ts.map +1 -1
  97. package/lib/typescript/module/floatingMenu/DevToolsSettingsModal.web.d.ts +5 -2
  98. package/lib/typescript/module/floatingMenu/DevToolsSettingsModal.web.d.ts.map +1 -1
  99. package/lib/typescript/module/floatingMenu/FloatingDevTools.web.d.ts +2 -14
  100. package/lib/typescript/module/floatingMenu/FloatingDevTools.web.d.ts.map +1 -1
  101. package/lib/typescript/module/floatingMenu/FloatingMenu.d.ts.map +1 -1
  102. package/lib/typescript/module/floatingMenu/MinimizedToolsContext.d.ts +2 -20
  103. package/lib/typescript/module/floatingMenu/MinimizedToolsContext.d.ts.map +1 -1
  104. package/lib/typescript/module/floatingMenu/MinimizedToolsStack.web.d.ts +21 -0
  105. package/lib/typescript/module/floatingMenu/MinimizedToolsStack.web.d.ts.map +1 -0
  106. package/lib/typescript/module/floatingMenu/ToolHost.d.ts +72 -0
  107. package/lib/typescript/module/floatingMenu/ToolHost.d.ts.map +1 -0
  108. package/lib/typescript/module/floatingMenu/allToolsRegistry.d.ts.map +1 -1
  109. package/lib/typescript/module/floatingMenu/autoDiscoverPresets.d.ts.map +1 -1
  110. package/lib/typescript/module/floatingMenu/autoExternalSync.d.ts.map +1 -1
  111. package/lib/typescript/module/floatingMenu/defaultConfig.d.ts +1 -1
  112. package/lib/typescript/module/floatingMenu/defaultConfig.d.ts.map +1 -1
  113. package/lib/typescript/module/floatingMenu/dial/DialDevTools.d.ts.map +1 -1
  114. package/lib/typescript/module/floatingMenu/dial/DialDevTools.web.d.ts +16 -2
  115. package/lib/typescript/module/floatingMenu/dial/DialDevTools.web.d.ts.map +1 -1
  116. package/lib/typescript/module/floatingMenu/dial/DialIcon.d.ts.map +1 -1
  117. package/lib/typescript/module/floatingMenu/dial/OnboardingTooltip.web.d.ts +9 -0
  118. package/lib/typescript/module/floatingMenu/dial/OnboardingTooltip.web.d.ts.map +1 -0
  119. package/lib/typescript/module/floatingMenu/dial/onboardingConstants.web.d.ts +13 -0
  120. package/lib/typescript/module/floatingMenu/dial/onboardingConstants.web.d.ts.map +1 -0
  121. package/lib/typescript/module/floatingMenu/floatingTools.web.d.ts +29 -2
  122. package/lib/typescript/module/floatingMenu/floatingTools.web.d.ts.map +1 -1
  123. package/lib/typescript/module/floatingMenu/types.d.ts +30 -1
  124. package/lib/typescript/module/floatingMenu/types.d.ts.map +1 -1
  125. package/lib/typescript/module/index.d.ts +2 -0
  126. package/lib/typescript/module/index.d.ts.map +1 -1
  127. package/lib/typescript/module/index.web.d.ts +1 -0
  128. package/lib/typescript/module/index.web.d.ts.map +1 -1
  129. package/lib/typescript/module/toolkit.d.ts +22 -0
  130. package/lib/typescript/module/toolkit.d.ts.map +1 -0
  131. package/lib/typescript/module/utils/autoDiscoverPresets.web.d.ts +2 -0
  132. package/lib/typescript/module/utils/autoDiscoverPresets.web.d.ts.map +1 -1
  133. package/package.json +5 -5
@@ -7,6 +7,7 @@ exports.SettingsModal = SettingsModal;
7
7
  var _react = require("react");
8
8
  var _floatingToolsReact = require("@buoy-gg/floating-tools-react");
9
9
  var _floatingToolsCore = require("@buoy-gg/floating-tools-core");
10
+ var _sharedUi = require("@buoy-gg/shared-ui");
10
11
  var _jsxRuntime = require("react/jsx-runtime");
11
12
  /**
12
13
  * DevToolsSettingsModal - Web renderer for the dev tools settings modal.
@@ -14,12 +15,54 @@ var _jsxRuntime = require("react/jsx-runtime");
14
15
  * Uses shared configuration and logic from @buoy-gg/floating-tools-react.
15
16
  * Platform-specific: CSS, mouse events, web JSX.
16
17
  *
17
- * This follows the same pattern as DialDevTools - all colors, labels, descriptions,
18
- * and styling constants come from the shared core package.
18
+ * VISUAL PARITY: styled 1:1 against the native reference
19
+ * (devtools-floating-menu/src/floatingMenu/DevToolsSettingsModal.tsx, which
20
+ * renders inside JsModal + ModalHeader + TabSelector from @buoy-gg/shared-ui).
21
+ * shared-ui is RN-only, so its buoyColors palette and the native-only style
22
+ * values are inlined below with provenance comments.
19
23
  *
20
24
  * @platform React DOM Web (Vite, CRA, Next.js, Electron)
21
25
  */
22
26
 
27
+ // JsModal.web + storage keys via the consumer's shared-ui web shim — the
28
+ // settings sheet is a real JsModal on web now, same as native.
29
+
30
+ /** env(safe-area-inset-top) via a one-shot probe (native: useSafeAreaInsets). */function readTopSafeAreaInset() {
31
+ if (typeof document === 'undefined') return 0;
32
+ const probe = document.createElement('div');
33
+ probe.style.cssText = 'position:fixed;top:env(safe-area-inset-top);visibility:hidden;pointer-events:none';
34
+ document.body.appendChild(probe);
35
+ const top = probe.getBoundingClientRect().top;
36
+ document.body.removeChild(probe);
37
+ return Math.max(0, top);
38
+ }
39
+
40
+ // =============================
41
+ // Native palette (provenance)
42
+ // =============================
43
+
44
+ /**
45
+ * buoyColors from @buoy-gg/shared-ui (gameUIColors.ts) — the palette the
46
+ * native settings modal is styled with. shared-ui cannot be imported on web,
47
+ * so the values are inlined verbatim.
48
+ */
49
+ const buoy = {
50
+ base: '#121212',
51
+ card: '#1A1A1A',
52
+ hover: '#242424',
53
+ input: '#2A2A2A',
54
+ border: '#333333',
55
+ borderStrong: '#444444',
56
+ text: '#E0E0E0',
57
+ textSecondary: '#A0A0A0',
58
+ textMuted: '#888888',
59
+ primary: '#20C997',
60
+ success: '#20C997',
61
+ warning: '#FFA94D',
62
+ error: '#EF4444',
63
+ info: '#00B8E6'
64
+ };
65
+
23
66
  // =============================
24
67
  // Types
25
68
  // =============================
@@ -37,21 +80,30 @@ const webStorageAdapter = {
37
80
  // Icon Components (Web SVGs)
38
81
  // =============================
39
82
 
40
- const Laptop = ({
83
+ /** Fallback for shared-ui Layers icon (native debug-borders card icon). */
84
+ const Layers = ({
41
85
  size = 24,
42
86
  color = 'currentColor'
43
- }) => /*#__PURE__*/(0, _jsxRuntime.jsx)("svg", {
87
+ }) => /*#__PURE__*/(0, _jsxRuntime.jsxs)("svg", {
44
88
  width: size,
45
89
  height: size,
46
90
  viewBox: "0 0 24 24",
47
91
  fill: "none",
48
92
  stroke: color,
49
93
  strokeWidth: "2",
50
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
51
- d: "M20 16V7a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v9m16 0H4m16 0 1.28 2.55a1 1 0 0 1-.9 1.45H3.62a1 1 0 0 1-.9-1.45L4 16"
52
- })
94
+ strokeLinecap: "round",
95
+ strokeLinejoin: "round",
96
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
97
+ d: "M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83Z"
98
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
99
+ d: "m22 17.65-9.17 4.16a2 2 0 0 1-1.66 0L2 17.65"
100
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
101
+ d: "m22 12.65-9.17 4.16a2 2 0 0 1-1.66 0L2 12.65"
102
+ })]
53
103
  });
54
- const Database = ({
104
+
105
+ /** Fallback for shared-ui RenderCountIcon (native highlight-updates card icon). */
106
+ const Sparkles = ({
55
107
  size = 24,
56
108
  color = 'currentColor'
57
109
  }) => /*#__PURE__*/(0, _jsxRuntime.jsxs)("svg", {
@@ -61,18 +113,23 @@ const Database = ({
61
113
  fill: "none",
62
114
  stroke: color,
63
115
  strokeWidth: "2",
64
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("ellipse", {
65
- cx: "12",
66
- cy: "5",
67
- rx: "9",
68
- ry: "3"
116
+ strokeLinecap: "round",
117
+ strokeLinejoin: "round",
118
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
119
+ d: "M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"
69
120
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
70
- d: "M3 5V19A9 3 0 0 0 21 19V5"
121
+ d: "M20 3v4"
71
122
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
72
- d: "M3 12A9 3 0 0 0 21 12"
123
+ d: "M22 5h-4"
124
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
125
+ d: "M4 17v2"
126
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
127
+ d: "M5 18H3"
73
128
  })]
74
129
  });
75
- const Wifi = ({
130
+
131
+ /** Fallback for shared-ui SentryBugIcon (native sentry card icon, red). */
132
+ const AlertTriangle = ({
76
133
  size = 24,
77
134
  color = 'currentColor'
78
135
  }) => /*#__PURE__*/(0, _jsxRuntime.jsxs)("svg", {
@@ -82,20 +139,19 @@ const Wifi = ({
82
139
  fill: "none",
83
140
  stroke: color,
84
141
  strokeWidth: "2",
142
+ strokeLinecap: "round",
143
+ strokeLinejoin: "round",
85
144
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
86
- d: "M5 13a10 10 0 0 1 14 0"
145
+ d: "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"
87
146
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
88
- d: "M8.5 16.5a5 5 0 0 1 7 0"
147
+ d: "M12 9v4"
89
148
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
90
- d: "M2 8.82a15 15 0 0 1 20 0"
91
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)("line", {
92
- x1: "12",
93
- y1: "20",
94
- x2: "12.01",
95
- y2: "20"
149
+ d: "M12 17h.01"
96
150
  })]
97
151
  });
98
- const Search = ({
152
+
153
+ /** shared-ui Info icon (native default tool icon). */
154
+ const Info = ({
99
155
  size = 24,
100
156
  color = 'currentColor'
101
157
  }) => /*#__PURE__*/(0, _jsxRuntime.jsxs)("svg", {
@@ -105,15 +161,21 @@ const Search = ({
105
161
  fill: "none",
106
162
  stroke: color,
107
163
  strokeWidth: "2",
164
+ strokeLinecap: "round",
165
+ strokeLinejoin: "round",
108
166
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("circle", {
109
- cx: "11",
110
- cy: "11",
111
- r: "8"
167
+ cx: "12",
168
+ cy: "12",
169
+ r: "10"
112
170
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
113
- d: "m21 21-4.3-4.3"
171
+ d: "M12 16v-4"
172
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
173
+ d: "M12 8h.01"
114
174
  })]
115
175
  });
116
- const Map = ({
176
+
177
+ /** shared-ui Database icon (native storage status card icon). */
178
+ const Database = ({
117
179
  size = 24,
118
180
  color = 'currentColor'
119
181
  }) => /*#__PURE__*/(0, _jsxRuntime.jsxs)("svg", {
@@ -123,29 +185,44 @@ const Map = ({
123
185
  fill: "none",
124
186
  stroke: color,
125
187
  strokeWidth: "2",
126
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
127
- d: "M14.106 5.553a2 2 0 0 0 1.788 0l3.659-1.83A1 1 0 0 1 21 4.619v12.764a1 1 0 0 1-.553.894l-4.553 2.277a2 2 0 0 1-1.788 0l-4.212-2.106a2 2 0 0 0-1.788 0l-3.659 1.83A1 1 0 0 1 3 19.381V6.618a1 1 0 0 1 .553-.894l4.553-2.277a2 2 0 0 1 1.788 0z"
188
+ strokeLinecap: "round",
189
+ strokeLinejoin: "round",
190
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("ellipse", {
191
+ cx: "12",
192
+ cy: "5",
193
+ rx: "9",
194
+ ry: "3"
128
195
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
129
- d: "M15 5.764v15"
196
+ d: "M3 5V19A9 3 0 0 0 21 19V5"
130
197
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
131
- d: "M9 3.236v15"
198
+ d: "M3 12A9 3 0 0 0 21 12"
132
199
  })]
133
200
  });
134
- const Zap = ({
201
+
202
+ /** shared-ui CheckCircle2 icon (native storage badge check). */
203
+ const CheckCircle2 = ({
135
204
  size = 24,
136
205
  color = 'currentColor'
137
- }) => /*#__PURE__*/(0, _jsxRuntime.jsx)("svg", {
206
+ }) => /*#__PURE__*/(0, _jsxRuntime.jsxs)("svg", {
138
207
  width: size,
139
208
  height: size,
140
209
  viewBox: "0 0 24 24",
141
210
  fill: "none",
142
211
  stroke: color,
143
212
  strokeWidth: "2",
144
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
145
- d: "M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z"
146
- })
213
+ strokeLinecap: "round",
214
+ strokeLinejoin: "round",
215
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("circle", {
216
+ cx: "12",
217
+ cy: "12",
218
+ r: "10"
219
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
220
+ d: "m9 12 2 2 4-4"
221
+ })]
147
222
  });
148
- const Sparkles = ({
223
+
224
+ /** shared-ui FileText icon (native SAVED SETTINGS header icon). */
225
+ const FileText = ({
149
226
  size = 24,
150
227
  color = 'currentColor'
151
228
  }) => /*#__PURE__*/(0, _jsxRuntime.jsxs)("svg", {
@@ -155,37 +232,23 @@ const Sparkles = ({
155
232
  fill: "none",
156
233
  stroke: color,
157
234
  strokeWidth: "2",
235
+ strokeLinecap: "round",
236
+ strokeLinejoin: "round",
158
237
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
159
- d: "M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"
238
+ d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"
160
239
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
161
- d: "M20 3v4"
240
+ d: "M14 2v4a2 2 0 0 0 2 2h4"
162
241
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
163
- d: "M22 5h-4"
242
+ d: "M10 9H8"
164
243
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
165
- d: "M4 17v2"
244
+ d: "M16 13H8"
166
245
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
167
- d: "M5 18H3"
246
+ d: "M16 17H8"
168
247
  })]
169
248
  });
170
- const Square = ({
171
- size = 24,
172
- color = 'currentColor'
173
- }) => /*#__PURE__*/(0, _jsxRuntime.jsx)("svg", {
174
- width: size,
175
- height: size,
176
- viewBox: "0 0 24 24",
177
- fill: "none",
178
- stroke: color,
179
- strokeWidth: "2",
180
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)("rect", {
181
- width: "18",
182
- height: "18",
183
- x: "3",
184
- y: "3",
185
- rx: "2"
186
- })
187
- });
188
- const AlertTriangle = ({
249
+
250
+ /** shared-ui Trash2 icon (native CLEAR ALL SETTINGS button icon). */
251
+ const Trash2 = ({
189
252
  size = 24,
190
253
  color = 'currentColor'
191
254
  }) => /*#__PURE__*/(0, _jsxRuntime.jsxs)("svg", {
@@ -195,122 +258,193 @@ const AlertTriangle = ({
195
258
  fill: "none",
196
259
  stroke: color,
197
260
  strokeWidth: "2",
261
+ strokeLinecap: "round",
262
+ strokeLinejoin: "round",
198
263
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
199
- d: "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"
264
+ d: "M3 6h18"
200
265
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
201
- d: "M12 9v4"
266
+ d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6"
202
267
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
203
- d: "M12 17h.01"
268
+ d: "M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"
269
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("line", {
270
+ x1: "10",
271
+ x2: "10",
272
+ y1: "11",
273
+ y2: "17"
274
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("line", {
275
+ x1: "14",
276
+ x2: "14",
277
+ y1: "11",
278
+ y2: "17"
204
279
  })]
205
280
  });
206
- const SettingsIcon = ({
207
- size = 24,
281
+ function ChevronRightIcon({
282
+ size = 18,
208
283
  color = 'currentColor'
209
- }) => /*#__PURE__*/(0, _jsxRuntime.jsxs)("svg", {
210
- width: size,
211
- height: size,
212
- viewBox: "0 0 24 24",
213
- fill: "none",
214
- stroke: color,
215
- strokeWidth: "2",
216
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
217
- d: "M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"
218
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)("circle", {
219
- cx: "12",
220
- cy: "12",
221
- r: "3"
222
- })]
223
- });
224
- function ChevronRightIcon() {
284
+ }) {
225
285
  return /*#__PURE__*/(0, _jsxRuntime.jsx)("svg", {
226
- width: "18",
227
- height: "18",
286
+ width: size,
287
+ height: size,
228
288
  viewBox: "0 0 24 24",
229
289
  fill: "none",
230
- stroke: "currentColor",
290
+ stroke: color,
231
291
  strokeWidth: "2",
292
+ strokeLinecap: "round",
293
+ strokeLinejoin: "round",
232
294
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
233
295
  d: "M9 18l6-6-6-6"
234
296
  })
235
297
  });
236
298
  }
237
- function CloseIcon() {
299
+ function ChevronDownIcon({
300
+ size = 18,
301
+ color = 'currentColor'
302
+ }) {
238
303
  return /*#__PURE__*/(0, _jsxRuntime.jsx)("svg", {
239
- width: "20",
240
- height: "20",
304
+ width: size,
305
+ height: size,
241
306
  viewBox: "0 0 24 24",
242
307
  fill: "none",
243
- stroke: "currentColor",
308
+ stroke: color,
244
309
  strokeWidth: "2",
310
+ strokeLinecap: "round",
311
+ strokeLinejoin: "round",
245
312
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
246
- d: "M18 6L6 18M6 6l12 12"
313
+ d: "m6 9 6 6 6-6"
247
314
  })
248
315
  });
249
316
  }
250
317
 
251
- // Tool icon mapping using SVG components
318
+ /**
319
+ * Tool icon mapping — mirrors the native getToolIcon() switch in
320
+ * DevToolsSettingsModal.tsx. Real tool icons come from floating-tools-core
321
+ * (web-compatible); shared-ui-only icons (SentryBugIcon, WifiCircuitIcon,
322
+ * Layers, RenderCountIcon) use the closest web SVG fallback.
323
+ */
252
324
  function ToolIcon({
253
- toolId,
254
- color
325
+ toolId
255
326
  }) {
256
- const size = 16;
257
- const iconMap = {
258
- env: /*#__PURE__*/(0, _jsxRuntime.jsx)(Laptop, {
259
- size: size,
260
- color: color
261
- }),
262
- storage: /*#__PURE__*/(0, _jsxRuntime.jsx)(Database, {
263
- size: size,
264
- color: color
265
- }),
266
- network: /*#__PURE__*/(0, _jsxRuntime.jsx)(Wifi, {
267
- size: size,
268
- color: color
269
- }),
270
- query: /*#__PURE__*/(0, _jsxRuntime.jsx)(Search, {
271
- size: size,
272
- color: color
273
- }),
274
- 'route-events': /*#__PURE__*/(0, _jsxRuntime.jsx)(Map, {
275
- size: size,
276
- color: color
277
- }),
278
- routes: /*#__PURE__*/(0, _jsxRuntime.jsx)(Map, {
279
- size: size,
280
- color: color
281
- }),
282
- benchmark: /*#__PURE__*/(0, _jsxRuntime.jsx)(Zap, {
283
- size: size,
284
- color: color
285
- }),
286
- 'highlight-updates': /*#__PURE__*/(0, _jsxRuntime.jsx)(Sparkles, {
287
- size: size,
288
- color: color
289
- }),
290
- renders: /*#__PURE__*/(0, _jsxRuntime.jsx)(Sparkles, {
291
- size: size,
292
- color: color
293
- }),
294
- 'debug-borders': /*#__PURE__*/(0, _jsxRuntime.jsx)(Square, {
295
- size: size,
296
- color: color
297
- }),
298
- sentry: /*#__PURE__*/(0, _jsxRuntime.jsx)(AlertTriangle, {
299
- size: size,
300
- color: color
301
- }),
302
- environment: /*#__PURE__*/(0, _jsxRuntime.jsx)(SettingsIcon, {
303
- size: size,
304
- color: color
305
- }),
306
- redux: /*#__PURE__*/(0, _jsxRuntime.jsx)(_floatingToolsCore.ReduxIcon, {
307
- size: size
308
- })
327
+ const size = 16; // native: getToolIcon renders all icons at size 16
328
+ switch (toolId) {
329
+ case 'query':
330
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_floatingToolsCore.QueryIcon, {
331
+ size: size
332
+ });
333
+ case 'env':
334
+ case 'environment':
335
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_floatingToolsCore.EnvIcon, {
336
+ size: size
337
+ });
338
+ case 'sentry':
339
+ // native: SentryBugIcon colorPreset="red" noBackground
340
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(AlertTriangle, {
341
+ size: size,
342
+ color: buoy.error
343
+ });
344
+ case 'storage':
345
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_floatingToolsCore.StorageIcon, {
346
+ size: size
347
+ });
348
+ case 'wifi':
349
+ case 'query-wifi-toggle':
350
+ // native: WifiCircuitIcon colorPreset="green" (shared-ui only)
351
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_floatingToolsCore.WifiIcon, {
352
+ size: size
353
+ });
354
+ case 'route-events':
355
+ case 'routes':
356
+ // web alias for the same tool
357
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_floatingToolsCore.RoutesIcon, {
358
+ size: size
359
+ });
360
+ case 'network':
361
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_floatingToolsCore.NetworkIcon, {
362
+ size: size
363
+ });
364
+ case 'debug-borders':
365
+ // native: Layers size 16 color buoyColors.primary
366
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(Layers, {
367
+ size: size,
368
+ color: buoy.primary
369
+ });
370
+ case 'highlight-updates':
371
+ // native: RenderCountIcon size 16 color buoyColors.primary
372
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(Sparkles, {
373
+ size: size,
374
+ color: buoy.primary
375
+ });
376
+ case 'highlight-updates-modal':
377
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_floatingToolsCore.HighlighterIcon, {
378
+ size: size
379
+ });
380
+ case 'redux':
381
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_floatingToolsCore.ReduxIcon, {
382
+ size: size
383
+ });
384
+ case 'image-overlay':
385
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_floatingToolsCore.ImageOverlayIcon, {
386
+ size: size
387
+ });
388
+ case 'events':
389
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_floatingToolsCore.EventsIcon, {
390
+ size: size
391
+ });
392
+ case 'zustand':
393
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_floatingToolsCore.ZustandIcon, {
394
+ size: size
395
+ });
396
+ case 'jotai':
397
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_floatingToolsCore.JotaiIcon, {
398
+ size: size
399
+ });
400
+ default:
401
+ // native: Info size 16 color buoyColors.textSecondary
402
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(Info, {
403
+ size: size,
404
+ color: buoy.textSecondary
405
+ });
406
+ }
407
+ }
408
+
409
+ // =============================
410
+ // Toggle Pill (shared by cards)
411
+ // =============================
412
+
413
+ /**
414
+ * Native styles.pillToggle / pillToggleOn / pillToggleOff.
415
+ * onColor lets the global-settings cards use the success color like native.
416
+ */
417
+ function togglePillStyle(on, onColor, onStrongBorder) {
418
+ return {
419
+ paddingLeft: 14,
420
+ // native DevToolsSettingsModal.tsx pillToggle: paddingHorizontal 14
421
+ paddingRight: 14,
422
+ paddingTop: _floatingToolsReact.settingsStyles.toggle.paddingVertical,
423
+ paddingBottom: _floatingToolsReact.settingsStyles.toggle.paddingVertical,
424
+ borderRadius: 6,
425
+ // native pillToggle: borderRadius 6
426
+ borderWidth: _floatingToolsReact.settingsStyles.toggle.borderWidth,
427
+ borderStyle: 'solid',
428
+ minWidth: 48,
429
+ // native pillToggle: minWidth 48
430
+ boxSizing: 'border-box',
431
+ display: 'inline-flex',
432
+ alignItems: 'center',
433
+ justifyContent: 'center',
434
+ backgroundColor: on ? `${onColor}${onStrongBorder ? '33' : '20'}` : buoy.hover,
435
+ borderColor: on ? onStrongBorder ? `${onColor}88` : onColor : buoy.border,
436
+ color: on ? onColor : buoy.textMuted,
437
+ fontSize: _floatingToolsReact.settingsStyles.toggle.fontSize,
438
+ fontWeight: 600,
439
+ // native pillToggleText: fontWeight 600
440
+ letterSpacing: 0.5,
441
+ // native pillToggleText: letterSpacing 0.5
442
+ fontFamily: 'inherit',
443
+ cursor: 'pointer',
444
+ transition: 'all 150ms ease',
445
+ // native global-settings toggle: teal glow when ON (shadowRadius 8 / opacity 0.4)
446
+ boxShadow: on && onStrongBorder ? `0 0 8px ${onColor}66` : 'none'
309
447
  };
310
- return iconMap[toolId] || /*#__PURE__*/(0, _jsxRuntime.jsx)(SettingsIcon, {
311
- size: size,
312
- color: color
313
- });
314
448
  }
315
449
 
316
450
  // =============================
@@ -324,63 +458,54 @@ function ToolCard({
324
458
  availableTools,
325
459
  onToggle
326
460
  }) {
327
- const [isHovered, setIsHovered] = (0, _react.useState)(false);
328
- const color = (0, _floatingToolsReact.getToolColor)(toolId);
329
461
  const label = (0, _floatingToolsReact.getToolLabel)(toolId, availableTools);
330
462
  const description = (0, _floatingToolsReact.getToolDescription)(toolId, availableTools);
463
+
464
+ // native styles.glassCard / glassCardActive
331
465
  const cardStyle = {
332
466
  display: 'flex',
333
467
  flexDirection: 'row',
334
468
  alignItems: 'center',
335
- gap: _floatingToolsReact.settingsStyles.cardInner.gap,
336
- paddingTop: _floatingToolsReact.settingsStyles.card.paddingVertical,
337
- paddingBottom: _floatingToolsReact.settingsStyles.card.paddingVertical,
469
+ gap: 12,
470
+ // native glassCardInner: gap 12
471
+ paddingTop: 12,
472
+ // native glassCard: paddingVertical 12
473
+ paddingBottom: 12,
338
474
  paddingLeft: _floatingToolsReact.settingsStyles.card.paddingHorizontal,
339
475
  paddingRight: _floatingToolsReact.settingsStyles.card.paddingHorizontal,
340
- backgroundColor: _floatingToolsReact.settingsColors.cardBackground,
341
- borderRadius: _floatingToolsReact.settingsStyles.card.borderRadius,
476
+ backgroundColor: enabled ? `${buoy.primary}08` : buoy.card,
477
+ // native glassCardActive bg
478
+ borderRadius: 12,
479
+ // native glassCard: borderRadius 12
342
480
  borderWidth: _floatingToolsReact.settingsStyles.card.borderWidth,
343
481
  borderStyle: 'solid',
344
- borderColor: isHovered && !disabled ? _floatingToolsReact.settingsColors.cardBorderHover : _floatingToolsReact.settingsColors.cardBorder,
345
- marginBottom: _floatingToolsReact.settingsStyles.card.marginBottom,
482
+ borderColor: enabled ? `${buoy.primary}50` : buoy.border,
483
+ // native glassCardActive border
484
+ marginBottom: 8,
485
+ // native renderToolCard wrapper: marginBottom 8
346
486
  cursor: disabled ? 'not-allowed' : 'pointer',
347
- opacity: disabled ? 0.6 : 1,
348
- transition: 'all 150ms ease',
349
- boxShadow: enabled ? `0 0 6px ${color}33, 0 0 12px ${color}20` : 'none'
350
- };
351
- const toggleStyle = {
352
- paddingLeft: _floatingToolsReact.settingsStyles.toggle.paddingHorizontal,
353
- paddingRight: _floatingToolsReact.settingsStyles.toggle.paddingHorizontal,
354
- paddingTop: _floatingToolsReact.settingsStyles.toggle.paddingVertical,
355
- paddingBottom: _floatingToolsReact.settingsStyles.toggle.paddingVertical,
356
- borderRadius: _floatingToolsReact.settingsStyles.toggle.borderRadius,
357
- borderWidth: _floatingToolsReact.settingsStyles.toggle.borderWidth,
358
- borderStyle: 'solid',
359
- backgroundColor: enabled ? _floatingToolsReact.settingsColors.toggleOnBg(color) : _floatingToolsReact.settingsColors.toggleOffBg,
360
- borderColor: enabled ? _floatingToolsReact.settingsColors.toggleOnBorder(color) : _floatingToolsReact.settingsColors.toggleOffBorder,
361
- color: enabled ? color : _floatingToolsReact.settingsColors.toggleOffText,
362
- fontSize: _floatingToolsReact.settingsStyles.toggle.fontSize,
363
- fontWeight: _floatingToolsReact.settingsStyles.toggle.fontWeight,
364
- cursor: disabled ? 'not-allowed' : 'pointer',
365
- transition: 'all 150ms ease',
366
- boxShadow: enabled ? `0 0 8px ${color}66` : 'none'
487
+ opacity: disabled ? 0.5 : 1,
488
+ // native wrapper: opacity 0.5 when disabled
489
+ transition: 'all 150ms ease'
367
490
  };
368
491
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
369
492
  onClick: disabled ? undefined : onToggle,
370
- onMouseEnter: () => setIsHovered(true),
371
- onMouseLeave: () => setIsHovered(false),
372
493
  style: cardStyle,
373
494
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
374
495
  style: {
375
- width: _floatingToolsReact.settingsStyles.iconContainer.width,
376
- height: _floatingToolsReact.settingsStyles.iconContainer.height,
496
+ width: 32,
497
+ // native iconContainer: 32x32
498
+ height: 32,
499
+ borderRadius: 8,
500
+ // native iconContainer: borderRadius 8
501
+ backgroundColor: enabled ? `${buoy.primary}20` : buoy.hover,
377
502
  display: 'flex',
378
503
  alignItems: 'center',
379
- justifyContent: 'center'
504
+ justifyContent: 'center',
505
+ flexShrink: 0
380
506
  },
381
507
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(ToolIcon, {
382
- toolId: toolId,
383
- color: color
508
+ toolId: toolId
384
509
  })
385
510
  }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
386
511
  style: {
@@ -389,15 +514,18 @@ function ToolCard({
389
514
  },
390
515
  children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
391
516
  style: {
392
- color: _floatingToolsReact.settingsColors.text,
393
- fontWeight: _floatingToolsReact.settingsStyles.toolName.fontWeight,
517
+ color: buoy.text,
518
+ fontWeight: 600,
519
+ // native toolName: fontWeight 600
394
520
  fontSize: _floatingToolsReact.settingsStyles.toolName.fontSize
395
521
  },
396
522
  children: [label, disabled && ' (MAX 6)']
397
- }), description && /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
523
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
398
524
  style: {
399
- color: _floatingToolsReact.settingsColors.textMuted,
525
+ color: buoy.textMuted,
400
526
  fontSize: _floatingToolsReact.settingsStyles.toolDescription.fontSize,
527
+ marginTop: 2,
528
+ // native toolDescription: marginTop 2
401
529
  overflow: 'hidden',
402
530
  textOverflow: 'ellipsis',
403
531
  whiteSpace: 'nowrap'
@@ -410,17 +538,181 @@ function ToolCard({
410
538
  if (!disabled) onToggle();
411
539
  },
412
540
  disabled: disabled,
413
- style: toggleStyle,
414
- children: enabled ? 'ON' : 'OFF'
415
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
416
541
  style: {
417
- color: _floatingToolsReact.settingsColors.textMuted
542
+ ...togglePillStyle(enabled, buoy.primary, false),
543
+ cursor: disabled ? 'not-allowed' : 'pointer'
418
544
  },
419
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(ChevronRightIcon, {})
545
+ children: enabled ? 'ON' : 'OFF'
420
546
  })]
421
547
  });
422
548
  }
423
549
 
550
+ // =============================
551
+ // Global Setting Card (expandable, native renderGlobalSettingCard)
552
+ // =============================
553
+
554
+ function GlobalSettingCard({
555
+ configKey,
556
+ label,
557
+ category,
558
+ shortDescription,
559
+ fullDescription,
560
+ recommendation,
561
+ value,
562
+ onToggle
563
+ }) {
564
+ const [isExpanded, setIsExpanded] = (0, _react.useState)(false);
565
+
566
+ // native styles.expandableCard (+ expanded teal ring/glow/scale)
567
+ const cardStyle = {
568
+ backgroundColor: buoy.card,
569
+ borderRadius: 8,
570
+ borderWidth: isExpanded ? 2 : 1,
571
+ // native expanded: borderWidth 2
572
+ borderStyle: 'solid',
573
+ borderColor: isExpanded ? buoy.primary : buoy.border,
574
+ padding: 12,
575
+ cursor: 'pointer',
576
+ transition: 'all 150ms ease',
577
+ // native expanded: shadowColor primary, opacity 0.8, radius 20
578
+ boxShadow: isExpanded ? `0 0 20px ${buoy.primary}CC` : 'none',
579
+ transform: isExpanded ? 'scale(1.01)' : 'scale(1)' // native expanded: scale 1.01
580
+ };
581
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
582
+ style: {
583
+ marginBottom: 10
584
+ },
585
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
586
+ onClick: () => setIsExpanded(v => !v),
587
+ style: cardStyle,
588
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
589
+ style: {
590
+ display: 'flex',
591
+ alignItems: 'center',
592
+ gap: 12
593
+ },
594
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
595
+ style: {
596
+ backgroundColor: `${buoy.primary}20`,
597
+ border: `1px solid ${buoy.primary}40`,
598
+ borderRadius: 4,
599
+ padding: '4px 8px',
600
+ flexShrink: 0
601
+ },
602
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
603
+ style: {
604
+ fontSize: 10,
605
+ fontWeight: 700,
606
+ color: buoy.primary,
607
+ letterSpacing: 0.5
608
+ },
609
+ children: category
610
+ })
611
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
612
+ style: {
613
+ flex: 1,
614
+ minWidth: 0,
615
+ paddingLeft: 4,
616
+ paddingRight: 4
617
+ },
618
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
619
+ style: {
620
+ fontFamily: 'monospace',
621
+ fontSize: 12,
622
+ fontWeight: 700,
623
+ color: buoy.text
624
+ },
625
+ children: label
626
+ }), !isExpanded && /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
627
+ style: {
628
+ fontSize: 10,
629
+ color: buoy.textMuted,
630
+ marginTop: 2,
631
+ overflow: 'hidden',
632
+ textOverflow: 'ellipsis',
633
+ whiteSpace: 'nowrap'
634
+ },
635
+ children: shortDescription
636
+ })]
637
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
638
+ style: {
639
+ display: 'flex',
640
+ alignItems: 'center',
641
+ gap: 8,
642
+ flexShrink: 0
643
+ },
644
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("button", {
645
+ onClick: e => {
646
+ e.stopPropagation();
647
+ onToggle();
648
+ },
649
+ style: togglePillStyle(value, buoy.success, true),
650
+ children: value ? 'ON' : 'OFF'
651
+ }), isExpanded ?
652
+ /*#__PURE__*/
653
+ // native: ChevronDown size 18 color #7F91B2
654
+ (0, _jsxRuntime.jsx)(ChevronDownIcon, {
655
+ size: 18,
656
+ color: "#7F91B2"
657
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(ChevronRightIcon, {
658
+ size: 18,
659
+ color: "#7F91B2"
660
+ })]
661
+ })]
662
+ }), isExpanded && /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
663
+ style: {
664
+ marginTop: 12,
665
+ paddingTop: 12,
666
+ borderTop: `1px solid ${buoy.border}50`
667
+ },
668
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
669
+ style: {
670
+ marginBottom: 12
671
+ },
672
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
673
+ style: {
674
+ fontSize: 10,
675
+ fontWeight: 700,
676
+ color: buoy.primary,
677
+ letterSpacing: 1,
678
+ marginBottom: 6
679
+ },
680
+ children: "DESCRIPTION"
681
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
682
+ style: {
683
+ fontSize: 12,
684
+ color: buoy.textSecondary,
685
+ lineHeight: '18px'
686
+ },
687
+ children: fullDescription
688
+ })]
689
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
690
+ style: {
691
+ marginBottom: 12
692
+ },
693
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
694
+ style: {
695
+ fontSize: 10,
696
+ fontWeight: 700,
697
+ color: buoy.primary,
698
+ letterSpacing: 1,
699
+ marginBottom: 6
700
+ },
701
+ children: "RECOMMENDATION"
702
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
703
+ style: {
704
+ fontSize: 12,
705
+ color: buoy.textSecondary,
706
+ lineHeight: '18px'
707
+ },
708
+ children: recommendation
709
+ })]
710
+ })]
711
+ })]
712
+ })
713
+ }, configKey);
714
+ }
715
+
424
716
  // =============================
425
717
  // Main Component
426
718
  // =============================
@@ -435,7 +727,9 @@ function SettingsModal({
435
727
  onSettingsChange
436
728
  }) {
437
729
  const [activeTab, setActiveTab] = (0, _react.useState)('floating');
438
- const [isExiting, setIsExiting] = (0, _react.useState)(false);
730
+ const [isStorageExpanded, setIsStorageExpanded] = (0, _react.useState)(false);
731
+ const [savedKeys, setSavedKeys] = (0, _react.useState)([]);
732
+ const [clearSuccess, setClearSuccess] = (0, _react.useState)(false);
439
733
 
440
734
  // Use the shared settings hook
441
735
  const {
@@ -450,13 +744,9 @@ function SettingsModal({
450
744
  onSettingsChange
451
745
  });
452
746
 
453
- // Handle close with animation
747
+ // JsModal owns the close animation now — this is just the Escape path.
454
748
  const handleClose = (0, _react.useCallback)(() => {
455
- setIsExiting(true);
456
- setTimeout(() => {
457
- setIsExiting(false);
458
- onClose();
459
- }, 200);
749
+ onClose();
460
750
  }, [onClose]);
461
751
 
462
752
  // Escape key handler
@@ -470,255 +760,334 @@ function SettingsModal({
470
760
  document.addEventListener('keydown', handleKeyDown);
471
761
  return () => document.removeEventListener('keydown', handleKeyDown);
472
762
  }, [visible, handleClose]);
763
+
764
+ // Saved-settings key list for the storage card (mirrors the native
765
+ // persistentStorage.getAllKeys() list; on web, Buoy keys in localStorage).
766
+ (0, _react.useEffect)(() => {
767
+ if (!visible || !isStorageExpanded) return;
768
+ try {
769
+ const keys = Object.keys(localStorage).filter(key => key.startsWith('@react_buoy')).sort();
770
+ setSavedKeys(keys);
771
+ } catch {
772
+ setSavedKeys([]);
773
+ }
774
+ }, [visible, isStorageExpanded, clearSuccess, settings]);
775
+ const handleClearAll = (0, _react.useCallback)(() => {
776
+ // Same behavior as before (reset via the shared hook); the 2s "CLEARED"
777
+ // flash mirrors the native clear button feedback.
778
+ actions.resetToDefaults();
779
+ setClearSuccess(true);
780
+ setTimeout(() => setClearSuccess(false), 2000);
781
+ }, [actions]);
473
782
  if (!visible) return null;
474
783
 
475
784
  // Filter tabs - exclude 'pro' for now on web
476
785
  const displayTabs = _floatingToolsReact.settingsTabs.filter(tab => tab.key !== 'pro');
477
- const containerStyle = {
478
- position: 'fixed',
479
- inset: 0,
480
- zIndex: 10000,
481
- display: 'flex',
482
- alignItems: 'center',
483
- justifyContent: 'center'
484
- };
485
- const backdropStyle = {
486
- position: 'absolute',
487
- inset: 0,
488
- backgroundColor: _floatingToolsReact.settingsColors.backdrop,
489
- opacity: isExiting ? 0 : 1,
490
- transition: 'opacity 200ms ease'
491
- };
492
- const modalStyle = {
493
- position: 'relative',
494
- width: '90%',
495
- maxWidth: 450,
496
- maxHeight: '80vh',
497
- backgroundColor: _floatingToolsReact.settingsColors.panel,
498
- borderRadius: 12,
499
- border: `1px solid ${_floatingToolsReact.settingsColors.cardBorder}`,
500
- boxShadow: `0 24px 48px rgba(0, 0, 0, 0.5), 0 0 24px ${_floatingToolsReact.settingsColors.info}20`,
501
- display: 'flex',
502
- flexDirection: 'column',
503
- overflow: 'hidden',
504
- transform: isExiting ? 'scale(0.95)' : 'scale(1)',
505
- opacity: isExiting ? 0 : 1,
506
- transition: 'transform 200ms ease, opacity 200ms ease'
507
- };
508
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
509
- role: "dialog",
510
- "aria-label": "Settings",
511
- "aria-modal": "true",
512
- style: containerStyle,
513
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
514
- role: "button",
515
- "aria-label": "Close settings",
516
- tabIndex: 0,
517
- onClick: handleClose,
518
- style: backdropStyle
519
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
520
- style: modalStyle,
521
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
522
- style: {
523
- display: 'flex',
524
- alignItems: 'center',
525
- padding: '12px 16px',
526
- borderBottom: `1px solid ${_floatingToolsReact.settingsColors.cardBorder}`
527
- },
528
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
786
+
787
+ // Tab pill row rendered inside the JsModal header — native passes
788
+ // ModalHeader + TabSelector as header.customContent the same way.
789
+ const tabHeader = /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
790
+ style: {
791
+ display: 'flex',
792
+ alignItems: 'center',
793
+ paddingLeft: 4,
794
+ paddingRight: 28,
795
+ // clears JsModal's absolutely-positioned window controls
796
+ paddingBottom: 6
797
+ },
798
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
799
+ style: {
800
+ flex: 1,
801
+ display: 'flex',
802
+ backgroundColor: buoy.hover,
803
+ borderRadius: 6,
804
+ padding: 2,
805
+ border: `1px solid ${buoy.border}`,
806
+ height: 28,
807
+ boxSizing: 'border-box'
808
+ },
809
+ children: displayTabs.map(tab => {
810
+ const isActive = activeTab === tab.key;
811
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)("button", {
812
+ onClick: () => setActiveTab(tab.key),
529
813
  style: {
530
814
  flex: 1,
531
- display: 'flex',
532
- backgroundColor: _floatingToolsReact.settingsColors.panel,
533
- borderRadius: 6,
534
- padding: 2,
535
- border: `1px solid ${_floatingToolsReact.settingsColors.cardBorder}`
536
- },
537
- children: displayTabs.map(tab => {
538
- const isActive = activeTab === tab.key;
539
- return /*#__PURE__*/(0, _jsxRuntime.jsx)("button", {
540
- onClick: () => setActiveTab(tab.key),
541
- style: {
542
- flex: 1,
543
- paddingLeft: _floatingToolsReact.settingsStyles.tab.paddingHorizontal,
544
- paddingRight: _floatingToolsReact.settingsStyles.tab.paddingHorizontal,
545
- paddingTop: _floatingToolsReact.settingsStyles.tab.paddingVertical,
546
- paddingBottom: _floatingToolsReact.settingsStyles.tab.paddingVertical,
547
- borderRadius: _floatingToolsReact.settingsStyles.tab.borderRadius,
548
- backgroundColor: isActive ? _floatingToolsReact.settingsColors.tabActiveBg : _floatingToolsReact.settingsColors.tabInactiveBg,
549
- border: isActive ? `1px solid ${_floatingToolsReact.settingsColors.tabActiveBorder}40` : '1px solid transparent',
550
- color: isActive ? _floatingToolsReact.settingsColors.info : _floatingToolsReact.settingsColors.tabInactiveText,
551
- fontSize: _floatingToolsReact.settingsStyles.tab.fontSize,
552
- fontWeight: _floatingToolsReact.settingsStyles.tab.fontWeight,
553
- letterSpacing: _floatingToolsReact.settingsStyles.tab.letterSpacing,
554
- cursor: 'pointer',
555
- transition: 'all 150ms ease',
556
- textTransform: 'uppercase',
557
- fontFamily: 'monospace'
558
- },
559
- children: tab.label
560
- }, tab.key);
561
- })
562
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)("button", {
563
- "aria-label": "Close",
564
- onClick: handleClose,
565
- style: {
566
- marginLeft: 12,
567
- background: 'none',
568
- border: 'none',
569
- padding: 4,
815
+ marginLeft: 1,
816
+ // native TabSelector tabButton: marginHorizontal 1
817
+ marginRight: 1,
818
+ paddingLeft: _floatingToolsReact.settingsStyles.tab.paddingHorizontal,
819
+ paddingRight: _floatingToolsReact.settingsStyles.tab.paddingHorizontal,
820
+ paddingTop: 3,
821
+ // native TabSelector tabButton: paddingVertical 3
822
+ paddingBottom: 3,
823
+ borderRadius: _floatingToolsReact.settingsStyles.tab.borderRadius,
824
+ // native tabButtonActive: bg primary+20, 1px primary border
825
+ backgroundColor: isActive ? `${buoy.primary}20` : 'transparent',
826
+ border: isActive ? `1px solid ${buoy.primary}` : '1px solid transparent',
827
+ color: isActive ? buoy.primary : buoy.textMuted,
828
+ fontSize: _floatingToolsReact.settingsStyles.tab.fontSize,
829
+ fontWeight: _floatingToolsReact.settingsStyles.tab.fontWeight,
830
+ letterSpacing: _floatingToolsReact.settingsStyles.tab.letterSpacing,
570
831
  cursor: 'pointer',
571
- color: _floatingToolsReact.settingsColors.textMuted,
832
+ transition: 'all 150ms ease',
833
+ textTransform: 'uppercase',
834
+ fontFamily: 'inherit',
835
+ // native TabSelector uses the system font
836
+ boxSizing: 'border-box',
572
837
  display: 'flex',
573
838
  alignItems: 'center',
574
839
  justifyContent: 'center'
575
840
  },
576
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(CloseIcon, {})
577
- })]
578
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
841
+ children: tab.label
842
+ }, tab.key);
843
+ })
844
+ })
845
+ });
846
+
847
+ // native: initialHeight = screenHeight / 3, floating starts centered at
848
+ // width min(screenWidth - 32, 400), y = insets.top + 20.
849
+ const modalWidth = Math.min(window.innerWidth - 32, 400);
850
+ const topInset = readTopSafeAreaInset();
851
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.JsModal, {
852
+ visible: visible,
853
+ onClose: handleClose,
854
+ header: {
855
+ showToggleButton: false,
856
+ customContent: tabHeader
857
+ },
858
+ initialMode: "bottomSheet",
859
+ persistenceKey: _sharedUi.devToolsStorageKeys.settings.root(),
860
+ enablePersistence: true,
861
+ initialHeight: Math.floor(window.innerHeight * 0.33),
862
+ initialFloatingPosition: {
863
+ x: (window.innerWidth - modalWidth) / 2,
864
+ y: topInset + 20 // native: insets.top + 20
865
+ },
866
+ zIndex: 10001 // above the dial (10000) — settings opens over it
867
+ ,
868
+ disableScrollWrapper: true,
869
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
870
+ style: {
871
+ flex: 1,
872
+ minHeight: 0,
873
+ overflow: 'auto',
874
+ backgroundColor: buoy.base,
875
+ paddingTop: _floatingToolsReact.settingsStyles.scrollContent.paddingTop,
876
+ paddingBottom: _floatingToolsReact.settingsStyles.scrollContent.paddingBottom,
877
+ paddingLeft: _floatingToolsReact.settingsStyles.section.marginHorizontal,
878
+ paddingRight: _floatingToolsReact.settingsStyles.section.marginHorizontal
879
+ },
880
+ children: isLoading ? /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
579
881
  style: {
580
- flex: 1,
581
- overflow: 'auto',
582
- paddingTop: _floatingToolsReact.settingsStyles.scrollContent.paddingTop,
583
- paddingBottom: _floatingToolsReact.settingsStyles.scrollContent.paddingBottom,
584
- paddingLeft: _floatingToolsReact.settingsStyles.section.marginHorizontal,
585
- paddingRight: _floatingToolsReact.settingsStyles.section.marginHorizontal
882
+ display: 'flex',
883
+ alignItems: 'center',
884
+ justifyContent: 'center',
885
+ padding: 40,
886
+ color: buoy.textMuted,
887
+ fontSize: 12
586
888
  },
587
- children: isLoading ? /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
588
- style: {
589
- display: 'flex',
590
- alignItems: 'center',
591
- justifyContent: 'center',
592
- padding: 40,
593
- color: _floatingToolsReact.settingsColors.textMuted
594
- },
595
- children: "Loading settings..."
596
- }) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
597
- children: [activeTab === 'floating' && /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
598
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
599
- style: {
600
- fontSize: _floatingToolsReact.settingsStyles.sectionTitle.fontSize,
601
- fontWeight: _floatingToolsReact.settingsStyles.sectionTitle.fontWeight,
602
- letterSpacing: _floatingToolsReact.settingsStyles.sectionTitle.letterSpacing,
603
- textTransform: _floatingToolsReact.settingsStyles.sectionTitle.textTransform,
604
- color: _floatingToolsReact.settingsColors.textMuted,
605
- marginBottom: _floatingToolsReact.settingsStyles.sectionHeader.marginBottom
606
- },
607
- children: "CONFIGURE FLOATING TOOLBAR ITEMS"
608
- }), Object.entries(settings.floatingTools).map(([id, enabled]) => /*#__PURE__*/(0, _jsxRuntime.jsx)(ToolCard, {
609
- toolId: id,
610
- enabled: enabled,
611
- availableTools: availableTools,
612
- onToggle: () => id === 'environment' ? actions.toggleEnvironment() : actions.toggleFloatingTool(id)
613
- }, id))]
614
- }), activeTab === 'settings' && /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
615
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
889
+ children: "Loading settings..."
890
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
891
+ children: [activeTab === 'floating' && /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
892
+ children: Object.entries(settings.floatingTools).map(([id, enabled]) => /*#__PURE__*/(0, _jsxRuntime.jsx)(ToolCard, {
893
+ toolId: id,
894
+ enabled: enabled,
895
+ availableTools: availableTools,
896
+ onToggle: () => id === 'environment' ? actions.toggleEnvironment() : actions.toggleFloatingTool(id)
897
+ }, id))
898
+ }), activeTab === 'settings' && /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
899
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
900
+ style: {
901
+ backgroundColor: buoy.card,
902
+ borderRadius: 8,
903
+ border: `1px solid ${isStorageExpanded ? `${buoy.success}60` : buoy.border}`,
904
+ padding: 12,
905
+ marginBottom: 10,
906
+ transition: 'border-color 150ms ease'
907
+ },
908
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
909
+ onClick: () => setIsStorageExpanded(v => !v),
616
910
  style: {
617
- fontSize: _floatingToolsReact.settingsStyles.sectionTitle.fontSize,
618
- fontWeight: _floatingToolsReact.settingsStyles.sectionTitle.fontWeight,
619
- letterSpacing: _floatingToolsReact.settingsStyles.sectionTitle.letterSpacing,
620
- textTransform: _floatingToolsReact.settingsStyles.sectionTitle.textTransform,
621
- color: _floatingToolsReact.settingsColors.textMuted,
622
- marginBottom: _floatingToolsReact.settingsStyles.sectionHeader.marginBottom
911
+ display: 'flex',
912
+ alignItems: 'center',
913
+ gap: 12,
914
+ marginBottom: 8,
915
+ cursor: 'pointer'
623
916
  },
624
- children: "GLOBAL SETTINGS"
625
- }), _floatingToolsReact.globalSettingsConfig.map(config => {
626
- const value = settings.globalSettings?.[config.key] ?? false;
627
- const color = _floatingToolsReact.settingsColors.success;
628
- return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
917
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
629
918
  style: {
630
- padding: 12,
631
- backgroundColor: _floatingToolsReact.settingsColors.cardBackground,
919
+ width: 36,
920
+ height: 36,
632
921
  borderRadius: 8,
633
- border: `1px solid ${_floatingToolsReact.settingsColors.cardBorder}`,
634
- marginBottom: 10
922
+ backgroundColor: `${buoy.success}15`,
923
+ display: 'flex',
924
+ alignItems: 'center',
925
+ justifyContent: 'center',
926
+ flexShrink: 0
635
927
  },
636
- children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
928
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(Database, {
929
+ size: 18,
930
+ color: buoy.success
931
+ })
932
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
933
+ style: {
934
+ flex: 1,
935
+ minWidth: 0
936
+ },
937
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
938
+ style: {
939
+ fontSize: 10,
940
+ fontWeight: 700,
941
+ color: buoy.textMuted,
942
+ letterSpacing: 1,
943
+ marginBottom: 4
944
+ },
945
+ children: "STORAGE TYPE"
946
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
637
947
  style: {
638
948
  display: 'flex',
639
949
  alignItems: 'center',
640
- gap: 12
950
+ gap: 6
641
951
  },
642
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
952
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
643
953
  style: {
644
- backgroundColor: `${_floatingToolsReact.settingsColors.info}20`,
645
- border: `1px solid ${_floatingToolsReact.settingsColors.info}40`,
954
+ padding: '4px 8px',
646
955
  borderRadius: 4,
647
- padding: '4px 8px'
648
- },
649
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
650
- style: {
651
- fontSize: 10,
652
- fontWeight: 700,
653
- color: _floatingToolsReact.settingsColors.info,
654
- letterSpacing: 0.5
655
- },
656
- children: config.category
657
- })
658
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
659
- style: {
660
- flex: 1
956
+ border: `1px solid ${buoy.success}60`,
957
+ backgroundColor: `${buoy.success}20`,
958
+ color: buoy.success,
959
+ fontSize: 11,
960
+ fontWeight: 700,
961
+ letterSpacing: 0.5
661
962
  },
662
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
663
- style: {
664
- fontFamily: 'monospace',
665
- fontSize: 12,
666
- fontWeight: 700,
667
- color: _floatingToolsReact.settingsColors.text
668
- },
669
- children: config.label
670
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
671
- style: {
672
- fontSize: 10,
673
- color: _floatingToolsReact.settingsColors.textMuted,
674
- marginTop: 2
675
- },
676
- children: config.shortDescription
677
- })]
678
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)("button", {
679
- onClick: () => actions.toggleGlobalSetting(config.key),
963
+ children: "LOCAL STORAGE"
964
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(CheckCircle2, {
965
+ size: 14,
966
+ color: buoy.success
967
+ })]
968
+ })]
969
+ }), isStorageExpanded ? /*#__PURE__*/(0, _jsxRuntime.jsx)(ChevronDownIcon, {
970
+ size: 18,
971
+ color: buoy.textMuted
972
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(ChevronRightIcon, {
973
+ size: 18,
974
+ color: buoy.textMuted
975
+ })]
976
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
977
+ style: {
978
+ fontSize: 11,
979
+ color: buoy.textMuted,
980
+ lineHeight: '16px',
981
+ marginBottom: 12
982
+ },
983
+ children: "Settings persist in the browser's localStorage and survive page reloads."
984
+ }), isStorageExpanded && /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
985
+ style: {
986
+ marginTop: 12,
987
+ paddingTop: 12,
988
+ borderTop: `1px solid ${buoy.border}50`,
989
+ marginBottom: 12
990
+ },
991
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
992
+ style: {
993
+ display: 'flex',
994
+ alignItems: 'center',
995
+ gap: 8,
996
+ marginBottom: 10
997
+ },
998
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(FileText, {
999
+ size: 14,
1000
+ color: buoy.primary
1001
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
1002
+ style: {
1003
+ fontSize: 10,
1004
+ fontWeight: 700,
1005
+ color: buoy.primary,
1006
+ letterSpacing: 1,
1007
+ flex: 1
1008
+ },
1009
+ children: "SAVED SETTINGS"
1010
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", {
1011
+ style: {
1012
+ fontSize: 10,
1013
+ color: buoy.textMuted
1014
+ },
1015
+ children: [savedKeys.length, " keys"]
1016
+ })]
1017
+ }), savedKeys.length === 0 ? /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
1018
+ style: {
1019
+ fontSize: 11,
1020
+ color: buoy.textMuted,
1021
+ fontStyle: 'italic',
1022
+ padding: '8px 0'
1023
+ },
1024
+ children: "No settings saved yet"
1025
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
1026
+ style: {
1027
+ maxHeight: 150,
1028
+ overflow: 'auto'
1029
+ },
1030
+ children: savedKeys.map(key => /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
1031
+ style: {
1032
+ backgroundColor: buoy.hover,
1033
+ borderRadius: 4,
1034
+ padding: '6px 8px',
1035
+ border: `1px solid ${buoy.border}50`,
1036
+ marginBottom: 4
1037
+ },
1038
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
680
1039
  style: {
681
- paddingLeft: _floatingToolsReact.settingsStyles.toggle.paddingHorizontal,
682
- paddingRight: _floatingToolsReact.settingsStyles.toggle.paddingHorizontal,
683
- paddingTop: _floatingToolsReact.settingsStyles.toggle.paddingVertical,
684
- paddingBottom: _floatingToolsReact.settingsStyles.toggle.paddingVertical,
685
- borderRadius: _floatingToolsReact.settingsStyles.toggle.borderRadius,
686
- borderWidth: _floatingToolsReact.settingsStyles.toggle.borderWidth,
687
- borderStyle: 'solid',
688
- backgroundColor: value ? _floatingToolsReact.settingsColors.toggleOnBg(color) : _floatingToolsReact.settingsColors.toggleOffBg,
689
- borderColor: value ? _floatingToolsReact.settingsColors.toggleOnBorder(color) : _floatingToolsReact.settingsColors.toggleOffBorder,
690
- color: value ? color : _floatingToolsReact.settingsColors.toggleOffText,
691
- fontSize: _floatingToolsReact.settingsStyles.toggle.fontSize,
692
- fontWeight: _floatingToolsReact.settingsStyles.toggle.fontWeight,
693
- cursor: 'pointer',
694
- transition: 'all 150ms ease',
695
- boxShadow: value ? `0 0 8px ${color}66` : 'none'
1040
+ fontSize: 11,
1041
+ color: buoy.textSecondary,
1042
+ fontFamily: 'monospace',
1043
+ overflow: 'hidden',
1044
+ textOverflow: 'ellipsis',
1045
+ whiteSpace: 'nowrap'
696
1046
  },
697
- children: value ? 'ON' : 'OFF'
698
- })]
699
- })
700
- }, config.key);
701
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)("button", {
702
- onClick: () => actions.resetToDefaults(),
1047
+ children: key.replace('@react_buoy_', '')
1048
+ })
1049
+ }, key))
1050
+ })]
1051
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("button", {
1052
+ onClick: handleClearAll,
703
1053
  style: {
704
1054
  width: '100%',
705
- padding: '12px 16px',
706
- marginTop: 8,
1055
+ display: 'flex',
1056
+ alignItems: 'center',
1057
+ justifyContent: 'center',
1058
+ gap: 8,
1059
+ padding: '10px 16px',
707
1060
  borderRadius: 6,
708
- border: `1px solid ${_floatingToolsReact.settingsColors.error}40`,
709
- backgroundColor: `${_floatingToolsReact.settingsColors.error}15`,
710
- color: _floatingToolsReact.settingsColors.error,
1061
+ border: `1px solid ${clearSuccess ? `${buoy.success}40` : `${buoy.error}40`}`,
1062
+ backgroundColor: clearSuccess ? `${buoy.success}15` : `${buoy.error}15`,
1063
+ color: clearSuccess ? buoy.success : buoy.error,
711
1064
  fontSize: 12,
712
1065
  fontWeight: 700,
713
1066
  letterSpacing: 0.5,
1067
+ fontFamily: 'inherit',
714
1068
  cursor: 'pointer',
715
1069
  transition: 'all 150ms ease'
716
1070
  },
717
- children: "CLEAR ALL SETTINGS"
1071
+ children: [clearSuccess ? /*#__PURE__*/(0, _jsxRuntime.jsx)(CheckCircle2, {
1072
+ size: 14,
1073
+ color: buoy.success
1074
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(Trash2, {
1075
+ size: 14,
1076
+ color: buoy.error
1077
+ }), clearSuccess ? 'CLEARED' : 'CLEAR ALL SETTINGS']
718
1078
  })]
719
- })]
720
- })
721
- })]
722
- })]
1079
+ }), _floatingToolsReact.globalSettingsConfig.map(config => /*#__PURE__*/(0, _jsxRuntime.jsx)(GlobalSettingCard, {
1080
+ configKey: config.key,
1081
+ label: config.label,
1082
+ category: config.category,
1083
+ shortDescription: config.shortDescription,
1084
+ fullDescription: config.fullDescription,
1085
+ recommendation: config.recommendation,
1086
+ value: settings.globalSettings?.[config.key] ?? false,
1087
+ onToggle: () => actions.toggleGlobalSetting(config.key)
1088
+ }, config.key))]
1089
+ })]
1090
+ })
1091
+ })
723
1092
  });
724
1093
  }