@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.
- package/lib/commonjs/floatingMenu/AppHost.js +18 -0
- package/lib/commonjs/floatingMenu/AppHost.web.js +359 -0
- package/lib/commonjs/floatingMenu/AppHostLogic.js +6 -0
- package/lib/commonjs/floatingMenu/DevToolsSettingsModal.web.js +787 -418
- package/lib/commonjs/floatingMenu/FloatingDevTools.js +1 -1
- package/lib/commonjs/floatingMenu/FloatingDevTools.web.js +244 -36
- package/lib/commonjs/floatingMenu/FloatingMenu.js +4 -3
- package/lib/commonjs/floatingMenu/MinimizedToolsContext.js +2 -3
- package/lib/commonjs/floatingMenu/MinimizedToolsStack.web.js +287 -0
- package/lib/commonjs/floatingMenu/ToolHost.js +264 -0
- package/lib/commonjs/floatingMenu/allToolsRegistry.js +7 -0
- package/lib/commonjs/floatingMenu/autoDiscoverPresets.js +32 -0
- package/lib/commonjs/floatingMenu/autoExternalSync.js +18 -0
- package/lib/commonjs/floatingMenu/dial/DialDevTools.js +9 -5
- package/lib/commonjs/floatingMenu/dial/DialDevTools.web.js +373 -231
- package/lib/commonjs/floatingMenu/dial/DialIcon.js +25 -3
- package/lib/commonjs/floatingMenu/dial/OnboardingTooltip.js +1 -1
- package/lib/commonjs/floatingMenu/dial/OnboardingTooltip.web.js +154 -0
- package/lib/commonjs/floatingMenu/dial/onboardingConstants.web.js +34 -0
- package/lib/commonjs/floatingMenu/floatingTools.js +3 -3
- package/lib/commonjs/floatingMenu/floatingTools.web.js +191 -28
- package/lib/commonjs/index.js +29 -2
- package/lib/commonjs/index.web.js +19 -0
- package/lib/commonjs/toolkit.js +427 -0
- package/lib/commonjs/utils/autoDiscoverPresets.web.js +50 -5
- package/lib/module/floatingMenu/AppHost.js +18 -0
- package/lib/module/floatingMenu/AppHost.web.js +351 -0
- package/lib/module/floatingMenu/AppHostLogic.js +6 -0
- package/lib/module/floatingMenu/DevToolsSettingsModal.web.js +792 -422
- package/lib/module/floatingMenu/FloatingDevTools.js +2 -2
- package/lib/module/floatingMenu/FloatingDevTools.web.js +247 -38
- package/lib/module/floatingMenu/FloatingMenu.js +4 -3
- package/lib/module/floatingMenu/MinimizedToolsContext.js +2 -3
- package/lib/module/floatingMenu/MinimizedToolsStack.web.js +284 -0
- package/lib/module/floatingMenu/ToolHost.js +256 -0
- package/lib/module/floatingMenu/allToolsRegistry.js +8 -1
- package/lib/module/floatingMenu/autoDiscoverPresets.js +32 -0
- package/lib/module/floatingMenu/autoExternalSync.js +18 -0
- package/lib/module/floatingMenu/dial/DialDevTools.js +10 -6
- package/lib/module/floatingMenu/dial/DialDevTools.web.js +375 -233
- package/lib/module/floatingMenu/dial/DialIcon.js +26 -4
- package/lib/module/floatingMenu/dial/OnboardingTooltip.js +1 -1
- package/lib/module/floatingMenu/dial/OnboardingTooltip.web.js +149 -0
- package/lib/module/floatingMenu/dial/onboardingConstants.web.js +27 -0
- package/lib/module/floatingMenu/floatingTools.js +3 -3
- package/lib/module/floatingMenu/floatingTools.web.js +190 -28
- package/lib/module/index.js +8 -2
- package/lib/module/index.web.js +5 -0
- package/lib/module/toolkit.js +45 -0
- package/lib/module/utils/autoDiscoverPresets.web.js +53 -7
- package/lib/typescript/commonjs/floatingMenu/AppHost.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/AppHost.web.d.ts +38 -0
- package/lib/typescript/commonjs/floatingMenu/AppHost.web.d.ts.map +1 -0
- package/lib/typescript/commonjs/floatingMenu/AppHostLogic.d.ts +24 -1
- package/lib/typescript/commonjs/floatingMenu/AppHostLogic.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/DevToolsSettingsModal.web.d.ts +5 -2
- package/lib/typescript/commonjs/floatingMenu/DevToolsSettingsModal.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/FloatingDevTools.web.d.ts +2 -14
- package/lib/typescript/commonjs/floatingMenu/FloatingDevTools.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/FloatingMenu.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/MinimizedToolsContext.d.ts +2 -20
- package/lib/typescript/commonjs/floatingMenu/MinimizedToolsContext.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/MinimizedToolsStack.web.d.ts +21 -0
- package/lib/typescript/commonjs/floatingMenu/MinimizedToolsStack.web.d.ts.map +1 -0
- package/lib/typescript/commonjs/floatingMenu/ToolHost.d.ts +72 -0
- package/lib/typescript/commonjs/floatingMenu/ToolHost.d.ts.map +1 -0
- package/lib/typescript/commonjs/floatingMenu/allToolsRegistry.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/autoDiscoverPresets.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/autoExternalSync.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/defaultConfig.d.ts +1 -1
- package/lib/typescript/commonjs/floatingMenu/defaultConfig.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 +16 -2
- package/lib/typescript/commonjs/floatingMenu/dial/DialDevTools.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/dial/DialIcon.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/dial/OnboardingTooltip.web.d.ts +9 -0
- package/lib/typescript/commonjs/floatingMenu/dial/OnboardingTooltip.web.d.ts.map +1 -0
- package/lib/typescript/commonjs/floatingMenu/dial/onboardingConstants.web.d.ts +13 -0
- package/lib/typescript/commonjs/floatingMenu/dial/onboardingConstants.web.d.ts.map +1 -0
- package/lib/typescript/commonjs/floatingMenu/floatingTools.web.d.ts +29 -2
- package/lib/typescript/commonjs/floatingMenu/floatingTools.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/types.d.ts +30 -1
- package/lib/typescript/commonjs/floatingMenu/types.d.ts.map +1 -1
- package/lib/typescript/commonjs/index.d.ts +2 -0
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/index.web.d.ts +1 -0
- package/lib/typescript/commonjs/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/toolkit.d.ts +22 -0
- package/lib/typescript/commonjs/toolkit.d.ts.map +1 -0
- package/lib/typescript/commonjs/utils/autoDiscoverPresets.web.d.ts +2 -0
- package/lib/typescript/commonjs/utils/autoDiscoverPresets.web.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/AppHost.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/AppHost.web.d.ts +38 -0
- package/lib/typescript/module/floatingMenu/AppHost.web.d.ts.map +1 -0
- package/lib/typescript/module/floatingMenu/AppHostLogic.d.ts +24 -1
- package/lib/typescript/module/floatingMenu/AppHostLogic.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/DevToolsSettingsModal.web.d.ts +5 -2
- package/lib/typescript/module/floatingMenu/DevToolsSettingsModal.web.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/FloatingDevTools.web.d.ts +2 -14
- package/lib/typescript/module/floatingMenu/FloatingDevTools.web.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/FloatingMenu.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/MinimizedToolsContext.d.ts +2 -20
- package/lib/typescript/module/floatingMenu/MinimizedToolsContext.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/MinimizedToolsStack.web.d.ts +21 -0
- package/lib/typescript/module/floatingMenu/MinimizedToolsStack.web.d.ts.map +1 -0
- package/lib/typescript/module/floatingMenu/ToolHost.d.ts +72 -0
- package/lib/typescript/module/floatingMenu/ToolHost.d.ts.map +1 -0
- package/lib/typescript/module/floatingMenu/allToolsRegistry.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/autoDiscoverPresets.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/autoExternalSync.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/defaultConfig.d.ts +1 -1
- package/lib/typescript/module/floatingMenu/defaultConfig.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 +16 -2
- package/lib/typescript/module/floatingMenu/dial/DialDevTools.web.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/dial/DialIcon.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/dial/OnboardingTooltip.web.d.ts +9 -0
- package/lib/typescript/module/floatingMenu/dial/OnboardingTooltip.web.d.ts.map +1 -0
- package/lib/typescript/module/floatingMenu/dial/onboardingConstants.web.d.ts +13 -0
- package/lib/typescript/module/floatingMenu/dial/onboardingConstants.web.d.ts.map +1 -0
- package/lib/typescript/module/floatingMenu/floatingTools.web.d.ts +29 -2
- package/lib/typescript/module/floatingMenu/floatingTools.web.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/types.d.ts +30 -1
- package/lib/typescript/module/floatingMenu/types.d.ts.map +1 -1
- package/lib/typescript/module/index.d.ts +2 -0
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/index.web.d.ts +1 -0
- package/lib/typescript/module/index.web.d.ts.map +1 -1
- package/lib/typescript/module/toolkit.d.ts +22 -0
- package/lib/typescript/module/toolkit.d.ts.map +1 -0
- package/lib/typescript/module/utils/autoDiscoverPresets.web.d.ts +2 -0
- package/lib/typescript/module/utils/autoDiscoverPresets.web.d.ts.map +1 -1
- package/package.json +5 -5
|
@@ -6,16 +6,22 @@
|
|
|
6
6
|
* Uses shared layout calculations, styling, and animation config from @buoy-gg/floating-tools-core.
|
|
7
7
|
* Platform-specific: CSS animations, mouse events, web JSX.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
9
|
+
* Visuals mirror the native DialDevTools.tsx exactly — values that never made
|
|
10
|
+
* it into the shared dial.ts are inlined here with provenance comments.
|
|
10
11
|
*
|
|
11
12
|
* @platform React DOM Web (Vite, CRA, Next.js, Electron)
|
|
12
13
|
*/
|
|
13
14
|
|
|
14
15
|
import { useState, useEffect, useMemo, useRef, useCallback } from 'react';
|
|
15
|
-
import { getDialLayout, getAllIconPositions, getGridLineRotations, getIconStaggerInputRange, MAX_DIAL_SLOTS, dialAnimationConfig, getDialCSSKeyframesString, getDialCSSAnimationStyles, dialColors, dialStyles } from '@buoy-gg/floating-tools-react';
|
|
16
|
+
import { getDialLayout, getAllIconPositions, getGridLineRotations, getIconStaggerInputRange, MAX_DIAL_SLOTS, DIAL_ICON_SIZE, dialAnimationConfig, getDialCSSKeyframesString, getDialCSSAnimationStyles, dialColors, dialStyles, withAlpha, floatingToolsColors } from '@buoy-gg/floating-tools-react';
|
|
17
|
+
import { persistentStorage } from '@buoy-gg/shared-ui';
|
|
18
|
+
import { OnboardingTooltip } from "./OnboardingTooltip.web.js";
|
|
16
19
|
|
|
17
|
-
//
|
|
20
|
+
// native DialDevTools.tsx SETTINGS_TOOLTIP_KEY
|
|
18
21
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
22
|
+
const SETTINGS_TOOLTIP_KEY = '@react_buoy_settings_tooltip_shown';
|
|
23
|
+
|
|
24
|
+
// Inject CSS keyframes once on module load
|
|
19
25
|
let keyframesInjected = false;
|
|
20
26
|
function injectKeyframes() {
|
|
21
27
|
if (keyframesInjected || typeof document === 'undefined') return;
|
|
@@ -48,6 +54,8 @@ function DialIconItem({
|
|
|
48
54
|
const [isHovered, setIsHovered] = useState(false);
|
|
49
55
|
const [isPressed, setIsPressed] = useState(false);
|
|
50
56
|
const isEmpty = !icon.icon && icon.id.startsWith('empty-');
|
|
57
|
+
const isUnavailable = !isEmpty && icon.unavailable === true;
|
|
58
|
+
const interactive = !isEmpty && !isUnavailable;
|
|
51
59
|
const {
|
|
52
60
|
icons: iconConfig
|
|
53
61
|
} = dialAnimationConfig;
|
|
@@ -65,12 +73,13 @@ function DialIconItem({
|
|
|
65
73
|
iconProgress = 1;
|
|
66
74
|
}
|
|
67
75
|
iconProgress = Math.max(0, Math.min(1, iconProgress));
|
|
68
|
-
const iconSize =
|
|
76
|
+
const iconSize = DIAL_ICON_SIZE;
|
|
69
77
|
const pressedScale = iconConfig.pressIn.scale;
|
|
70
|
-
const hoveredScale = 1.1;
|
|
78
|
+
const hoveredScale = 1.1; // web-only hover affordance (no native counterpart)
|
|
79
|
+
|
|
71
80
|
const scale = iconProgress * (isPressed ? pressedScale : isHovered ? hoveredScale : 1);
|
|
72
81
|
|
|
73
|
-
// Opacity interpolation
|
|
82
|
+
// Opacity interpolation — native DialIcon.tsx: [0, 0.3, 1] -> [0, 0.3, 1]
|
|
74
83
|
let opacity = 0;
|
|
75
84
|
if (iconProgress <= 0) {
|
|
76
85
|
opacity = 0;
|
|
@@ -84,15 +93,15 @@ function DialIconItem({
|
|
|
84
93
|
return /*#__PURE__*/_jsx("button", {
|
|
85
94
|
role: "menuitem",
|
|
86
95
|
"aria-label": isEmpty ? 'Empty slot' : icon.name,
|
|
87
|
-
"aria-disabled":
|
|
88
|
-
tabIndex:
|
|
89
|
-
onClick:
|
|
90
|
-
onMouseEnter: () =>
|
|
96
|
+
"aria-disabled": !interactive,
|
|
97
|
+
tabIndex: interactive ? 0 : -1,
|
|
98
|
+
onClick: interactive ? onPress : undefined,
|
|
99
|
+
onMouseEnter: () => interactive && setIsHovered(true),
|
|
91
100
|
onMouseLeave: () => {
|
|
92
101
|
setIsHovered(false);
|
|
93
102
|
setIsPressed(false);
|
|
94
103
|
},
|
|
95
|
-
onMouseDown: () =>
|
|
104
|
+
onMouseDown: () => interactive && setIsPressed(true),
|
|
96
105
|
onMouseUp: () => setIsPressed(false),
|
|
97
106
|
style: {
|
|
98
107
|
position: 'absolute',
|
|
@@ -106,7 +115,7 @@ function DialIconItem({
|
|
|
106
115
|
flexDirection: 'column',
|
|
107
116
|
alignItems: 'center',
|
|
108
117
|
justifyContent: 'center',
|
|
109
|
-
cursor:
|
|
118
|
+
cursor: interactive ? 'pointer' : 'default',
|
|
110
119
|
transform: `translate(${x}px, ${y}px) scale(${scale})`,
|
|
111
120
|
opacity,
|
|
112
121
|
transition: isHovered || isPressed ? 'transform 100ms ease' : 'none',
|
|
@@ -148,25 +157,130 @@ function DialIconItem({
|
|
|
148
157
|
alignItems: 'center',
|
|
149
158
|
justifyContent: 'center',
|
|
150
159
|
fontSize: 32,
|
|
160
|
+
// native DialIcon.tsx: icon rendered at size 32
|
|
151
161
|
filter: isHovered ? 'brightness(1.2)' : 'none'
|
|
152
162
|
},
|
|
153
163
|
children: icon.icon
|
|
154
164
|
}), /*#__PURE__*/_jsx("span", {
|
|
155
165
|
style: {
|
|
156
|
-
fontSize:
|
|
166
|
+
fontSize:
|
|
167
|
+
// native: adjustsFontSizeToFit minimumFontScale 0.7 — long
|
|
168
|
+
// names shrink instead of wrapping/overflowing the slot.
|
|
169
|
+
icon.name.length > 8 ? Math.max(dialStyles.icon.label.fontSize * 0.7, dialStyles.icon.label.fontSize * 8 / icon.name.length) : dialStyles.icon.label.fontSize,
|
|
157
170
|
fontWeight: dialStyles.icon.label.fontWeight,
|
|
158
171
|
fontFamily: dialStyles.icon.label.fontFamily,
|
|
159
172
|
color: dialColors.iconLabel,
|
|
160
173
|
letterSpacing: dialStyles.icon.label.letterSpacing,
|
|
161
174
|
marginTop: dialStyles.icon.label.marginTop,
|
|
162
|
-
textTransform: 'uppercase'
|
|
175
|
+
textTransform: 'uppercase',
|
|
176
|
+
whiteSpace: 'nowrap'
|
|
163
177
|
},
|
|
164
178
|
children: icon.name
|
|
179
|
+
}), isUnavailable &&
|
|
180
|
+
/*#__PURE__*/
|
|
181
|
+
// native DialIcon.tsx unavailableCaption: label size - 1, muted
|
|
182
|
+
_jsx("span", {
|
|
183
|
+
style: {
|
|
184
|
+
fontSize: dialStyles.icon.label.fontSize - 1,
|
|
185
|
+
fontWeight: dialStyles.icon.label.fontWeight,
|
|
186
|
+
fontFamily: dialStyles.icon.label.fontFamily,
|
|
187
|
+
letterSpacing: dialStyles.icon.label.letterSpacing,
|
|
188
|
+
color: floatingToolsColors.muted,
|
|
189
|
+
textTransform: 'uppercase',
|
|
190
|
+
whiteSpace: 'nowrap'
|
|
191
|
+
},
|
|
192
|
+
children: "Unavailable"
|
|
165
193
|
})]
|
|
166
194
|
})
|
|
167
195
|
});
|
|
168
196
|
}
|
|
169
197
|
|
|
198
|
+
// =============================
|
|
199
|
+
// Pagination (mirrors native DialPagination.tsx)
|
|
200
|
+
// =============================
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Chevron glyph matching the native pager's ChevronLeft/ChevronRight from
|
|
204
|
+
* @buoy-gg/shared-ui (lucide two-line chevron, size 18, strokeWidth 2).
|
|
205
|
+
* Inlined as SVG because shared-ui is React Native-only.
|
|
206
|
+
*/
|
|
207
|
+
function PagerChevron({
|
|
208
|
+
side,
|
|
209
|
+
color
|
|
210
|
+
}) {
|
|
211
|
+
// native lucide-icons.tsx ChevronLeft: (15,18)->(9,12)->(15,6); ChevronRight mirrored
|
|
212
|
+
const lines = side === 'prev' ? [[15, 18, 9, 12], [9, 12, 15, 6]] : [[9, 18, 15, 12], [15, 12, 9, 6]];
|
|
213
|
+
return /*#__PURE__*/_jsx("svg", {
|
|
214
|
+
width: 18,
|
|
215
|
+
height: 18,
|
|
216
|
+
viewBox: "0 0 24 24",
|
|
217
|
+
"aria-hidden": "true",
|
|
218
|
+
focusable: "false",
|
|
219
|
+
children: lines.map(([x1, y1, x2, y2], i) => /*#__PURE__*/_jsx("line", {
|
|
220
|
+
x1: x1,
|
|
221
|
+
y1: y1,
|
|
222
|
+
x2: x2,
|
|
223
|
+
y2: y2,
|
|
224
|
+
stroke: color,
|
|
225
|
+
strokeWidth: 2
|
|
226
|
+
}, i))
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
function PagerButton({
|
|
230
|
+
side,
|
|
231
|
+
disabled,
|
|
232
|
+
onClick
|
|
233
|
+
}) {
|
|
234
|
+
const [isPressed, setIsPressed] = useState(false);
|
|
235
|
+
|
|
236
|
+
// native DialPagination.tsx: accent = disabled ? emptyDotBorder : buoyColors.primary
|
|
237
|
+
// (buoyColors.primary === floatingToolsColors.info === dialColors.dialShadow, #20C997)
|
|
238
|
+
const accent = disabled ? dialColors.emptyDotBorder : dialColors.dialShadow;
|
|
239
|
+
return /*#__PURE__*/_jsxs("button", {
|
|
240
|
+
type: "button",
|
|
241
|
+
"aria-label": `${side === 'prev' ? 'Previous' : 'Next'} dial page`,
|
|
242
|
+
disabled: disabled,
|
|
243
|
+
onClick: onClick,
|
|
244
|
+
onMouseDown: () => !disabled && setIsPressed(true),
|
|
245
|
+
onMouseUp: () => setIsPressed(false),
|
|
246
|
+
onMouseLeave: () => setIsPressed(false),
|
|
247
|
+
style: {
|
|
248
|
+
display: 'flex',
|
|
249
|
+
alignItems: 'center',
|
|
250
|
+
gap: 4,
|
|
251
|
+
// native DialPagination.tsx: gap 4
|
|
252
|
+
padding: '10px 16px',
|
|
253
|
+
// native: paddingVertical 10, paddingHorizontal 16
|
|
254
|
+
borderRadius: 10,
|
|
255
|
+
border: `1px solid ${dialColors.dialBorder}`,
|
|
256
|
+
backgroundColor: dialColors.dialBackground,
|
|
257
|
+
color: accent,
|
|
258
|
+
fontSize: 12,
|
|
259
|
+
fontWeight: 900,
|
|
260
|
+
fontFamily: 'monospace',
|
|
261
|
+
letterSpacing: 1.5,
|
|
262
|
+
textTransform: 'uppercase',
|
|
263
|
+
// native: textShadow buoyColors.primary radius 4 (removed when disabled)
|
|
264
|
+
textShadow: disabled ? 'none' : `0 0 4px ${accent}`,
|
|
265
|
+
cursor: disabled ? 'default' : 'pointer',
|
|
266
|
+
opacity: disabled ? 0.4 : 1,
|
|
267
|
+
// native: buttonDisabled opacity 0.4
|
|
268
|
+
// native: shadowColor dialShadow, shadowOpacity 0.4, shadowRadius 8
|
|
269
|
+
boxShadow: disabled ? 'none' : `0 0 8px ${withAlpha(dialColors.dialShadow, 0.4)}`,
|
|
270
|
+
// native: press-in springs to scale 0.92
|
|
271
|
+
transform: isPressed ? 'scale(0.92)' : 'scale(1)',
|
|
272
|
+
transition: 'transform 100ms ease'
|
|
273
|
+
},
|
|
274
|
+
children: [side === 'prev' && /*#__PURE__*/_jsx(PagerChevron, {
|
|
275
|
+
side: "prev",
|
|
276
|
+
color: accent
|
|
277
|
+
}), side === 'prev' ? 'PREV' : 'NEXT', side === 'next' && /*#__PURE__*/_jsx(PagerChevron, {
|
|
278
|
+
side: "next",
|
|
279
|
+
color: accent
|
|
280
|
+
})]
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
|
|
170
284
|
// =============================
|
|
171
285
|
// Main DialMenu Component
|
|
172
286
|
// =============================
|
|
@@ -175,7 +289,9 @@ export function DialMenu({
|
|
|
175
289
|
icons,
|
|
176
290
|
onClose,
|
|
177
291
|
centerLabel = 'MENU',
|
|
178
|
-
onCenterPress
|
|
292
|
+
onCenterPress,
|
|
293
|
+
settingsOpen = false,
|
|
294
|
+
hintsDisabled = false
|
|
179
295
|
}) {
|
|
180
296
|
// Animation values
|
|
181
297
|
const [backdropOpacity, setBackdropOpacity] = useState(0);
|
|
@@ -187,20 +303,17 @@ export function DialMenu({
|
|
|
187
303
|
|
|
188
304
|
// UI state
|
|
189
305
|
const [isHoveringCenter, setIsHoveringCenter] = useState(false);
|
|
190
|
-
const [triggerGlitch, setTriggerGlitch] = useState(0);
|
|
191
306
|
const [isExiting, setIsExiting] = useState(false);
|
|
192
307
|
const [entranceComplete, setEntranceComplete] = useState(false);
|
|
193
308
|
|
|
194
309
|
// Refs
|
|
195
310
|
const animationRef = useRef(null);
|
|
196
|
-
const glitchIntervalRef = useRef(null);
|
|
197
311
|
const isClosingRef = useRef(false);
|
|
198
312
|
|
|
199
313
|
// Config
|
|
200
314
|
const {
|
|
201
315
|
entrance,
|
|
202
316
|
exit,
|
|
203
|
-
continuous,
|
|
204
317
|
interaction
|
|
205
318
|
} = dialAnimationConfig;
|
|
206
319
|
const cssAnimations = getDialCSSAnimationStyles();
|
|
@@ -243,7 +356,6 @@ export function DialMenu({
|
|
|
243
356
|
const centerButtonDelay = entrance.centerButton.delay;
|
|
244
357
|
const iconsDelay = entrance.icons.delay;
|
|
245
358
|
const iconsDuration = entrance.icons.duration;
|
|
246
|
-
const glitchInterval = continuous.glitch.interval;
|
|
247
359
|
const startTime = performance.now();
|
|
248
360
|
const animate = currentTime => {
|
|
249
361
|
const elapsed = currentTime - startTime;
|
|
@@ -296,14 +408,8 @@ export function DialMenu({
|
|
|
296
408
|
}
|
|
297
409
|
};
|
|
298
410
|
animationRef.current = requestAnimationFrame(animate);
|
|
299
|
-
|
|
300
|
-
// Glitch interval
|
|
301
|
-
glitchIntervalRef.current = setInterval(() => {
|
|
302
|
-
setTriggerGlitch(prev => prev + 1);
|
|
303
|
-
}, glitchInterval);
|
|
304
411
|
return () => {
|
|
305
412
|
if (animationRef.current) cancelAnimationFrame(animationRef.current);
|
|
306
|
-
if (glitchIntervalRef.current) clearInterval(glitchIntervalRef.current);
|
|
307
413
|
};
|
|
308
414
|
}, []);
|
|
309
415
|
|
|
@@ -312,16 +418,14 @@ export function DialMenu({
|
|
|
312
418
|
if (isClosingRef.current) return;
|
|
313
419
|
isClosingRef.current = true;
|
|
314
420
|
setIsExiting(true);
|
|
315
|
-
if (glitchIntervalRef.current) {
|
|
316
|
-
clearInterval(glitchIntervalRef.current);
|
|
317
|
-
glitchIntervalRef.current = null;
|
|
318
|
-
}
|
|
319
421
|
if (animationRef.current) {
|
|
320
422
|
cancelAnimationFrame(animationRef.current);
|
|
321
423
|
}
|
|
322
424
|
const startTime = performance.now();
|
|
323
425
|
const iconsDuration = exit.icons.duration;
|
|
324
|
-
const
|
|
426
|
+
const centerDuration = exit.centerButton.duration;
|
|
427
|
+
const dialDuration = exit.dialScale.duration;
|
|
428
|
+
const step2Duration = Math.max(centerDuration, dialDuration);
|
|
325
429
|
const backdropDuration = exit.backdrop.duration;
|
|
326
430
|
const animate = currentTime => {
|
|
327
431
|
const elapsed = currentTime - startTime;
|
|
@@ -334,19 +438,21 @@ export function DialMenu({
|
|
|
334
438
|
return;
|
|
335
439
|
}
|
|
336
440
|
|
|
337
|
-
// Step 2: Dial + Center scale down
|
|
441
|
+
// Step 2: Dial + Center scale down in parallel — native runs the center
|
|
442
|
+
// button (200ms) and dial (250ms) with their own durations.
|
|
338
443
|
const step2Start = iconsDuration;
|
|
339
|
-
if (elapsed < step2Start +
|
|
444
|
+
if (elapsed < step2Start + step2Duration) {
|
|
340
445
|
setIconProgress(0);
|
|
341
|
-
const
|
|
342
|
-
|
|
343
|
-
setCenterButtonScale(1 -
|
|
446
|
+
const centerProgress = Math.min(1, (elapsed - step2Start) / centerDuration);
|
|
447
|
+
const dialProgress = Math.min(1, (elapsed - step2Start) / dialDuration);
|
|
448
|
+
setCenterButtonScale(1 - easeInCubic(centerProgress));
|
|
449
|
+
setDialScale(1 - easeInCubic(dialProgress));
|
|
344
450
|
animationRef.current = requestAnimationFrame(animate);
|
|
345
451
|
return;
|
|
346
452
|
}
|
|
347
453
|
|
|
348
454
|
// Step 3: Backdrop fade (550 - 750ms)
|
|
349
|
-
const step3Start = step2Start +
|
|
455
|
+
const step3Start = step2Start + step2Duration;
|
|
350
456
|
if (elapsed < step3Start + backdropDuration) {
|
|
351
457
|
setDialScale(0);
|
|
352
458
|
setCenterButtonScale(0);
|
|
@@ -374,6 +480,33 @@ export function DialMenu({
|
|
|
374
480
|
return () => document.removeEventListener('keydown', handleKeyDown);
|
|
375
481
|
}, [handleClose]);
|
|
376
482
|
|
|
483
|
+
// Settings onboarding tooltip — native DialDevTools.tsx:174-196: shown
|
|
484
|
+
// 1200ms after the dial mounts (entrance animations settle first) if never
|
|
485
|
+
// dismissed; suppressed while settings is open; dismissed forever when
|
|
486
|
+
// settings opens.
|
|
487
|
+
const [showSettingsTooltip, setShowSettingsTooltip] = useState(false);
|
|
488
|
+
useEffect(() => {
|
|
489
|
+
if (hintsDisabled) return;
|
|
490
|
+
let cancelled = false;
|
|
491
|
+
const timer = setTimeout(async () => {
|
|
492
|
+
const seen = await persistentStorage.getItem(SETTINGS_TOOLTIP_KEY);
|
|
493
|
+
if (!cancelled && !seen) setShowSettingsTooltip(true);
|
|
494
|
+
}, 1200);
|
|
495
|
+
return () => {
|
|
496
|
+
cancelled = true;
|
|
497
|
+
clearTimeout(timer);
|
|
498
|
+
};
|
|
499
|
+
}, [hintsDisabled]);
|
|
500
|
+
const dismissSettingsTooltip = useCallback(() => {
|
|
501
|
+
setShowSettingsTooltip(false);
|
|
502
|
+
void persistentStorage.setItem(SETTINGS_TOOLTIP_KEY, 'true');
|
|
503
|
+
}, []);
|
|
504
|
+
useEffect(() => {
|
|
505
|
+
if (settingsOpen && showSettingsTooltip) {
|
|
506
|
+
dismissSettingsTooltip();
|
|
507
|
+
}
|
|
508
|
+
}, [settingsOpen, showSettingsTooltip, dismissSettingsTooltip]);
|
|
509
|
+
|
|
377
510
|
// Icon press handler
|
|
378
511
|
const handleIconPress = useCallback(icon => {
|
|
379
512
|
if (icon.id.startsWith('empty-') || isClosingRef.current) return;
|
|
@@ -418,24 +551,6 @@ export function DialMenu({
|
|
|
418
551
|
const buttonContainerSize = layout.buttonSize * dialStyles.centerButton.containerRatio;
|
|
419
552
|
const buttonBorderSize = layout.buttonSize * dialStyles.centerButton.borderRatio;
|
|
420
553
|
const isAnimating = entranceComplete && !isExiting;
|
|
421
|
-
const pagerButtonStyle = disabled => ({
|
|
422
|
-
display: 'flex',
|
|
423
|
-
alignItems: 'center',
|
|
424
|
-
gap: 4,
|
|
425
|
-
padding: '8px 16px',
|
|
426
|
-
borderRadius: 10,
|
|
427
|
-
border: `1px solid ${dialColors.dialBorder}`,
|
|
428
|
-
backgroundColor: dialColors.dialBackground,
|
|
429
|
-
color: disabled ? dialColors.emptyDotBorder : dialColors.dialShadow,
|
|
430
|
-
fontSize: 12,
|
|
431
|
-
fontWeight: 900,
|
|
432
|
-
fontFamily: 'monospace',
|
|
433
|
-
letterSpacing: 1.5,
|
|
434
|
-
textTransform: 'uppercase',
|
|
435
|
-
cursor: disabled ? 'default' : 'pointer',
|
|
436
|
-
opacity: disabled ? 0.4 : 1,
|
|
437
|
-
boxShadow: disabled ? 'none' : `0 0 8px ${dialColors.dialShadow}66`
|
|
438
|
-
});
|
|
439
554
|
return /*#__PURE__*/_jsxs("div", {
|
|
440
555
|
role: "dialog",
|
|
441
556
|
"aria-label": "Dial Menu",
|
|
@@ -443,10 +558,7 @@ export function DialMenu({
|
|
|
443
558
|
style: {
|
|
444
559
|
position: 'fixed',
|
|
445
560
|
inset: 0,
|
|
446
|
-
zIndex: 10000
|
|
447
|
-
display: 'flex',
|
|
448
|
-
alignItems: 'center',
|
|
449
|
-
justifyContent: 'center'
|
|
561
|
+
zIndex: 10000
|
|
450
562
|
},
|
|
451
563
|
children: [/*#__PURE__*/_jsx("div", {
|
|
452
564
|
role: "button",
|
|
@@ -462,204 +574,234 @@ export function DialMenu({
|
|
|
462
574
|
}
|
|
463
575
|
}), /*#__PURE__*/_jsxs("div", {
|
|
464
576
|
style: {
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
577
|
+
position: 'absolute',
|
|
578
|
+
left: '50%',
|
|
579
|
+
marginLeft: -layout.circleSize / 2,
|
|
580
|
+
bottom: 80,
|
|
581
|
+
// native DialDevTools.tsx: bottom: 80
|
|
582
|
+
width: layout.circleSize,
|
|
583
|
+
height: layout.circleSize,
|
|
584
|
+
borderRadius: '50%',
|
|
585
|
+
backgroundColor: dialColors.dialBackground,
|
|
586
|
+
border: `${dialStyles.circle.borderWidth}px solid ${dialColors.dialBorder}`,
|
|
587
|
+
// native: shadowColor dialShadow at shadowOpacity 0.5, shadowRadius 20
|
|
588
|
+
boxShadow: `0 0 ${dialStyles.circle.shadowRadius}px ${withAlpha(dialColors.dialShadow, dialStyles.circle.shadowOpacity)}`,
|
|
589
|
+
transform: `scale(${dialScale}) rotate(${dialRotation}deg)`,
|
|
590
|
+
opacity: dialScale > 0.01 ? 1 : 0,
|
|
591
|
+
overflow: 'hidden'
|
|
470
592
|
},
|
|
471
593
|
children: [/*#__PURE__*/_jsx("div", {
|
|
472
594
|
style: {
|
|
473
|
-
|
|
595
|
+
position: 'absolute',
|
|
596
|
+
inset: 0,
|
|
597
|
+
borderRadius: '50%',
|
|
598
|
+
backgroundColor: dialColors.dialGradient1,
|
|
599
|
+
opacity: dialStyles.gradientLayers[0].opacity
|
|
600
|
+
}
|
|
601
|
+
}), /*#__PURE__*/_jsx("div", {
|
|
602
|
+
style: {
|
|
603
|
+
position: 'absolute',
|
|
604
|
+
inset: 0,
|
|
605
|
+
top: '30%',
|
|
606
|
+
left: '30%',
|
|
607
|
+
borderRadius: '50%',
|
|
608
|
+
backgroundColor: dialColors.dialGradient2,
|
|
609
|
+
opacity: dialStyles.gradientLayers[1].opacity
|
|
610
|
+
}
|
|
611
|
+
}), /*#__PURE__*/_jsx("div", {
|
|
612
|
+
style: {
|
|
613
|
+
position: 'absolute',
|
|
614
|
+
inset: 0,
|
|
615
|
+
top: '50%',
|
|
616
|
+
left: '50%',
|
|
617
|
+
borderRadius: '50%',
|
|
618
|
+
backgroundColor: dialColors.dialGradient3,
|
|
619
|
+
opacity: dialStyles.gradientLayers[2].opacity
|
|
620
|
+
}
|
|
621
|
+
}), gridRotations.map(deg => /*#__PURE__*/_jsx("div", {
|
|
622
|
+
style: {
|
|
623
|
+
position: 'absolute',
|
|
624
|
+
top: '50%',
|
|
625
|
+
left: 0,
|
|
626
|
+
right: 0,
|
|
627
|
+
height: dialStyles.grid.lineHeight,
|
|
628
|
+
backgroundColor: dialColors.dialGridLine,
|
|
629
|
+
transform: `rotate(${deg}deg)`,
|
|
630
|
+
transformOrigin: 'center'
|
|
631
|
+
}
|
|
632
|
+
}, deg)), paddedIcons.map((icon, index) => /*#__PURE__*/_jsx(DialIconItem, {
|
|
633
|
+
icon: icon,
|
|
634
|
+
index: index,
|
|
635
|
+
totalIcons: paddedIcons.length,
|
|
636
|
+
position: positions[index],
|
|
637
|
+
progress: iconProgress,
|
|
638
|
+
onPress: () => handleIconPress(icon)
|
|
639
|
+
}, index)), /*#__PURE__*/_jsxs("div", {
|
|
640
|
+
style: {
|
|
641
|
+
position: 'absolute',
|
|
642
|
+
left: '50%',
|
|
643
|
+
top: '50%',
|
|
644
|
+
width: buttonContainerSize,
|
|
645
|
+
height: buttonContainerSize,
|
|
646
|
+
marginLeft: -buttonContainerSize / 2,
|
|
647
|
+
marginTop: -buttonContainerSize / 2,
|
|
648
|
+
display: 'flex',
|
|
649
|
+
alignItems: 'center',
|
|
650
|
+
justifyContent: 'center',
|
|
651
|
+
backgroundColor: dialColors.dialBackground,
|
|
652
|
+
borderRadius: layout.buttonSize,
|
|
653
|
+
overflow: 'hidden',
|
|
654
|
+
transform: `scale(${centerButtonScale * centerPulseScale})`,
|
|
655
|
+
opacity: centerButtonScale > 0.01 ? 1 : 0
|
|
474
656
|
},
|
|
475
|
-
children: /*#__PURE__*/
|
|
657
|
+
children: [/*#__PURE__*/_jsx("div", {
|
|
658
|
+
style: {
|
|
659
|
+
position: 'absolute',
|
|
660
|
+
inset: 0,
|
|
661
|
+
backgroundColor: dialColors.dialGradient1,
|
|
662
|
+
opacity: 0.5,
|
|
663
|
+
borderRadius: layout.buttonSize
|
|
664
|
+
}
|
|
665
|
+
}), /*#__PURE__*/_jsx("div", {
|
|
666
|
+
style: {
|
|
667
|
+
position: 'absolute',
|
|
668
|
+
inset: 0,
|
|
669
|
+
top: '20%',
|
|
670
|
+
left: '20%',
|
|
671
|
+
backgroundColor: dialColors.dialGradient2,
|
|
672
|
+
opacity: 0.3,
|
|
673
|
+
borderRadius: layout.buttonSize
|
|
674
|
+
}
|
|
675
|
+
}), /*#__PURE__*/_jsx("div", {
|
|
476
676
|
style: {
|
|
477
|
-
position: '
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
backgroundColor: dialColors.
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
677
|
+
position: 'absolute',
|
|
678
|
+
inset: 0,
|
|
679
|
+
top: '40%',
|
|
680
|
+
left: '40%',
|
|
681
|
+
backgroundColor: dialColors.dialGradient3,
|
|
682
|
+
opacity: 0.2,
|
|
683
|
+
borderRadius: layout.buttonSize
|
|
684
|
+
}
|
|
685
|
+
}), /*#__PURE__*/_jsx("div", {
|
|
686
|
+
style: {
|
|
687
|
+
width: buttonBorderSize,
|
|
688
|
+
height: buttonBorderSize,
|
|
689
|
+
borderRadius: layout.buttonSize * dialStyles.centerButton.borderRadiusRatio,
|
|
690
|
+
backgroundColor: dialColors.dialGridLine,
|
|
691
|
+
border: `${dialStyles.centerButton.borderWidth}px solid ${dialColors.dialBorder}`,
|
|
692
|
+
display: 'flex',
|
|
693
|
+
alignItems: 'center',
|
|
694
|
+
justifyContent: 'center'
|
|
487
695
|
},
|
|
488
|
-
children:
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
borderRadius: '50%',
|
|
493
|
-
backgroundColor: dialColors.dialGradient1,
|
|
494
|
-
opacity: dialStyles.gradientLayers[0].opacity
|
|
495
|
-
}
|
|
496
|
-
}), /*#__PURE__*/_jsx("div", {
|
|
696
|
+
children: /*#__PURE__*/_jsx("div", {
|
|
697
|
+
onClick: onCenterPress,
|
|
698
|
+
onMouseEnter: () => setIsHoveringCenter(true),
|
|
699
|
+
onMouseLeave: () => setIsHoveringCenter(false),
|
|
497
700
|
style: {
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
left: '30%',
|
|
502
|
-
borderRadius: '50%',
|
|
503
|
-
backgroundColor: dialColors.dialGradient2,
|
|
504
|
-
opacity: dialStyles.gradientLayers[1].opacity
|
|
505
|
-
}
|
|
506
|
-
}), /*#__PURE__*/_jsx("div", {
|
|
507
|
-
style: {
|
|
508
|
-
position: 'absolute',
|
|
509
|
-
inset: 0,
|
|
510
|
-
top: '50%',
|
|
511
|
-
left: '50%',
|
|
512
|
-
borderRadius: '50%',
|
|
513
|
-
backgroundColor: dialColors.dialGradient3,
|
|
514
|
-
opacity: dialStyles.gradientLayers[2].opacity
|
|
515
|
-
}
|
|
516
|
-
}), gridRotations.map(deg => /*#__PURE__*/_jsx("div", {
|
|
517
|
-
style: {
|
|
518
|
-
position: 'absolute',
|
|
519
|
-
top: '50%',
|
|
520
|
-
left: 0,
|
|
521
|
-
right: 0,
|
|
522
|
-
height: dialStyles.grid.lineHeight,
|
|
523
|
-
backgroundColor: dialColors.dialGridLine,
|
|
524
|
-
transform: `rotate(${deg}deg)`,
|
|
525
|
-
transformOrigin: 'center'
|
|
526
|
-
}
|
|
527
|
-
}, deg)), paddedIcons.map((icon, index) => /*#__PURE__*/_jsx(DialIconItem, {
|
|
528
|
-
icon: icon,
|
|
529
|
-
index: index,
|
|
530
|
-
totalIcons: paddedIcons.length,
|
|
531
|
-
position: positions[index],
|
|
532
|
-
progress: iconProgress,
|
|
533
|
-
onPress: () => handleIconPress(icon)
|
|
534
|
-
}, index)), /*#__PURE__*/_jsxs("div", {
|
|
535
|
-
style: {
|
|
536
|
-
position: 'absolute',
|
|
537
|
-
left: '50%',
|
|
538
|
-
top: '50%',
|
|
539
|
-
width: buttonContainerSize,
|
|
540
|
-
height: buttonContainerSize,
|
|
541
|
-
marginLeft: -buttonContainerSize / 2,
|
|
542
|
-
marginTop: -buttonContainerSize / 2,
|
|
701
|
+
width: layout.buttonSize,
|
|
702
|
+
height: layout.buttonSize,
|
|
703
|
+
borderRadius: layout.buttonSize / 2,
|
|
543
704
|
display: 'flex',
|
|
705
|
+
flexDirection: 'column',
|
|
544
706
|
alignItems: 'center',
|
|
545
707
|
justifyContent: 'center',
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
opacity: centerButtonScale > 0.01 ? 1 : 0
|
|
708
|
+
cursor: onCenterPress ? 'pointer' : 'default',
|
|
709
|
+
transform: isHoveringCenter ? `scale(${interaction.centerHover.scale})` : 'scale(1)',
|
|
710
|
+
transition: `transform ${interaction.centerHover.duration}ms ease`,
|
|
711
|
+
animation: isAnimating && !isHoveringCenter ? cssAnimations.pulse : 'none'
|
|
551
712
|
},
|
|
552
|
-
children:
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
backgroundColor: dialColors.dialGradient1,
|
|
557
|
-
opacity: 0.5,
|
|
558
|
-
borderRadius: layout.buttonSize
|
|
559
|
-
}
|
|
560
|
-
}), /*#__PURE__*/_jsx("div", {
|
|
561
|
-
style: {
|
|
562
|
-
position: 'absolute',
|
|
563
|
-
inset: 0,
|
|
564
|
-
top: '20%',
|
|
565
|
-
left: '20%',
|
|
566
|
-
backgroundColor: dialColors.dialGradient2,
|
|
567
|
-
opacity: 0.3,
|
|
568
|
-
borderRadius: layout.buttonSize
|
|
569
|
-
}
|
|
570
|
-
}), /*#__PURE__*/_jsx("div", {
|
|
571
|
-
style: {
|
|
572
|
-
position: 'absolute',
|
|
573
|
-
inset: 0,
|
|
574
|
-
top: '40%',
|
|
575
|
-
left: '40%',
|
|
576
|
-
backgroundColor: dialColors.dialGradient3,
|
|
577
|
-
opacity: 0.2,
|
|
578
|
-
borderRadius: layout.buttonSize
|
|
579
|
-
}
|
|
580
|
-
}), /*#__PURE__*/_jsx("div", {
|
|
713
|
+
children: settingsOpen ?
|
|
714
|
+
/*#__PURE__*/
|
|
715
|
+
// native DialDevTools.tsx:716-724 — stacked CLOSE / SETTINGS
|
|
716
|
+
_jsxs("span", {
|
|
581
717
|
style: {
|
|
582
|
-
width: buttonBorderSize,
|
|
583
|
-
height: buttonBorderSize,
|
|
584
|
-
borderRadius: layout.buttonSize * dialStyles.centerButton.borderRadiusRatio,
|
|
585
|
-
backgroundColor: dialColors.dialGridLine,
|
|
586
|
-
border: `${dialStyles.centerButton.borderWidth}px solid ${dialColors.dialBorder}`,
|
|
587
718
|
display: 'flex',
|
|
719
|
+
flexDirection: 'column',
|
|
588
720
|
alignItems: 'center',
|
|
589
|
-
|
|
721
|
+
fontSize: dialStyles.centerButton.text.fontSize - 2,
|
|
722
|
+
fontWeight: dialStyles.centerButton.text.fontWeight,
|
|
723
|
+
fontFamily: dialStyles.centerButton.text.fontFamily,
|
|
724
|
+
color: '#FFFFFF',
|
|
725
|
+
letterSpacing: dialStyles.centerButton.text.letterSpacing,
|
|
726
|
+
textAlign: 'center',
|
|
727
|
+
textShadow: `0 0 4px ${dialColors.centerTextGlow}`,
|
|
728
|
+
textTransform: 'uppercase',
|
|
729
|
+
lineHeight: 1.2
|
|
590
730
|
},
|
|
591
|
-
children: /*#__PURE__*/_jsx("
|
|
592
|
-
onClick: onCenterPress,
|
|
593
|
-
onMouseEnter: () => setIsHoveringCenter(true),
|
|
594
|
-
onMouseLeave: () => setIsHoveringCenter(false),
|
|
731
|
+
children: [/*#__PURE__*/_jsx("span", {
|
|
595
732
|
style: {
|
|
596
|
-
|
|
597
|
-
height: layout.buttonSize,
|
|
598
|
-
borderRadius: layout.buttonSize / 2,
|
|
599
|
-
display: 'flex',
|
|
600
|
-
flexDirection: 'column',
|
|
601
|
-
alignItems: 'center',
|
|
602
|
-
justifyContent: 'center',
|
|
603
|
-
cursor: onCenterPress ? 'pointer' : 'default',
|
|
604
|
-
transform: isHoveringCenter ? `scale(${interaction.centerHover.scale})` : 'scale(1)',
|
|
605
|
-
transition: `transform ${interaction.centerHover.duration}ms ease`,
|
|
606
|
-
animation: isAnimating && !isHoveringCenter ? cssAnimations.breathing : 'none'
|
|
733
|
+
marginBottom: -2
|
|
607
734
|
},
|
|
608
|
-
children:
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
735
|
+
children: "CLOSE"
|
|
736
|
+
}), /*#__PURE__*/_jsx("span", {
|
|
737
|
+
style: {
|
|
738
|
+
marginTop: -2
|
|
739
|
+
},
|
|
740
|
+
children: "SETTINGS"
|
|
741
|
+
})]
|
|
742
|
+
}) : /*#__PURE__*/_jsx("span", {
|
|
743
|
+
style: {
|
|
744
|
+
fontSize: dialStyles.centerButton.text.fontSize,
|
|
745
|
+
fontWeight: dialStyles.centerButton.text.fontWeight,
|
|
746
|
+
fontFamily: dialStyles.centerButton.text.fontFamily,
|
|
747
|
+
color: '#FFFFFF',
|
|
748
|
+
// native DialDevTools.tsx centerText: #FFFFFF
|
|
749
|
+
letterSpacing: dialStyles.centerButton.text.letterSpacing,
|
|
750
|
+
textAlign: 'center',
|
|
751
|
+
textShadow: `0 0 4px ${dialColors.centerTextGlow}`,
|
|
752
|
+
textTransform: 'uppercase'
|
|
753
|
+
},
|
|
754
|
+
children: centerLabel
|
|
755
|
+
})
|
|
756
|
+
})
|
|
757
|
+
})]
|
|
758
|
+
})]
|
|
759
|
+
}), pageCount > 1 && /*#__PURE__*/_jsxs("div", {
|
|
760
|
+
style: {
|
|
761
|
+
position: 'absolute',
|
|
762
|
+
left: '50%',
|
|
763
|
+
marginLeft: -layout.circleSize / 2,
|
|
764
|
+
top: 'calc(100% - 64px)',
|
|
765
|
+
// native: screenHeight - 80 + 16
|
|
766
|
+
width: layout.circleSize,
|
|
767
|
+
display: 'flex',
|
|
768
|
+
alignItems: 'center',
|
|
769
|
+
justifyContent: 'space-between',
|
|
770
|
+
opacity: Math.min(1, dialScale),
|
|
771
|
+
transform: `scale(${Math.min(1, dialScale)})`
|
|
772
|
+
},
|
|
773
|
+
children: [/*#__PURE__*/_jsx(PagerButton, {
|
|
774
|
+
side: "prev",
|
|
775
|
+
disabled: safePage <= 0,
|
|
776
|
+
onClick: () => handlePageChange(safePage - 1)
|
|
777
|
+
}), /*#__PURE__*/_jsxs("span", {
|
|
625
778
|
style: {
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
779
|
+
padding: '6px 12px',
|
|
780
|
+
// native indicator: paddingVertical 6, paddingHorizontal 12
|
|
781
|
+
fontSize: 13,
|
|
782
|
+
fontWeight: 900,
|
|
783
|
+
fontFamily: 'monospace',
|
|
784
|
+
letterSpacing: 2,
|
|
785
|
+
color: '#FFFFFF',
|
|
786
|
+
textShadow: `0 0 6px ${dialColors.dialShadow}`
|
|
630
787
|
},
|
|
631
|
-
children: [/*#__PURE__*/
|
|
632
|
-
type: "button",
|
|
633
|
-
"aria-label": "Previous dial page",
|
|
634
|
-
disabled: safePage <= 0,
|
|
635
|
-
onClick: () => handlePageChange(safePage - 1),
|
|
636
|
-
style: pagerButtonStyle(safePage <= 0),
|
|
637
|
-
children: "\u2039 PREV"
|
|
638
|
-
}), /*#__PURE__*/_jsxs("span", {
|
|
788
|
+
children: [String(safePage + 1).padStart(2, '0'), /*#__PURE__*/_jsxs("span", {
|
|
639
789
|
style: {
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
fontFamily: 'monospace',
|
|
643
|
-
letterSpacing: 2,
|
|
644
|
-
color: '#FFFFFF',
|
|
645
|
-
textShadow: `0 0 6px ${dialColors.dialShadow}`
|
|
790
|
+
color: dialColors.iconLabel,
|
|
791
|
+
textShadow: 'none'
|
|
646
792
|
},
|
|
647
|
-
children: [String(
|
|
648
|
-
style: {
|
|
649
|
-
color: dialColors.iconLabel,
|
|
650
|
-
textShadow: 'none'
|
|
651
|
-
},
|
|
652
|
-
children: [' / ', String(pageCount).padStart(2, '0')]
|
|
653
|
-
})]
|
|
654
|
-
}), /*#__PURE__*/_jsx("button", {
|
|
655
|
-
type: "button",
|
|
656
|
-
"aria-label": "Next dial page",
|
|
657
|
-
disabled: safePage >= pageCount - 1,
|
|
658
|
-
onClick: () => handlePageChange(safePage + 1),
|
|
659
|
-
style: pagerButtonStyle(safePage >= pageCount - 1),
|
|
660
|
-
children: "NEXT \u203A"
|
|
793
|
+
children: [' / ', String(pageCount).padStart(2, '0')]
|
|
661
794
|
})]
|
|
795
|
+
}), /*#__PURE__*/_jsx(PagerButton, {
|
|
796
|
+
side: "next",
|
|
797
|
+
disabled: safePage >= pageCount - 1,
|
|
798
|
+
onClick: () => handlePageChange(safePage + 1)
|
|
662
799
|
})]
|
|
800
|
+
}), showSettingsTooltip && !settingsOpen && /*#__PURE__*/_jsx(OnboardingTooltip, {
|
|
801
|
+
title: "Welcome to Buoy!",
|
|
802
|
+
message: "Tap the center button to configure and add tools to your dial menu.",
|
|
803
|
+
onDismiss: dismissSettingsTooltip,
|
|
804
|
+
showArrow: false
|
|
663
805
|
})]
|
|
664
806
|
});
|
|
665
807
|
}
|