@buoy-gg/shared-ui 7.0.31 → 7.0.33

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 (79) hide show
  1. package/lib/commonjs/JsModal.js +13 -6
  2. package/lib/commonjs/hooks/safe-area-impl.js +1 -1
  3. package/lib/commonjs/storage/devToolsStorageKeys.js +12 -0
  4. package/lib/commonjs/ui/components/EmptyState.js +10 -2
  5. package/lib/commonjs/ui/components/ModalHeader.js +5 -0
  6. package/lib/commonjs/ui/components/ToolEmptyState.js +154 -0
  7. package/lib/commonjs/ui/components/WindowControls.js +8 -5
  8. package/lib/commonjs/ui/components/index.js +26 -0
  9. package/lib/commonjs/ui/components/windowDrag.js +45 -0
  10. package/lib/commonjs/ui/index.js +12 -0
  11. package/lib/commonjs/ui/otto/OttoSprite.js +510 -0
  12. package/lib/commonjs/ui/otto/index.js +38 -0
  13. package/lib/commonjs/ui/otto/ottoEngine.js +2734 -0
  14. package/lib/commonjs/ui/otto/ottoSheet.js +191 -0
  15. package/lib/module/JsModal.js +13 -6
  16. package/lib/module/hooks/safe-area-impl.js +1 -1
  17. package/lib/module/storage/devToolsStorageKeys.js +12 -0
  18. package/lib/module/ui/components/EmptyState.js +10 -2
  19. package/lib/module/ui/components/ModalHeader.js +5 -0
  20. package/lib/module/ui/components/ToolEmptyState.js +149 -0
  21. package/lib/module/ui/components/WindowControls.js +8 -5
  22. package/lib/module/ui/components/index.js +4 -0
  23. package/lib/module/ui/components/windowDrag.js +41 -0
  24. package/lib/module/ui/index.js +4 -1
  25. package/lib/module/ui/otto/OttoSprite.js +496 -0
  26. package/lib/module/ui/otto/index.js +20 -0
  27. package/lib/module/ui/otto/ottoEngine.js +2726 -0
  28. package/lib/module/ui/otto/ottoSheet.js +180 -0
  29. package/lib/typescript/commonjs/JsModal.d.ts.map +1 -1
  30. package/lib/typescript/commonjs/hooks/safe-area-impl.d.ts +1 -1
  31. package/lib/typescript/commonjs/storage/devToolsStorageKeys.d.ts +12 -0
  32. package/lib/typescript/commonjs/storage/devToolsStorageKeys.d.ts.map +1 -1
  33. package/lib/typescript/commonjs/ui/components/EmptyState.d.ts +14 -1
  34. package/lib/typescript/commonjs/ui/components/EmptyState.d.ts.map +1 -1
  35. package/lib/typescript/commonjs/ui/components/ModalHeader.d.ts.map +1 -1
  36. package/lib/typescript/commonjs/ui/components/ToolEmptyState.d.ts +113 -0
  37. package/lib/typescript/commonjs/ui/components/ToolEmptyState.d.ts.map +1 -0
  38. package/lib/typescript/commonjs/ui/components/WindowControls.d.ts +7 -1
  39. package/lib/typescript/commonjs/ui/components/WindowControls.d.ts.map +1 -1
  40. package/lib/typescript/commonjs/ui/components/index.d.ts +3 -0
  41. package/lib/typescript/commonjs/ui/components/index.d.ts.map +1 -1
  42. package/lib/typescript/commonjs/ui/components/windowDrag.d.ts +39 -0
  43. package/lib/typescript/commonjs/ui/components/windowDrag.d.ts.map +1 -0
  44. package/lib/typescript/commonjs/ui/index.d.ts +1 -0
  45. package/lib/typescript/commonjs/ui/index.d.ts.map +1 -1
  46. package/lib/typescript/commonjs/ui/otto/OttoSprite.d.ts +103 -0
  47. package/lib/typescript/commonjs/ui/otto/OttoSprite.d.ts.map +1 -0
  48. package/lib/typescript/commonjs/ui/otto/index.d.ts +19 -0
  49. package/lib/typescript/commonjs/ui/otto/index.d.ts.map +1 -0
  50. package/lib/typescript/commonjs/ui/otto/ottoEngine.d.ts +2205 -0
  51. package/lib/typescript/commonjs/ui/otto/ottoEngine.d.ts.map +1 -0
  52. package/lib/typescript/commonjs/ui/otto/ottoSheet.d.ts +73 -0
  53. package/lib/typescript/commonjs/ui/otto/ottoSheet.d.ts.map +1 -0
  54. package/lib/typescript/module/JsModal.d.ts.map +1 -1
  55. package/lib/typescript/module/hooks/safe-area-impl.d.ts +1 -1
  56. package/lib/typescript/module/storage/devToolsStorageKeys.d.ts +12 -0
  57. package/lib/typescript/module/storage/devToolsStorageKeys.d.ts.map +1 -1
  58. package/lib/typescript/module/ui/components/EmptyState.d.ts +14 -1
  59. package/lib/typescript/module/ui/components/EmptyState.d.ts.map +1 -1
  60. package/lib/typescript/module/ui/components/ModalHeader.d.ts.map +1 -1
  61. package/lib/typescript/module/ui/components/ToolEmptyState.d.ts +113 -0
  62. package/lib/typescript/module/ui/components/ToolEmptyState.d.ts.map +1 -0
  63. package/lib/typescript/module/ui/components/WindowControls.d.ts +7 -1
  64. package/lib/typescript/module/ui/components/WindowControls.d.ts.map +1 -1
  65. package/lib/typescript/module/ui/components/index.d.ts +3 -0
  66. package/lib/typescript/module/ui/components/index.d.ts.map +1 -1
  67. package/lib/typescript/module/ui/components/windowDrag.d.ts +39 -0
  68. package/lib/typescript/module/ui/components/windowDrag.d.ts.map +1 -0
  69. package/lib/typescript/module/ui/index.d.ts +1 -0
  70. package/lib/typescript/module/ui/index.d.ts.map +1 -1
  71. package/lib/typescript/module/ui/otto/OttoSprite.d.ts +103 -0
  72. package/lib/typescript/module/ui/otto/OttoSprite.d.ts.map +1 -0
  73. package/lib/typescript/module/ui/otto/index.d.ts +19 -0
  74. package/lib/typescript/module/ui/otto/index.d.ts.map +1 -0
  75. package/lib/typescript/module/ui/otto/ottoEngine.d.ts +2205 -0
  76. package/lib/typescript/module/ui/otto/ottoEngine.d.ts.map +1 -0
  77. package/lib/typescript/module/ui/otto/ottoSheet.d.ts +73 -0
  78. package/lib/typescript/module/ui/otto/ottoSheet.d.ts.map +1 -0
  79. package/package.json +4 -4
@@ -437,15 +437,19 @@ const JsModalComponent = ({
437
437
  return () => clearTimeout(timeoutId);
438
438
  }, [mode, panelHeight, dimensions, visible, persistenceKey, enablePersistence, isStateLoaded]);
439
439
 
440
- // Sync with external height if provided
440
+ // Seed the external height ONCE. This used to re-run when `isResizing`
441
+ // flipped, which snapped an externally-controlled sheet back to
442
+ // initialHeight the moment a drag-resize ended (the release handler had
443
+ // just written the real height). The host owns the value after the seed;
444
+ // persistence restore above may overwrite the seed, which is correct.
445
+ const externalHeightSeeded = (0, _react.useRef)(false);
441
446
  (0, _react.useEffect)(() => {
442
- // Height sync effect
443
- if (externalAnimatedHeight && !isResizing) {
447
+ if (externalAnimatedHeight && !externalHeightSeeded.current) {
448
+ externalHeightSeeded.current = true;
444
449
  currentHeightRef.current = initialHeight;
445
450
  externalAnimatedHeight.setValue(initialHeight);
446
- // Set external height
447
451
  }
448
- }, [externalAnimatedHeight, initialHeight, isResizing]);
452
+ }, [externalAnimatedHeight, initialHeight]);
449
453
 
450
454
  // Update refs when dimensions change
451
455
  (0, _react.useEffect)(() => {
@@ -535,11 +539,14 @@ const JsModalComponent = ({
535
539
  onModeChangeRef.current?.(savedState.mode);
536
540
  }
537
541
 
538
- // Restore bottom sheet height
542
+ // Restore bottom sheet height. The external animated height (when a
543
+ // host passes one) IS the rendered height, so it must be restored
544
+ // too or a persisted sheet always reopens at initialHeight.
539
545
  if (savedState.panelHeight) {
540
546
  setPanelHeight(savedState.panelHeight);
541
547
  currentHeightRef.current = savedState.panelHeight;
542
548
  animatedBottomPosition.setValue(savedState.panelHeight);
549
+ externalAnimatedHeight?.setValue(savedState.panelHeight);
543
550
  }
544
551
 
545
552
  // Restore floating dimensions and position
@@ -7,7 +7,7 @@ exports.useNativeSafeAreaInsets = exports.safeAreaType = exports.hasSafeAreaPack
7
7
  /**
8
8
  * Auto-generated safe area implementation
9
9
  * Detected: none
10
- * Generated at: 2026-08-29T17:41:46.184Z
10
+ * Generated at: 2026-09-02T23:25:39.783Z
11
11
  *
12
12
  * DO NOT EDIT - This file is generated by scripts/detect-safe-area.js
13
13
  *
@@ -257,6 +257,18 @@ const devToolsStorageKeys = exports.devToolsStorageKeys = {
257
257
  pausedAt: () => `${devToolsStorageKeys.events.root()}_paused_at`,
258
258
  /** Copy/export settings */
259
259
  copySettings: () => `${devToolsStorageKeys.events.root()}_copy_settings`
260
+ },
261
+ /**
262
+ * Desktop/MCP sync identity
263
+ */
264
+ sync: {
265
+ root: () => `${devToolsStorageKeys.base}_sync`,
266
+ /**
267
+ * The per-install id minted the first time this app dials the broker.
268
+ * It is what makes two devices on the same build register as two
269
+ * devices — see core's deviceIdentity.ts.
270
+ */
271
+ deviceId: () => `${devToolsStorageKeys.sync.root()}_device_id`
260
272
  }
261
273
  };
262
274
 
@@ -9,11 +9,13 @@ exports.NoResultsEmptyState = NoResultsEmptyState;
9
9
  exports.NoSearchResultsEmptyState = NoSearchResultsEmptyState;
10
10
  var _reactNative = require("react-native");
11
11
  var _macOSDesignSystemColors = require("../gameUI/constants/macOSDesignSystemColors.js");
12
+ var _index = require("../otto/index.js");
12
13
  var _jsxRuntime = require("react/jsx-runtime");
13
14
  /**
14
15
  * Reusable empty state component for consistent empty/no-data displays
15
16
  */
16
17
  function EmptyState({
18
+ otto,
17
19
  title,
18
20
  description,
19
21
  icon: Icon,
@@ -28,13 +30,19 @@ function EmptyState({
28
30
  style: containerStyle,
29
31
  children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
30
32
  style: styles.content,
31
- children: [Icon && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
33
+ children: [otto ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
34
+ style: styles.iconContainer,
35
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_index.Otto, {
36
+ state: otto,
37
+ pixelSize: Math.max(2, Math.round(iconSize / 16))
38
+ })
39
+ }) : Icon ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
32
40
  style: styles.iconContainer,
33
41
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(Icon, {
34
42
  size: iconSize,
35
43
  color: iconColor
36
44
  })
37
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
45
+ }) : null, /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
38
46
  style: styles.title,
39
47
  children: title
40
48
  }), description && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
@@ -12,6 +12,7 @@ var _reactNative = require("react-native");
12
12
  var _react = require("react");
13
13
  var _index = require("../../icons/index.js");
14
14
  var _nightTheme = require("../night/nightTheme.js");
15
+ var _windowDrag = require("./windowDrag.js");
15
16
  var _jsxRuntime = require("react/jsx-runtime");
16
17
  // Base ModalHeader container component
17
18
  // Note: onClose and onMinimize are now handled by WindowControls in JsModal
@@ -19,8 +20,12 @@ var _jsxRuntime = require("react/jsx-runtime");
19
20
  function ModalHeader({
20
21
  children
21
22
  }) {
23
+ // Tagged as a window-drag region for Buoy Desktop (see ./windowDrag): on
24
+ // the desktop dashboard this header is the top edge of a frameless window,
25
+ // so it moves the app like a title bar. Inert everywhere else.
22
26
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
23
27
  style: styles.headerContainer,
28
+ ..._windowDrag.windowDragProps,
24
29
  children: children
25
30
  });
26
31
  }
@@ -0,0 +1,154 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.ToolEmptyState = ToolEmptyState;
7
+ exports.resolveListEmptyState = resolveListEmptyState;
8
+ var _reactNative = require("react-native");
9
+ var _index = require("../otto/index.js");
10
+ var _nightTheme = require("../night/nightTheme.js");
11
+ var _jsxRuntime = require("react/jsx-runtime");
12
+ /**
13
+ * The one "nothing here" panel, for every tool that shows a list.
14
+ *
15
+ * WHY THIS EXISTS
16
+ *
17
+ * Every capture tool — network, events, highlight-updates, storage, zustand,
18
+ * redux, jotai, console — renders the same panel with the same four causes and
19
+ * different nouns. Written out per tool, that produced four copies of the same
20
+ * layout (each of which had to be re-inset by hand the first time a sentence
21
+ * was longer than "No events yet"), and four independent guesses at the
22
+ * PRECEDENCE between those causes. The guesses disagreed, and the disagreements
23
+ * were bugs:
24
+ *
25
+ * - A search that matched nothing showed "Enable tracking to start
26
+ * capturing" — pointing at a toggle that was already on.
27
+ * - Turning every source chip off showed "Events will appear here as they
28
+ * occur" — inviting you to go generate events that were already in the
29
+ * store, behind your own filter.
30
+ * - Typing into a search box while the store was empty produced no
31
+ * acknowledgement of the query at all, which reads as a dead search box.
32
+ *
33
+ * So the precedence lives here, once, and each tool supplies only what is
34
+ * genuinely its own: the noun, and what "switched on but waiting" looks like
35
+ * for it (network fishes, events listens, the highlighter stares).
36
+ *
37
+ * SPLIT IN TWO ON PURPOSE
38
+ *
39
+ * `resolveListEmptyState` is a pure function returning `{ otto, title,
40
+ * message }`, and `ToolEmptyState` renders that object. Tools with a cause
41
+ * nobody else has — storage's "no issues found" (which is a PASS, not a
42
+ * failure), zustand's unregistered store — resolve the common cases and
43
+ * substitute their own, or skip the resolver and hand the shell a literal.
44
+ * Adding a mascot to every tool at once is then one edit in this file, which is
45
+ * also what makes the Flutter and Swift ports one component to mirror instead
46
+ * of eight.
47
+ */
48
+
49
+ /** What a "nothing here" panel says. */
50
+
51
+ /**
52
+ * The panel itself: Otto, a heading, a sentence. Nothing else — this only ever
53
+ * renders where the alternative is a blank body, so it has no actions and no
54
+ * decoration to compete with the list it stands in for.
55
+ */
56
+ function ToolEmptyState({
57
+ otto,
58
+ title,
59
+ message,
60
+ testID,
61
+ style
62
+ }) {
63
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
64
+ style: [styles.container, style],
65
+ testID: testID,
66
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_index.Otto, {
67
+ state: otto,
68
+ pixelSize: 2
69
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
70
+ style: styles.title,
71
+ testID: testID ? `${testID}-title` : undefined,
72
+ numberOfLines: 2,
73
+ children: title
74
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
75
+ style: styles.message,
76
+ testID: testID ? `${testID}-text` : undefined,
77
+ children: message
78
+ })]
79
+ });
80
+ }
81
+ /**
82
+ * Which "nothing here" this is, in the order the facts answer the question.
83
+ *
84
+ * A typed query first (see `search`), then the user's filters, then the
85
+ * capture switch, then the honest "nothing yet".
86
+ */
87
+ function resolveListEmptyState(facts) {
88
+ const {
89
+ subject,
90
+ verb = "captured",
91
+ search,
92
+ total = 0,
93
+ capturing,
94
+ waiting,
95
+ paused,
96
+ blocked
97
+ } = facts;
98
+ const term = (search ?? "").trim();
99
+ if (term) {
100
+ return {
101
+ otto: "sad",
102
+ // The query goes in the HEADING because checking what you typed is the
103
+ // first thing you do; the body names whichever blocker is in the way.
104
+ title: `No results for “${term}”`,
105
+ message: blocked ?? (total > 0 ? `None of the ${total} ${verb} ${subject} match. Clear the search to see them.` : capturing === false ? `Nothing is ${verb} to search — capture is off. Turn it on to start.` : `Nothing has been ${verb} yet, so there is nothing to match.`)
106
+ };
107
+ }
108
+ if (blocked) {
109
+ return {
110
+ otto: "filtering",
111
+ title: "Filtered Out",
112
+ message: blocked
113
+ };
114
+ }
115
+ if (total > 0) {
116
+ return {
117
+ otto: "filtering",
118
+ title: "Filtered Out",
119
+ message: `${total} ${verb} ${subject} ${total === 1 ? "is" : "are"} hidden by the active filters.`
120
+ };
121
+ }
122
+ if (capturing === false) {
123
+ return {
124
+ otto: paused?.otto ?? "paused",
125
+ title: paused?.title ?? "Not capturing",
126
+ message: paused?.message ?? "Capture is off. Turn it on to start."
127
+ };
128
+ }
129
+ return waiting;
130
+ }
131
+ const styles = _reactNative.StyleSheet.create({
132
+ container: {
133
+ alignItems: "center",
134
+ paddingVertical: 40,
135
+ // The generated sentences are full sentences. Every tool that hand-rolled
136
+ // this panel shipped without an inset and had it run to both edges of the
137
+ // sheet the first time the copy grew past a few words.
138
+ paddingHorizontal: 24
139
+ },
140
+ title: {
141
+ color: _nightTheme.night.color.text,
142
+ fontSize: 14,
143
+ fontWeight: "600",
144
+ marginTop: 12,
145
+ marginBottom: 6,
146
+ textAlign: "center"
147
+ },
148
+ message: {
149
+ color: _nightTheme.night.color.textTertiary,
150
+ fontSize: 12,
151
+ textAlign: "center",
152
+ lineHeight: 17
153
+ }
154
+ });
@@ -74,7 +74,8 @@ function WindowControls({
74
74
  onMinimize,
75
75
  onToggleMode,
76
76
  mode,
77
- variant = "night"
77
+ variant = "night",
78
+ defaultExpanded
78
79
  }) {
79
80
  // Show action-based icon: what will happen when clicked
80
81
  const ToggleModeIcon = mode === "floating" ? _index.DockBottom : _index.FloatWindow;
@@ -129,7 +130,8 @@ function WindowControls({
129
130
  onMinimize: onMinimize,
130
131
  onToggleMode: onToggleMode,
131
132
  mode: mode,
132
- variant: variant
133
+ variant: variant,
134
+ defaultExpanded: defaultExpanded
133
135
  });
134
136
  }
135
137
  function ExpandableWindowControls({
@@ -137,11 +139,12 @@ function ExpandableWindowControls({
137
139
  onMinimize,
138
140
  onToggleMode,
139
141
  mode,
140
- variant = "night"
142
+ variant = "night",
143
+ defaultExpanded = false
141
144
  }) {
142
145
  const isNight = variant === "night";
143
- const [expanded, setExpanded] = (0, _react.useState)(false);
144
- const expandAnim = (0, _react.useRef)(new _reactNative.Animated.Value(0)).current;
146
+ const [expanded, setExpanded] = (0, _react.useState)(defaultExpanded);
147
+ const expandAnim = (0, _react.useRef)(new _reactNative.Animated.Value(defaultExpanded ? 1 : 0)).current;
145
148
  const dismissTimeout = (0, _react.useRef)(null);
146
149
  const ToggleModeIcon = mode === "floating" ? _index.DockBottom : _index.FloatWindow;
147
150
  const toggleModeLabel = mode === "floating" ? "Dock to bottom sheet" : "Make floating window";
@@ -303,6 +303,12 @@ Object.defineProperty(exports, "ToolButton", {
303
303
  return _ToolButton.ToolButton;
304
304
  }
305
305
  });
306
+ Object.defineProperty(exports, "ToolEmptyState", {
307
+ enumerable: true,
308
+ get: function () {
309
+ return _ToolEmptyState.ToolEmptyState;
310
+ }
311
+ });
306
312
  Object.defineProperty(exports, "ToolbarClearButton", {
307
313
  enumerable: true,
308
314
  get: function () {
@@ -339,17 +345,36 @@ Object.defineProperty(exports, "WindowControls", {
339
345
  return _WindowControls.WindowControls;
340
346
  }
341
347
  });
348
+ Object.defineProperty(exports, "noWindowDragProps", {
349
+ enumerable: true,
350
+ get: function () {
351
+ return _windowDrag.noWindowDragProps;
352
+ }
353
+ });
354
+ Object.defineProperty(exports, "resolveListEmptyState", {
355
+ enumerable: true,
356
+ get: function () {
357
+ return _ToolEmptyState.resolveListEmptyState;
358
+ }
359
+ });
342
360
  Object.defineProperty(exports, "setExpandableWindowControls", {
343
361
  enumerable: true,
344
362
  get: function () {
345
363
  return _WindowControls.setExpandableWindowControls;
346
364
  }
347
365
  });
366
+ Object.defineProperty(exports, "windowDragProps", {
367
+ enumerable: true,
368
+ get: function () {
369
+ return _windowDrag.windowDragProps;
370
+ }
371
+ });
348
372
  var _BackButton = require("./BackButton.js");
349
373
  var _ValueTypeBadge = require("./ValueTypeBadge.js");
350
374
  var _StorageTypeBadge = require("./StorageTypeBadge.js");
351
375
  var _CopyButton = require("./CopyButton.js");
352
376
  var _ModalHeader = require("./ModalHeader.js");
377
+ var _windowDrag = require("./windowDrag.js");
353
378
  var _ModalHintBanner = require("./ModalHintBanner.js");
354
379
  var _ClipboardHintBanner = require("./ClipboardHintBanner.js");
355
380
  var _SectionHeader = require("./SectionHeader.js");
@@ -365,6 +390,7 @@ var _CompactRow = require("./CompactRow.js");
365
390
  var _DevToolsCard = require("./DevToolsCard.js");
366
391
  var _HeaderSearchButton = require("./HeaderSearchButton.js");
367
392
  var _EmptyState = require("./EmptyState.js");
393
+ var _ToolEmptyState = require("./ToolEmptyState.js");
368
394
  var _StatusIndicator = require("./StatusIndicator.js");
369
395
  var _TimeDisplay = require("./TimeDisplay.js");
370
396
  var _DetailView = require("./DetailView.js");
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.windowDragProps = exports.noWindowDragProps = void 0;
7
+ /**
8
+ * Desktop window-drag tagging for tool headers.
9
+ *
10
+ * Buoy Desktop runs a FRAMELESS Electron window: nothing but a
11
+ * `-webkit-app-region: drag` region moves it. The sidebar's own header carries
12
+ * that duty, but with the sidebar open the content column has no strip of its
13
+ * own — the TOOL's header is the top edge of the window there, so grabbing it
14
+ * looked like it should move the app and didn't.
15
+ *
16
+ * These spread onto a `View` and mark the region for the desktop stylesheet
17
+ * (`apps/desktop/src/index.css`, `[data-buoy-window-drag]`). react-native-web
18
+ * turns `dataSet` into `data-*` attributes; React Native drops the prop on
19
+ * device, so this is INERT on mobile — the styling that gives it meaning only
20
+ * exists in the desktop app.
21
+ *
22
+ * `dataSet` is a react-native-web extension that RN's own prop types don't
23
+ * declare; spreading it (rather than passing it inline) is what keeps
24
+ * TypeScript quiet, and puts the explanation here once instead of a
25
+ * `@ts-ignore` at every header.
26
+ *
27
+ * A drag region SWALLOWS mouse events, so every control inside one has to opt
28
+ * back out or it stops being clickable. The desktop app does that for itself:
29
+ * react-native-web renders touchables as featureless `<div>`s, so it finds
30
+ * them at runtime by their `cursor: pointer` rather than by any selector —
31
+ * see apps/desktop/src/windowDragRegions.ts. `noWindowDragProps` is here for
32
+ * a region that must opt out regardless of how it looks.
33
+ */
34
+ const windowDragProps = exports.windowDragProps = {
35
+ dataSet: {
36
+ buoyWindowDrag: "1"
37
+ }
38
+ };
39
+
40
+ /** Opt a subtree back out of an enclosing {@link windowDragProps} region. */
41
+ const noWindowDragProps = exports.noWindowDragProps = {
42
+ dataSet: {
43
+ buoyNoDrag: "1"
44
+ }
45
+ };
@@ -56,4 +56,16 @@ Object.keys(_index3).forEach(function (key) {
56
56
  return _index3[key];
57
57
  }
58
58
  });
59
+ });
60
+ var _index4 = require("./otto/index.js");
61
+ Object.keys(_index4).forEach(function (key) {
62
+ if (key === "default" || key === "__esModule") return;
63
+ if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
64
+ if (key in exports && exports[key] === _index4[key]) return;
65
+ Object.defineProperty(exports, key, {
66
+ enumerable: true,
67
+ get: function () {
68
+ return _index4[key];
69
+ }
70
+ });
59
71
  });