@multiplatform.one/core 7.1.0 → 7.2.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@multiplatform.one/core",
3
- "version": "7.1.0",
3
+ "version": "7.2.1",
4
4
  "description": "Core framework shell, provider composition, and layout factories for multiplatform.one",
5
5
  "keywords": [
6
6
  "app",
@@ -42,15 +42,16 @@
42
42
  },
43
43
  "dependencies": {
44
44
  "@tanstack/devtools-event-client": "^0.4.3",
45
+ "@tanstack/devtools-utils": "^0.4.0",
46
+ "@tanstack/pacer-devtools": "1.3.0",
45
47
  "@tanstack/react-devtools": "^0.10.2",
46
48
  "@tanstack/react-form-devtools": "0.2.22",
47
- "@tanstack/react-pacer-devtools": "^0.7.0",
48
49
  "react-cookie": "^8.1.2",
49
- "@multiplatform.one/i18n": "7.1.0",
50
- "@multiplatform.one/logger": "7.1.0",
51
- "@multiplatform.one/platform": "7.1.0",
52
- "@multiplatform.one/store": "7.1.0",
53
- "@multiplatform.one/theme": "7.1.0"
50
+ "@multiplatform.one/platform": "7.2.1",
51
+ "@multiplatform.one/store": "7.2.1",
52
+ "@multiplatform.one/theme": "7.2.1",
53
+ "@multiplatform.one/i18n": "7.2.1",
54
+ "@multiplatform.one/logger": "7.2.1"
54
55
  },
55
56
  "devDependencies": {
56
57
  "@sentry/react": "^10.51.0",
@@ -68,8 +69,8 @@
68
69
  "tamagui": "2.7.6",
69
70
  "typescript": "~5.9.3",
70
71
  "vitest": "^4.1.5",
71
- "@multiplatform.one/frappe": "7.1.0",
72
- "@multiplatform.one/web3": "7.1.0"
72
+ "@multiplatform.one/frappe": "7.2.1",
73
+ "@multiplatform.one/web3": "7.2.1"
73
74
  },
74
75
  "peerDependencies": {
75
76
  "@sentry/react": "^9.0.0",
@@ -85,10 +86,10 @@
85
86
  "react-native-gesture-handler": ">=2.0.0",
86
87
  "react-native-safe-area-context": ">=4.0.0",
87
88
  "tamagui": "^2.0.0-rc",
88
- "@multiplatform.one/frappe": "^7.1.0",
89
- "@multiplatform.one/frappe-ui": "^7.1.0",
90
- "@multiplatform.one/keycloak": "^7.1.0",
91
- "@multiplatform.one/web3": "^7.1.0"
89
+ "@multiplatform.one/frappe": "^7.2.1",
90
+ "@multiplatform.one/web3": "^7.2.1",
91
+ "@multiplatform.one/frappe-ui": "^7.2.1",
92
+ "@multiplatform.one/keycloak": "^7.2.1"
92
93
  },
93
94
  "peerDependenciesMeta": {
94
95
  "@multiplatform.one/web3": {
@@ -52,6 +52,15 @@ export function followPageOriginForLoopback(configured: string): string {
52
52
  export interface TanstackConfig {
53
53
  /** Show React Query devtools (web only, ignored on native and in Storybook). */
54
54
  debug?: boolean;
55
+ /**
56
+ * Shake the device to open the devtools shell (web only; requires
57
+ * `debug`). Defaults to true whenever the devtools mount. On iOS 13+
58
+ * WebKit the motion permission is requested once from the user's first
59
+ * tap; Android and desktop need no permission (desktop simply never
60
+ * fires devicemotion — use Cmd/Ctrl+Shift+` there). Set false to
61
+ * keep the keyboard shortcut as the only trigger.
62
+ */
63
+ shakeToOpen?: boolean;
55
64
  /** Options forwarded to the QueryClient constructor. */
56
65
  queryClientOptions?: Record<string, unknown>;
57
66
  /**
@@ -70,6 +79,22 @@ export interface TanstackConfig {
70
79
  * Passed automatically by `createApp()` from the theme config.
71
80
  */
72
81
  tamaguiConfig?: unknown;
82
+ /**
83
+ * Theme COLOR names the devtools panel offers in its accent dropdown
84
+ * (e.g. `["", "blue", "green", "purple"]`; `""` is the base theme).
85
+ * The panel renders the dropdown only when this AND `onThemeColorChange`
86
+ * are both set, and only then does the panel's Randomize action touch the
87
+ * accent — otherwise the picker is inert.
88
+ */
89
+ themeColors?: string[];
90
+ /** The theme color the app currently has applied (`""` for the base). */
91
+ currentThemeColor?: string;
92
+ /**
93
+ * Apply a theme color the user picked. The app owns this because a theme
94
+ * color is app state, not devtools state: the panel changes nothing on its
95
+ * own, it hands the choice back.
96
+ */
97
+ onThemeColorChange?: (color: string) => void;
73
98
  }
74
99
 
75
100
  export interface KeycloakConfig {
@@ -1,15 +1,36 @@
1
1
  import React from "react";
2
- import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
2
+ // The `/production` subpaths carry the same implementations the main
3
+ // entries carry in development, but WITHOUT the NODE_ENV !== "development"
4
+ // no-op stubs the main entries dead-code themselves into in a production
5
+ // build. This whole file is lazy-loaded and gated on `tanstackConfig.debug`,
6
+ // so importing the real panels unconditionally is what lets a deployed
7
+ // build that opts in (debug: true) actually show devtools.
8
+ import { ReactQueryDevtools } from "@tanstack/react-query-devtools/production";
3
9
  import { TanStackDevtools } from "@tanstack/react-devtools";
4
- import { formDevtoolsPlugin } from "@tanstack/react-form-devtools";
5
- import { pacerDevtoolsPlugin } from "@tanstack/react-pacer-devtools";
10
+ import { formDevtoolsPlugin } from "@tanstack/react-form-devtools/production";
11
+ import { createReactPanel, createReactPlugin } from "@tanstack/devtools-utils/react";
12
+ import { PacerDevtoolsCore } from "@tanstack/pacer-devtools/production";
6
13
  import { ThemeDevtoolsPanel } from "@multiplatform.one/theme";
7
14
  import { storage } from "@multiplatform.one/store";
8
15
  import { useEffect, useState } from "react";
9
16
  import type { TanstackConfig } from "./CreateApp";
17
+ import { devtoolsOpenHotkey, useDevtoolsKeyboardTrigger, useShakeToOpen } from "./devtoolsTrigger";
10
18
 
11
19
  const devtoolsSettingsKey = "tanstack_devtools_settings";
12
20
 
21
+ // @tanstack/react-pacer-devtools' /production entry is broken upstream
22
+ // (0.7.x): it re-exports its panel from ReactPacerDevtools.js, which pulls
23
+ // PacerDevtoolsCore from @tanstack/pacer-devtools' MAIN entry — the
24
+ // NODE_ENV-gated one — so its "production" plugin silently mounts the no-op
25
+ // core in a deployed bundle. Rebuild the plugin from the genuinely ungated
26
+ // /production core instead. devtoolsTrigger.spec.ts pins the resolved core
27
+ // as real (its unmount throws; the NoOp's is silent).
28
+ const [PacerDevtoolsPanel] = createReactPanel(PacerDevtoolsCore);
29
+ const [pacerDevtoolsPlugin] = createReactPlugin({
30
+ name: "TanStack Pacer",
31
+ Component: PacerDevtoolsPanel,
32
+ });
33
+
13
34
  /**
14
35
  * Sync the resolved color scheme into the TanStack Devtools settings
15
36
  * stored via the shared storage adapter. The devtools shell reads this on mount and
@@ -36,7 +57,7 @@ export interface TanstackDevtoolsProps {
36
57
  /**
37
58
  * Lazily-loaded devtools shell. All heavy devtools dependencies
38
59
  * (`@tanstack/react-devtools`, `@tanstack/react-query-devtools`,
39
- * `@tanstack/react-form-devtools`, `@tanstack/react-pacer-devtools`,
60
+ * `@tanstack/react-form-devtools`, `@tanstack/pacer-devtools`,
40
61
  * and `ThemeDevtoolsPanel`) live here so they are code-split away
41
62
  * from the production bundle.
42
63
  */
@@ -108,6 +129,14 @@ export default function TanstackDevtoolsWrapper({
108
129
 
109
130
  const frappePlugin = useFrappePlugin();
110
131
 
132
+ // Shake-to-open (devicemotion) — the phone-friendly counterpart to the
133
+ // keyboard shortcut. Ships whenever the devtools mount unless the app
134
+ // opts out with `tanstack: { shakeToOpen: false }`.
135
+ useShakeToOpen(tanstackConfig.shakeToOpen !== false);
136
+ // Cmd/Ctrl+Shift+` — capture-phase so apps cannot swallow it. TanStack
137
+ // still receives openHotkey (US-layout e.key sequence) as a fallback.
138
+ useDevtoolsKeyboardTrigger(true);
139
+
111
140
  const plugins = [
112
141
  {
113
142
  id: "react-query",
@@ -119,11 +148,29 @@ export default function TanstackDevtoolsWrapper({
119
148
  {
120
149
  id: "theme",
121
150
  name: "Theme",
151
+ // The panel opens focused on Theme, so a shake (or the hotkey) lands
152
+ // straight on the theme flipper — the whole point of the trigger is
153
+ // to check that everything is themable. `defaultOpen` seeds the tab
154
+ // only on first open, when no layout is persisted yet; once the user
155
+ // moves to another tab their choice is restored on later opens.
156
+ defaultOpen: true,
122
157
  render: (_el: HTMLElement, props: { theme: "dark" | "light" }) => (
123
158
  <ThemeDevtoolsPanel
124
159
  useUserScheme={tanstackConfig.useUserScheme}
125
160
  devtoolsTheme={props.theme}
126
161
  tamaguiConfig={tanstackConfig.tamaguiConfig}
162
+ // The accent channel. `ThemeDevtoolsPanel` has taken these three
163
+ // props all along and core passed none of them, so the panel's
164
+ // accent dropdown never rendered and its Randomize action skipped
165
+ // the colour — a control that is present in the component and
166
+ // unreachable through the only wrapper that mounts it. They are
167
+ // forwarded, not invented here: a theme colour is app state, so the
168
+ // app supplies the list, the current value and the setter, exactly
169
+ // as it already supplies `useUserScheme`. Undefined stays undefined,
170
+ // so an app that wires nothing sees the panel it sees today.
171
+ themeColors={tanstackConfig.themeColors}
172
+ currentThemeColor={tanstackConfig.currentThemeColor}
173
+ onThemeColorChange={tanstackConfig.onThemeColorChange}
127
174
  />
128
175
  ),
129
176
  },
@@ -136,7 +183,7 @@ export default function TanstackDevtoolsWrapper({
136
183
  config={{
137
184
  defaultOpen: false,
138
185
  triggerHidden: true,
139
- openHotkey: ["CtrlOrMeta", "`"],
186
+ openHotkey: [...devtoolsOpenHotkey],
140
187
  theme: resolvedScheme,
141
188
  }}
142
189
  plugins={plugins}