@buoy-gg/shared-ui 7.0.22 → 7.0.24

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 (154) hide show
  1. package/lib/commonjs/JsModal.js +39 -16
  2. package/lib/commonjs/dataViewer/JsonStringNotice.js +59 -0
  3. package/lib/commonjs/dataViewer/ThemedSplitView.js +20 -1
  4. package/lib/commonjs/dataViewer/TimestampDeltaBar.js +96 -0
  5. package/lib/commonjs/dataViewer/index.js +52 -0
  6. package/lib/commonjs/dataViewer/jsonStringValue.js +94 -0
  7. package/lib/commonjs/dataViewer/timestampDiff.js +146 -0
  8. package/lib/commonjs/hooks/safe-area-impl.js +1 -1
  9. package/lib/commonjs/index.js +50 -1
  10. package/lib/commonjs/license/FeatureGate.js +43 -10
  11. package/lib/commonjs/license/FreeAccountPrompt.js +181 -0
  12. package/lib/commonjs/license/index.js +57 -42
  13. package/lib/commonjs/license/licenseModule.js +99 -0
  14. package/lib/commonjs/license/tierLimits.js +165 -0
  15. package/lib/commonjs/ui/backgrounds/BackgroundSwitcher.js +180 -0
  16. package/lib/commonjs/ui/backgrounds/README.md +115 -0
  17. package/lib/commonjs/ui/backgrounds/ToolBackground.js +74 -0
  18. package/lib/commonjs/ui/backgrounds/backgroundStore.js +116 -0
  19. package/lib/commonjs/ui/backgrounds/index.js +70 -0
  20. package/lib/commonjs/ui/backgrounds/primitives.js +333 -0
  21. package/lib/commonjs/ui/backgrounds/registry.js +112 -0
  22. package/lib/commonjs/ui/backgrounds/rng.js +72 -0
  23. package/lib/commonjs/ui/backgrounds/types.js +1 -0
  24. package/lib/commonjs/ui/backgrounds/variants/deepField.js +351 -0
  25. package/lib/commonjs/ui/backgrounds/variants/lattice.js +579 -0
  26. package/lib/commonjs/ui/backgrounds/variants/starfield.js +210 -0
  27. package/lib/commonjs/ui/index.js +15 -3
  28. package/lib/module/JsModal.js +39 -16
  29. package/lib/module/dataViewer/JsonStringNotice.js +54 -0
  30. package/lib/module/dataViewer/ThemedSplitView.js +20 -1
  31. package/lib/module/dataViewer/TimestampDeltaBar.js +91 -0
  32. package/lib/module/dataViewer/index.js +4 -0
  33. package/lib/module/dataViewer/jsonStringValue.js +89 -0
  34. package/lib/module/dataViewer/timestampDiff.js +139 -0
  35. package/lib/module/hooks/safe-area-impl.js +1 -1
  36. package/lib/module/index.js +1 -1
  37. package/lib/module/license/FeatureGate.js +43 -10
  38. package/lib/module/license/FreeAccountPrompt.js +176 -0
  39. package/lib/module/license/index.js +5 -40
  40. package/lib/module/license/licenseModule.js +92 -0
  41. package/lib/module/license/tierLimits.js +158 -0
  42. package/lib/module/ui/backgrounds/BackgroundSwitcher.js +176 -0
  43. package/lib/module/ui/backgrounds/README.md +115 -0
  44. package/lib/module/ui/backgrounds/ToolBackground.js +70 -0
  45. package/lib/module/ui/backgrounds/backgroundStore.js +111 -0
  46. package/lib/module/ui/backgrounds/index.js +9 -0
  47. package/lib/module/ui/backgrounds/primitives.js +328 -0
  48. package/lib/module/ui/backgrounds/registry.js +105 -0
  49. package/lib/module/ui/backgrounds/rng.js +65 -0
  50. package/lib/module/ui/backgrounds/types.js +1 -0
  51. package/lib/module/ui/backgrounds/variants/deepField.js +347 -0
  52. package/lib/module/ui/backgrounds/variants/lattice.js +575 -0
  53. package/lib/module/ui/backgrounds/variants/starfield.js +206 -0
  54. package/lib/module/ui/index.js +3 -0
  55. package/lib/typescript/commonjs/JsModal.d.ts.map +1 -1
  56. package/lib/typescript/commonjs/dataViewer/JsonStringNotice.d.ts +6 -0
  57. package/lib/typescript/commonjs/dataViewer/JsonStringNotice.d.ts.map +1 -0
  58. package/lib/typescript/commonjs/dataViewer/ThemedSplitView.d.ts.map +1 -1
  59. package/lib/typescript/commonjs/dataViewer/TimestampDeltaBar.d.ts +7 -0
  60. package/lib/typescript/commonjs/dataViewer/TimestampDeltaBar.d.ts.map +1 -0
  61. package/lib/typescript/commonjs/dataViewer/index.d.ts +6 -0
  62. package/lib/typescript/commonjs/dataViewer/index.d.ts.map +1 -1
  63. package/lib/typescript/commonjs/dataViewer/jsonStringValue.d.ts +25 -0
  64. package/lib/typescript/commonjs/dataViewer/jsonStringValue.d.ts.map +1 -0
  65. package/lib/typescript/commonjs/dataViewer/timestampDiff.d.ts +55 -0
  66. package/lib/typescript/commonjs/dataViewer/timestampDiff.d.ts.map +1 -0
  67. package/lib/typescript/commonjs/hooks/safe-area-impl.d.ts +1 -1
  68. package/lib/typescript/commonjs/index.d.ts +2 -2
  69. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  70. package/lib/typescript/commonjs/license/FeatureGate.d.ts +19 -3
  71. package/lib/typescript/commonjs/license/FeatureGate.d.ts.map +1 -1
  72. package/lib/typescript/commonjs/license/FreeAccountPrompt.d.ts +23 -0
  73. package/lib/typescript/commonjs/license/FreeAccountPrompt.d.ts.map +1 -0
  74. package/lib/typescript/commonjs/license/index.d.ts +6 -15
  75. package/lib/typescript/commonjs/license/index.d.ts.map +1 -1
  76. package/lib/typescript/commonjs/license/licenseModule.d.ts +55 -0
  77. package/lib/typescript/commonjs/license/licenseModule.d.ts.map +1 -0
  78. package/lib/typescript/commonjs/license/tierLimits.d.ts +143 -0
  79. package/lib/typescript/commonjs/license/tierLimits.d.ts.map +1 -0
  80. package/lib/typescript/commonjs/ui/backgrounds/BackgroundSwitcher.d.ts +13 -0
  81. package/lib/typescript/commonjs/ui/backgrounds/BackgroundSwitcher.d.ts.map +1 -0
  82. package/lib/typescript/commonjs/ui/backgrounds/ToolBackground.d.ts +30 -0
  83. package/lib/typescript/commonjs/ui/backgrounds/ToolBackground.d.ts.map +1 -0
  84. package/lib/typescript/commonjs/ui/backgrounds/backgroundStore.d.ts +43 -0
  85. package/lib/typescript/commonjs/ui/backgrounds/backgroundStore.d.ts.map +1 -0
  86. package/lib/typescript/commonjs/ui/backgrounds/index.d.ts +7 -0
  87. package/lib/typescript/commonjs/ui/backgrounds/index.d.ts.map +1 -0
  88. package/lib/typescript/commonjs/ui/backgrounds/primitives.d.ts +106 -0
  89. package/lib/typescript/commonjs/ui/backgrounds/primitives.d.ts.map +1 -0
  90. package/lib/typescript/commonjs/ui/backgrounds/registry.d.ts +28 -0
  91. package/lib/typescript/commonjs/ui/backgrounds/registry.d.ts.map +1 -0
  92. package/lib/typescript/commonjs/ui/backgrounds/rng.d.ts +27 -0
  93. package/lib/typescript/commonjs/ui/backgrounds/rng.d.ts.map +1 -0
  94. package/lib/typescript/commonjs/ui/backgrounds/types.d.ts +14 -0
  95. package/lib/typescript/commonjs/ui/backgrounds/types.d.ts.map +1 -0
  96. package/lib/typescript/commonjs/ui/backgrounds/variants/deepField.d.ts +65 -0
  97. package/lib/typescript/commonjs/ui/backgrounds/variants/deepField.d.ts.map +1 -0
  98. package/lib/typescript/commonjs/ui/backgrounds/variants/lattice.d.ts +33 -0
  99. package/lib/typescript/commonjs/ui/backgrounds/variants/lattice.d.ts.map +1 -0
  100. package/lib/typescript/commonjs/ui/backgrounds/variants/starfield.d.ts +12 -0
  101. package/lib/typescript/commonjs/ui/backgrounds/variants/starfield.d.ts.map +1 -0
  102. package/lib/typescript/commonjs/ui/index.d.ts +1 -0
  103. package/lib/typescript/commonjs/ui/index.d.ts.map +1 -1
  104. package/lib/typescript/module/JsModal.d.ts.map +1 -1
  105. package/lib/typescript/module/dataViewer/JsonStringNotice.d.ts +6 -0
  106. package/lib/typescript/module/dataViewer/JsonStringNotice.d.ts.map +1 -0
  107. package/lib/typescript/module/dataViewer/ThemedSplitView.d.ts.map +1 -1
  108. package/lib/typescript/module/dataViewer/TimestampDeltaBar.d.ts +7 -0
  109. package/lib/typescript/module/dataViewer/TimestampDeltaBar.d.ts.map +1 -0
  110. package/lib/typescript/module/dataViewer/index.d.ts +6 -0
  111. package/lib/typescript/module/dataViewer/index.d.ts.map +1 -1
  112. package/lib/typescript/module/dataViewer/jsonStringValue.d.ts +25 -0
  113. package/lib/typescript/module/dataViewer/jsonStringValue.d.ts.map +1 -0
  114. package/lib/typescript/module/dataViewer/timestampDiff.d.ts +55 -0
  115. package/lib/typescript/module/dataViewer/timestampDiff.d.ts.map +1 -0
  116. package/lib/typescript/module/hooks/safe-area-impl.d.ts +1 -1
  117. package/lib/typescript/module/index.d.ts +2 -2
  118. package/lib/typescript/module/index.d.ts.map +1 -1
  119. package/lib/typescript/module/license/FeatureGate.d.ts +19 -3
  120. package/lib/typescript/module/license/FeatureGate.d.ts.map +1 -1
  121. package/lib/typescript/module/license/FreeAccountPrompt.d.ts +23 -0
  122. package/lib/typescript/module/license/FreeAccountPrompt.d.ts.map +1 -0
  123. package/lib/typescript/module/license/index.d.ts +6 -15
  124. package/lib/typescript/module/license/index.d.ts.map +1 -1
  125. package/lib/typescript/module/license/licenseModule.d.ts +55 -0
  126. package/lib/typescript/module/license/licenseModule.d.ts.map +1 -0
  127. package/lib/typescript/module/license/tierLimits.d.ts +143 -0
  128. package/lib/typescript/module/license/tierLimits.d.ts.map +1 -0
  129. package/lib/typescript/module/ui/backgrounds/BackgroundSwitcher.d.ts +13 -0
  130. package/lib/typescript/module/ui/backgrounds/BackgroundSwitcher.d.ts.map +1 -0
  131. package/lib/typescript/module/ui/backgrounds/ToolBackground.d.ts +30 -0
  132. package/lib/typescript/module/ui/backgrounds/ToolBackground.d.ts.map +1 -0
  133. package/lib/typescript/module/ui/backgrounds/backgroundStore.d.ts +43 -0
  134. package/lib/typescript/module/ui/backgrounds/backgroundStore.d.ts.map +1 -0
  135. package/lib/typescript/module/ui/backgrounds/index.d.ts +7 -0
  136. package/lib/typescript/module/ui/backgrounds/index.d.ts.map +1 -0
  137. package/lib/typescript/module/ui/backgrounds/primitives.d.ts +106 -0
  138. package/lib/typescript/module/ui/backgrounds/primitives.d.ts.map +1 -0
  139. package/lib/typescript/module/ui/backgrounds/registry.d.ts +28 -0
  140. package/lib/typescript/module/ui/backgrounds/registry.d.ts.map +1 -0
  141. package/lib/typescript/module/ui/backgrounds/rng.d.ts +27 -0
  142. package/lib/typescript/module/ui/backgrounds/rng.d.ts.map +1 -0
  143. package/lib/typescript/module/ui/backgrounds/types.d.ts +14 -0
  144. package/lib/typescript/module/ui/backgrounds/types.d.ts.map +1 -0
  145. package/lib/typescript/module/ui/backgrounds/variants/deepField.d.ts +65 -0
  146. package/lib/typescript/module/ui/backgrounds/variants/deepField.d.ts.map +1 -0
  147. package/lib/typescript/module/ui/backgrounds/variants/lattice.d.ts +33 -0
  148. package/lib/typescript/module/ui/backgrounds/variants/lattice.d.ts.map +1 -0
  149. package/lib/typescript/module/ui/backgrounds/variants/starfield.d.ts +12 -0
  150. package/lib/typescript/module/ui/backgrounds/variants/starfield.d.ts.map +1 -0
  151. package/lib/typescript/module/ui/index.d.ts +1 -0
  152. package/lib/typescript/module/ui/index.d.ts.map +1 -1
  153. package/package.json +4 -4
  154. package/scripts/detect-safe-area.js +0 -20
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "BACKGROUND_PRESETS", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _registry.BACKGROUND_PRESETS;
10
+ }
11
+ });
12
+ Object.defineProperty(exports, "BackgroundSwitcher", {
13
+ enumerable: true,
14
+ get: function () {
15
+ return _BackgroundSwitcher.BackgroundSwitcher;
16
+ }
17
+ });
18
+ Object.defineProperty(exports, "DEFAULT_BACKGROUND", {
19
+ enumerable: true,
20
+ get: function () {
21
+ return _registry.DEFAULT_BACKGROUND;
22
+ }
23
+ });
24
+ Object.defineProperty(exports, "DeepFieldTunable", {
25
+ enumerable: true,
26
+ get: function () {
27
+ return _deepField.DeepFieldTunable;
28
+ }
29
+ });
30
+ Object.defineProperty(exports, "ToolBackground", {
31
+ enumerable: true,
32
+ get: function () {
33
+ return _ToolBackground.ToolBackground;
34
+ }
35
+ });
36
+ Object.defineProperty(exports, "backgroundStore", {
37
+ enumerable: true,
38
+ get: function () {
39
+ return _backgroundStore.backgroundStore;
40
+ }
41
+ });
42
+ Object.defineProperty(exports, "getPreset", {
43
+ enumerable: true,
44
+ get: function () {
45
+ return _registry.getPreset;
46
+ }
47
+ });
48
+ Object.defineProperty(exports, "presetAt", {
49
+ enumerable: true,
50
+ get: function () {
51
+ return _registry.presetAt;
52
+ }
53
+ });
54
+ Object.defineProperty(exports, "presetIndex", {
55
+ enumerable: true,
56
+ get: function () {
57
+ return _registry.presetIndex;
58
+ }
59
+ });
60
+ Object.defineProperty(exports, "useToolBackground", {
61
+ enumerable: true,
62
+ get: function () {
63
+ return _backgroundStore.useToolBackground;
64
+ }
65
+ });
66
+ var _ToolBackground = require("./ToolBackground.js");
67
+ var _BackgroundSwitcher = require("./BackgroundSwitcher.js");
68
+ var _backgroundStore = require("./backgroundStore.js");
69
+ var _registry = require("./registry.js");
70
+ var _deepField = require("./variants/deepField.js");
@@ -0,0 +1,333 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.hairline = exports.Vignette = exports.RasterLayer = exports.RadialGlow = exports.LinearFade = exports.Base = void 0;
7
+ exports.useLoop = useLoop;
8
+ exports.usePulse = usePulse;
9
+ var _react = require("react");
10
+ var _reactNative = require("react-native");
11
+ var _absoluteFill = require("../../utils/absoluteFill.js");
12
+ var _rng = require("./rng.js");
13
+ var _jsxRuntime = require("react/jsx-runtime");
14
+ /**
15
+ * Drawing + animation primitives for the tool backgrounds.
16
+ *
17
+ * HARD CONSTRAINT: Buoy's packages peer-depend on nothing but `react` and
18
+ * `react-native`. No Skia, no Reanimated, no SVG, no gradient library — a
19
+ * devtool cannot force a native dependency into someone's app. So every
20
+ * background here is built out of plain `View`s plus `Animated`, and the
21
+ * gradients/glows below are *faked* by stacking translucent layers.
22
+ *
23
+ * That sounds expensive. It isn't, because of two rules every preset follows:
24
+ *
25
+ * 1. **Every animation is native-driven.** `useNativeDriver: true` on a
26
+ * looping `Animated.timing` means the whole loop is handed to the UI thread
27
+ * once and never touches JS again — no per-frame callback, no re-render, no
28
+ * bridge traffic while it runs. A preset animates a handful of *layers*
29
+ * (transform on one parent view), never per-particle.
30
+ *
31
+ * 2. **Every static layer is rasterized.** `shouldRasterizeIOS` /
32
+ * `renderToHardwareTextureAndroid` turn a layer of 40 dots into a single
33
+ * cached GPU texture, so sliding it is one composite — the same cost as
34
+ * sliding one view. See `RasterLayer`.
35
+ *
36
+ * The result: a preset costs a one-time mount of static views and then ~0
37
+ * JS-thread work per frame. See `packages/shared/src/ui/backgrounds/README.md`.
38
+ */
39
+
40
+ // ============================================================================
41
+ // Animation
42
+ // ============================================================================
43
+
44
+ /**
45
+ * A native-driven 0→1 loop.
46
+ *
47
+ * The returned value is only ever consumed by `interpolate` inside an
48
+ * `Animated.View` style, so React never re-renders while it runs. The loop is
49
+ * stopped when the app backgrounds (a background animation is pure battery
50
+ * burn) and restarted on foreground.
51
+ */
52
+ function useLoop(durationMs, enabled = true) {
53
+ const value = (0, _react.useRef)(new _reactNative.Animated.Value(0)).current;
54
+ (0, _react.useEffect)(() => {
55
+ if (!enabled) return;
56
+ let anim = null;
57
+ const start = () => {
58
+ if (anim) return;
59
+ value.setValue(0);
60
+ anim = _reactNative.Animated.loop(_reactNative.Animated.timing(value, {
61
+ toValue: 1,
62
+ duration: durationMs,
63
+ easing: _reactNative.Easing.linear,
64
+ useNativeDriver: true
65
+ }));
66
+ anim.start();
67
+ };
68
+ const stop = () => {
69
+ anim?.stop();
70
+ anim = null;
71
+ value.setValue(0);
72
+ };
73
+ start();
74
+ const sub = _reactNative.AppState.addEventListener("change", state => {
75
+ if (state === "active") start();else stop();
76
+ });
77
+ return () => {
78
+ stop();
79
+ sub.remove();
80
+ };
81
+ }, [durationMs, enabled, value]);
82
+ return value;
83
+ }
84
+
85
+ /**
86
+ * A native-driven 0→1→0 breathe, for glows that pulse rather than travel.
87
+ * Same no-JS-per-frame guarantee as `useLoop`.
88
+ */
89
+ function usePulse(durationMs, enabled = true) {
90
+ const value = (0, _react.useRef)(new _reactNative.Animated.Value(0)).current;
91
+ (0, _react.useEffect)(() => {
92
+ if (!enabled) return;
93
+ let anim = null;
94
+ const start = () => {
95
+ if (anim) return;
96
+ value.setValue(0);
97
+ anim = _reactNative.Animated.loop(_reactNative.Animated.sequence([_reactNative.Animated.timing(value, {
98
+ toValue: 1,
99
+ duration: durationMs / 2,
100
+ easing: _reactNative.Easing.inOut(_reactNative.Easing.quad),
101
+ useNativeDriver: true
102
+ }), _reactNative.Animated.timing(value, {
103
+ toValue: 0,
104
+ duration: durationMs / 2,
105
+ easing: _reactNative.Easing.inOut(_reactNative.Easing.quad),
106
+ useNativeDriver: true
107
+ })]));
108
+ anim.start();
109
+ };
110
+ const stop = () => {
111
+ anim?.stop();
112
+ anim = null;
113
+ };
114
+ start();
115
+ const sub = _reactNative.AppState.addEventListener("change", state => {
116
+ if (state === "active") start();else stop();
117
+ });
118
+ return () => {
119
+ stop();
120
+ sub.remove();
121
+ };
122
+ }, [durationMs, enabled, value]);
123
+ return value;
124
+ }
125
+
126
+ // ============================================================================
127
+ // Layers
128
+ // ============================================================================
129
+
130
+ /**
131
+ * A layer whose children are static and should be flattened into one GPU
132
+ * texture. Wrap anything that gets translated/scaled as a whole — this is what
133
+ * makes a 40-dot star band cost the same to move as a single view.
134
+ */
135
+ const RasterLayer = exports.RasterLayer = /*#__PURE__*/(0, _react.memo)(function RasterLayer({
136
+ style,
137
+ raster = true,
138
+ children
139
+ }) {
140
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
141
+ style: style,
142
+ pointerEvents: "none"
143
+ // Both are no-ops on the platform they don't belong to, and on web
144
+ // (react-native-web) neither exists — there the browser already
145
+ // composites a transformed subtree on the GPU.
146
+ ,
147
+ shouldRasterizeIOS: raster && _reactNative.Platform.OS === "ios",
148
+ renderToHardwareTextureAndroid: raster && _reactNative.Platform.OS === "android",
149
+ children: children
150
+ });
151
+ });
152
+
153
+ /**
154
+ * Fake radial gradient: concentric rounded views, each a constant per-ring
155
+ * alpha, with radii shrinking on a curve. Alpha compositing of N equal layers
156
+ * gives `1 - (1-a)^N` at the centre, so `a` is solved from the requested peak
157
+ * alpha and the falloff comes from the radius curve.
158
+ *
159
+ * 8 rings is the sweet spot on a dark surface — below that you can see banding,
160
+ * above it you're paying for views nobody can distinguish.
161
+ */
162
+ const RadialGlow = exports.RadialGlow = /*#__PURE__*/(0, _react.memo)(function RadialGlow({
163
+ size,
164
+ color,
165
+ alpha = 0.35,
166
+ rings = 8,
167
+ falloff = 1.7,
168
+ style
169
+ }) {
170
+ const per = 1 - Math.pow(1 - alpha, 1 / rings);
171
+ const layers = [];
172
+ for (let i = 0; i < rings; i++) {
173
+ const d = size * Math.pow((rings - i) / rings, falloff);
174
+ layers.push(/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
175
+ style: {
176
+ position: "absolute",
177
+ left: (size - d) / 2,
178
+ top: (size - d) / 2,
179
+ width: d,
180
+ height: d,
181
+ borderRadius: d / 2,
182
+ backgroundColor: (0, _rng.withAlpha)(color, per)
183
+ }
184
+ }, i));
185
+ }
186
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
187
+ style: [{
188
+ width: size,
189
+ height: size
190
+ }, style],
191
+ pointerEvents: "none",
192
+ shouldRasterizeIOS: _reactNative.Platform.OS === "ios",
193
+ renderToHardwareTextureAndroid: _reactNative.Platform.OS === "android",
194
+ children: layers
195
+ });
196
+ });
197
+
198
+ /**
199
+ * Fake linear gradient: `bands` stacked strips with linearly interpolated
200
+ * alpha. Used for scrims (keep text readable over a busy field) and for
201
+ * horizon glows. 12–16 bands is invisible as banding at these alphas.
202
+ */
203
+ const LinearFade = exports.LinearFade = /*#__PURE__*/(0, _react.memo)(function LinearFade({
204
+ color,
205
+ from = 0,
206
+ to = 1,
207
+ bands = 14,
208
+ direction = "down",
209
+ style
210
+ }) {
211
+ const vertical = direction === "down" || direction === "up";
212
+ const reversed = direction === "up" || direction === "left";
213
+ const pct = 100 / bands;
214
+ const strips = [];
215
+ for (let i = 0; i < bands; i++) {
216
+ const t = (i + 0.5) / bands;
217
+ const a = from + (to - from) * (reversed ? 1 - t : t);
218
+ strips.push(/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
219
+ style: vertical ? {
220
+ position: "absolute",
221
+ left: 0,
222
+ right: 0,
223
+ top: `${i * pct}%`,
224
+ height: `${pct + 1.2}%`,
225
+ backgroundColor: (0, _rng.withAlpha)(color, a)
226
+ } : {
227
+ position: "absolute",
228
+ top: 0,
229
+ bottom: 0,
230
+ left: `${i * pct}%`,
231
+ width: `${pct + 1.2}%`,
232
+ backgroundColor: (0, _rng.withAlpha)(color, a)
233
+ }
234
+ }, i));
235
+ }
236
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
237
+ style: [_absoluteFill.absoluteFill, style],
238
+ pointerEvents: "none",
239
+ children: strips
240
+ });
241
+ });
242
+
243
+ /**
244
+ * Edge darkening. Four `LinearFade`s rather than a real radial vignette —
245
+ * cheaper, and at these alphas the corners read as round anyway.
246
+ */
247
+ const Vignette = exports.Vignette = /*#__PURE__*/(0, _react.memo)(function Vignette({
248
+ color = "#000000",
249
+ alpha = 0.55,
250
+ spread = 0.34
251
+ }) {
252
+ // Each fade fills its own positioned band, rather than trying to unset
253
+ // `absoluteFill`'s edges through the style array.
254
+ const band = `${spread * 100}%`;
255
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
256
+ style: _absoluteFill.absoluteFill,
257
+ pointerEvents: "none",
258
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
259
+ style: {
260
+ position: "absolute",
261
+ left: 0,
262
+ right: 0,
263
+ top: 0,
264
+ height: band
265
+ },
266
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(LinearFade, {
267
+ color: color,
268
+ from: alpha,
269
+ to: 0,
270
+ direction: "down",
271
+ bands: 10
272
+ })
273
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
274
+ style: {
275
+ position: "absolute",
276
+ left: 0,
277
+ right: 0,
278
+ bottom: 0,
279
+ height: band
280
+ },
281
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(LinearFade, {
282
+ color: color,
283
+ from: 0,
284
+ to: alpha,
285
+ direction: "down",
286
+ bands: 10
287
+ })
288
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
289
+ style: {
290
+ position: "absolute",
291
+ top: 0,
292
+ bottom: 0,
293
+ left: 0,
294
+ width: band
295
+ },
296
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(LinearFade, {
297
+ color: color,
298
+ from: alpha,
299
+ to: 0,
300
+ direction: "right",
301
+ bands: 8
302
+ })
303
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
304
+ style: {
305
+ position: "absolute",
306
+ top: 0,
307
+ bottom: 0,
308
+ right: 0,
309
+ width: band
310
+ },
311
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(LinearFade, {
312
+ color: color,
313
+ from: 0,
314
+ to: alpha,
315
+ direction: "right",
316
+ bands: 8
317
+ })
318
+ })]
319
+ });
320
+ });
321
+
322
+ /** Flat wash used as the base coat under every preset. */
323
+ const Base = exports.Base = /*#__PURE__*/(0, _react.memo)(function Base({
324
+ color
325
+ }) {
326
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
327
+ style: [_absoluteFill.absoluteFill, {
328
+ backgroundColor: color
329
+ }],
330
+ pointerEvents: "none"
331
+ });
332
+ });
333
+ const hairline = exports.hairline = _reactNative.StyleSheet.hairlineWidth;
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.DEFAULT_BACKGROUND = exports.BACKGROUND_PRESETS = void 0;
7
+ exports.getPreset = getPreset;
8
+ exports.presetAt = presetAt;
9
+ exports.presetIndex = presetIndex;
10
+ var _lattice = require("./variants/lattice.js");
11
+ var _deepField = require("./variants/deepField.js");
12
+ var _starfield = require("./variants/starfield.js");
13
+ /**
14
+ * The catalogue. Adding a preset means adding one entry here — the switcher,
15
+ * the persisted selection and every tool surface read from this list.
16
+ *
17
+ * `nodes` and `views` are not decoration: they are the number of native
18
+ * animated nodes the preset runs and the rough count of static views it mounts,
19
+ * so the switcher can show what each look costs while you compare them. Keep
20
+ * them honest.
21
+ */
22
+
23
+ const BACKGROUND_PRESETS = exports.BACKGROUND_PRESETS = [{
24
+ id: "off",
25
+ label: "Off",
26
+ blurb: "Plain black — the baseline to compare against",
27
+ nodes: 0,
28
+ views: 1,
29
+ Component: null
30
+ }, {
31
+ id: "starfield",
32
+ label: "Starfield",
33
+ blurb: "Five depth bands drifting at parallax speeds",
34
+ nodes: 6,
35
+ views: 222,
36
+ Component: _starfield.Starfield
37
+ }, {
38
+ id: "deepfield",
39
+ label: "Deep Field",
40
+ blurb: "The Everlights field, 1:1 — 160 stars, richer but pricier",
41
+ nodes: 22,
42
+ views: 462,
43
+ Component: _deepField.DeepField
44
+ }, {
45
+ id: "hexmesh",
46
+ label: "Hex Mesh",
47
+ blurb: "Diamond lattice with a slow breath",
48
+ nodes: 1,
49
+ views: 160,
50
+ Component: _lattice.HexMesh
51
+ }, {
52
+ id: "isogrid",
53
+ label: "Iso Grid",
54
+ blurb: "Three-axis isometric ruling",
55
+ nodes: 1,
56
+ views: 66,
57
+ Component: _lattice.IsoGrid
58
+ }, {
59
+ id: "crosshatch",
60
+ label: "Crosshatch",
61
+ blurb: "Fine 45° weave, drafting-paper quiet",
62
+ nodes: 1,
63
+ views: 64,
64
+ Component: _lattice.Crosshatch
65
+ }, {
66
+ id: "perfboard",
67
+ label: "Perf Board",
68
+ blurb: "Solder-pad matrix with datum pads every fourth",
69
+ nodes: 1,
70
+ views: 150,
71
+ Component: _lattice.PerfBoard
72
+ }, {
73
+ id: "halftone",
74
+ label: "Halftone",
75
+ blurb: "Dot grid swelling toward the light",
76
+ nodes: 1,
77
+ views: 176,
78
+ Component: _lattice.Halftone
79
+ }, {
80
+ id: "waffle",
81
+ label: "Waffle",
82
+ blurb: "Machined panel of rounded cells",
83
+ nodes: 1,
84
+ views: 88,
85
+ Component: _lattice.Waffle
86
+ }, {
87
+ id: "instrument",
88
+ label: "Instrument",
89
+ blurb: "Ruled scales with major graduations",
90
+ nodes: 1,
91
+ views: 110,
92
+ Component: _lattice.Instrument
93
+ }, {
94
+ id: "radar",
95
+ label: "Radar",
96
+ blurb: "Rings and spokes under a rotating sweep",
97
+ nodes: 2,
98
+ views: 40,
99
+ Component: _lattice.Radar
100
+ }];
101
+ const DEFAULT_BACKGROUND = exports.DEFAULT_BACKGROUND = "hexmesh";
102
+ function presetIndex(id) {
103
+ const i = BACKGROUND_PRESETS.findIndex(p => p.id === id);
104
+ return i < 0 ? 0 : i;
105
+ }
106
+ function presetAt(index) {
107
+ const n = BACKGROUND_PRESETS.length;
108
+ return BACKGROUND_PRESETS[(index % n + n) % n];
109
+ }
110
+ function getPreset(id) {
111
+ return BACKGROUND_PRESETS[presetIndex(id)];
112
+ }
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.flattenOver = flattenOver;
7
+ exports.mulberry32 = mulberry32;
8
+ exports.scatter = scatter;
9
+ exports.withAlpha = withAlpha;
10
+ /**
11
+ * Deterministic scatter tables for the tool backgrounds.
12
+ *
13
+ * Every preset needs a pile of "random" positions, sizes and phases. Those are
14
+ * generated ONCE at module load from a fixed seed and frozen, so:
15
+ * - the same seed always paints the same field (screenshots are stable, and
16
+ * two tools showing the same background look identical),
17
+ * - no allocation happens on mount or on any re-render — the presets only
18
+ * read these arrays.
19
+ *
20
+ * Ported from the seeded field in the Everlights starfield (mulberry32).
21
+ */
22
+
23
+ function mulberry32(seed) {
24
+ return () => {
25
+ seed = seed + 0x6d2b79f5 | 0;
26
+ let t = Math.imul(seed ^ seed >>> 15, 1 | seed);
27
+ t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
28
+ return ((t ^ t >>> 14) >>> 0) / 4294967296;
29
+ };
30
+ }
31
+
32
+ /** `count` numbers in [0,1) from `seed`. */
33
+ function scatter(seed, count) {
34
+ const rnd = mulberry32(seed >>> 0);
35
+ const out = new Array(count);
36
+ for (let i = 0; i < count; i++) out[i] = rnd();
37
+ return out;
38
+ }
39
+
40
+ /** `#RRGGBB` (or `#RGB`) + alpha 0..1 → `rgba(...)`. */
41
+ function withAlpha(hex, alpha) {
42
+ let h = hex.replace("#", "");
43
+ if (h.length === 3) h = h[0] + h[0] + h[1] + h[1] + h[2] + h[2];
44
+ const n = parseInt(h, 16);
45
+ const r = n >> 16 & 255;
46
+ const g = n >> 8 & 255;
47
+ const b = n & 255;
48
+ const a = alpha < 0 ? 0 : alpha > 1 ? 1 : alpha;
49
+ return `rgba(${r},${g},${b},${a.toFixed(3)})`;
50
+ }
51
+
52
+ /**
53
+ * `hex` at `alpha` composited over an opaque `base`, returned as an OPAQUE
54
+ * colour.
55
+ *
56
+ * Over a known backdrop this is pixel-identical to drawing the translucent
57
+ * colour — the GPU just doesn't have to blend it. Only valid where nothing
58
+ * else sits between the layer and `base`.
59
+ */
60
+ function flattenOver(hex, alpha, base) {
61
+ const parse = h => {
62
+ let v = h.replace("#", "");
63
+ if (v.length === 3) v = v[0] + v[0] + v[1] + v[1] + v[2] + v[2];
64
+ const n = parseInt(v, 16);
65
+ return [n >> 16 & 255, n >> 8 & 255, n & 255];
66
+ };
67
+ const [r, g, b] = parse(hex);
68
+ const [br, bg, bb] = parse(base);
69
+ const a = alpha < 0 ? 0 : alpha > 1 ? 1 : alpha;
70
+ const mix = (c, bc) => Math.round(c * a + bc * (1 - a));
71
+ return `rgb(${mix(r, br)},${mix(g, bg)},${mix(b, bb)})`;
72
+ }
@@ -0,0 +1 @@
1
+ "use strict";