@ethisyscore/plugin-ui 1.61.0 → 1.63.0
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/dist/platform-react/index.cjs +48 -2
- package/dist/platform-react/index.cjs.map +1 -1
- package/dist/platform-react/index.d.cts +39 -2
- package/dist/platform-react/index.d.ts +39 -2
- package/dist/platform-react/index.js +47 -4
- package/dist/platform-react/index.js.map +1 -1
- package/package.json +1 -1
- package/styles/plugin-base.css +30 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import { ComponentType, ReactElement,
|
|
2
|
+
import { ComponentType, ReactElement, ReactNode, AnchorHTMLAttributes, MouseEvent } from 'react';
|
|
3
3
|
import * as _tanstack_react_query from '@tanstack/react-query';
|
|
4
4
|
import { QueryClient, UseQueryResult, UseQueryOptions, QueryKey } from '@tanstack/react-query';
|
|
5
5
|
import { PlatformReactPageProps } from '@ethisyscore/components-react';
|
|
@@ -177,6 +177,12 @@ declare function useAuthenticatedQueries<TQueryFnData = unknown, TError = Error>
|
|
|
177
177
|
* the host would load, so the styles travel inside the bundle (typically via a
|
|
178
178
|
* `*.css?inline` import) and are mounted at runtime. Scope the CSS to a plugin
|
|
179
179
|
* root class (never `:root`) so it cannot override the host theme.
|
|
180
|
+
*
|
|
181
|
+
* Tailwind's generated layers (`utilities`, and the `@property` fallbacks in
|
|
182
|
+
* `properties`) are emitted UNSCOPED and used to break that rule — a plugin's bare
|
|
183
|
+
* `.text-sm` silently restyled host chrome. The build now scopes them:
|
|
184
|
+
* `scopePluginCssPlugin` in `@ethisyscore/vite-plugin`, applied by both page-build
|
|
185
|
+
* paths. Hand-written plugin CSS still has to scope itself.
|
|
180
186
|
*/
|
|
181
187
|
declare function injectPluginStyles(id: string, css: string): void;
|
|
182
188
|
/** Component form of {@link injectPluginStyles}; renders nothing. */
|
|
@@ -185,6 +191,37 @@ declare function PluginStyleScope({ id, css }: {
|
|
|
185
191
|
css: string;
|
|
186
192
|
}): null;
|
|
187
193
|
|
|
194
|
+
/**
|
|
195
|
+
* Class on the portal container element rendered at the end of a plugin surface.
|
|
196
|
+
* `plugin-base.css` positions it; the class is exported so a plugin can target it
|
|
197
|
+
* (e.g. to raise the stacking order for one surface).
|
|
198
|
+
*/
|
|
199
|
+
declare const EHX_PLUGIN_PORTAL_CLASS = "ehx-plugin-portal-root";
|
|
200
|
+
/**
|
|
201
|
+
* Marker attribute on any element acting as a plugin portal container. Scoped
|
|
202
|
+
* plugin CSS keys off `.ehx-plugin-root` OR this attribute, so a plugin that
|
|
203
|
+
* supplies its OWN container for a specific overlay (passing `container` on the
|
|
204
|
+
* component, which beats the default set here) can mark it and keep utilities.
|
|
205
|
+
*/
|
|
206
|
+
declare const EHX_PLUGIN_PORTAL_ATTR = "data-ehx-plugin-portal";
|
|
207
|
+
/**
|
|
208
|
+
* Renders plugin content plus a portal container INSIDE the plugin's style root,
|
|
209
|
+
* and defaults MUI's portalling components to that container.
|
|
210
|
+
*
|
|
211
|
+
* Why: a plugin's compiled CSS is injected into the host document and is scoped
|
|
212
|
+
* to the plugin root, but MUI renders modals, menus, poppers and tooltips through
|
|
213
|
+
* a portal, landing wherever the host theme sends them — a sibling of the plugin
|
|
214
|
+
* root, not a descendant — so they fall outside every scoped rule. Containing
|
|
215
|
+
* them first is what lets plugin CSS be scoped at all.
|
|
216
|
+
*
|
|
217
|
+
* This is a nested `ThemeProvider` over the HOST theme (MUI is a host external,
|
|
218
|
+
* so `useTheme()` reads the host's provider through the same module instance).
|
|
219
|
+
* It adds the container defaults and changes nothing else.
|
|
220
|
+
*/
|
|
221
|
+
declare function PluginPortalScope({ children }: {
|
|
222
|
+
children: ReactNode;
|
|
223
|
+
}): ReactElement;
|
|
224
|
+
|
|
188
225
|
/**
|
|
189
226
|
* Minimal `react-router-dom` compatibility shim for lifted monolith code.
|
|
190
227
|
*
|
|
@@ -1170,4 +1207,4 @@ interface MenuConfigHostSidebarOptions {
|
|
|
1170
1207
|
*/
|
|
1171
1208
|
declare function menuConfigToHostSidebarInput(config: HeaderMenuItem[], opts: MenuConfigHostSidebarOptions): HostSidebarHookInput;
|
|
1172
1209
|
|
|
1173
|
-
export { type AuthenticatedQueryResult, BaseMcpService, DEFAULT_MAX_UPLOAD_BYTES, type DefinePlatformReactPluginOverlayOptions, type DefinePlatformReactPluginPageOptions, EHX_PLUGIN_ROOT_CLASS, HostSidebarHookInput, HostSidebarInput, type InsetLease, type ManagedLifecycle, type MenuConfigHostSidebarOptions, MissingViewFallback, OVERLAY_HOST_CONTRACT_VERSION, type OverlayHostApi, type OverlayHostCapabilities, OverlayHostContext, type PlatformReactOverlayProps, type PluginOverlayDefinerConfig, type PluginPageDefinerConfig, PluginStyleScope, type ReactRouterShimOptions, SurfaceBaseContext, type SurfaceBaseValue, TemplateContext, type TemplateManifest, type ToHostSidebarInputOptions, type ToolInvoker, type UseMcpUploadOptions, type UseMcpUploadResult, type UseMcpUploadTarget, type ViewComponent, buildSurfaceUrl, createPluginOverlayDefiner, createPluginPageDefiner, createReactRouterShim, createUseView, definePlatformReactPluginOverlay, definePlatformReactPluginPage, deriveHostEntityToken, injectPluginStyles, isComponent, menuConfigToHostSidebarInput, normaliseSlug, notViaMcp, resolveSurfaceBase, surfacePathFor, toHostSidebarInput, useAuthenticatedQueries, useAuthenticatedQuery, useManagedLifecycle, useMcpUpload, useOverlayHost, usePluginRealtime, useSurfaceUrl, useToolInvoker, useToolInvokerMap, useView };
|
|
1210
|
+
export { type AuthenticatedQueryResult, BaseMcpService, DEFAULT_MAX_UPLOAD_BYTES, type DefinePlatformReactPluginOverlayOptions, type DefinePlatformReactPluginPageOptions, EHX_PLUGIN_PORTAL_ATTR, EHX_PLUGIN_PORTAL_CLASS, EHX_PLUGIN_ROOT_CLASS, HostSidebarHookInput, HostSidebarInput, type InsetLease, type ManagedLifecycle, type MenuConfigHostSidebarOptions, MissingViewFallback, OVERLAY_HOST_CONTRACT_VERSION, type OverlayHostApi, type OverlayHostCapabilities, OverlayHostContext, type PlatformReactOverlayProps, type PluginOverlayDefinerConfig, type PluginPageDefinerConfig, PluginPortalScope, PluginStyleScope, type ReactRouterShimOptions, SurfaceBaseContext, type SurfaceBaseValue, TemplateContext, type TemplateManifest, type ToHostSidebarInputOptions, type ToolInvoker, type UseMcpUploadOptions, type UseMcpUploadResult, type UseMcpUploadTarget, type ViewComponent, buildSurfaceUrl, createPluginOverlayDefiner, createPluginPageDefiner, createReactRouterShim, createUseView, definePlatformReactPluginOverlay, definePlatformReactPluginPage, deriveHostEntityToken, injectPluginStyles, isComponent, menuConfigToHostSidebarInput, normaliseSlug, notViaMcp, resolveSurfaceBase, surfacePathFor, toHostSidebarInput, useAuthenticatedQueries, useAuthenticatedQuery, useManagedLifecycle, useMcpUpload, useOverlayHost, usePluginRealtime, useSurfaceUrl, useToolInvoker, useToolInvokerMap, useView };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import { ComponentType, ReactElement,
|
|
2
|
+
import { ComponentType, ReactElement, ReactNode, AnchorHTMLAttributes, MouseEvent } from 'react';
|
|
3
3
|
import * as _tanstack_react_query from '@tanstack/react-query';
|
|
4
4
|
import { QueryClient, UseQueryResult, UseQueryOptions, QueryKey } from '@tanstack/react-query';
|
|
5
5
|
import { PlatformReactPageProps } from '@ethisyscore/components-react';
|
|
@@ -177,6 +177,12 @@ declare function useAuthenticatedQueries<TQueryFnData = unknown, TError = Error>
|
|
|
177
177
|
* the host would load, so the styles travel inside the bundle (typically via a
|
|
178
178
|
* `*.css?inline` import) and are mounted at runtime. Scope the CSS to a plugin
|
|
179
179
|
* root class (never `:root`) so it cannot override the host theme.
|
|
180
|
+
*
|
|
181
|
+
* Tailwind's generated layers (`utilities`, and the `@property` fallbacks in
|
|
182
|
+
* `properties`) are emitted UNSCOPED and used to break that rule — a plugin's bare
|
|
183
|
+
* `.text-sm` silently restyled host chrome. The build now scopes them:
|
|
184
|
+
* `scopePluginCssPlugin` in `@ethisyscore/vite-plugin`, applied by both page-build
|
|
185
|
+
* paths. Hand-written plugin CSS still has to scope itself.
|
|
180
186
|
*/
|
|
181
187
|
declare function injectPluginStyles(id: string, css: string): void;
|
|
182
188
|
/** Component form of {@link injectPluginStyles}; renders nothing. */
|
|
@@ -185,6 +191,37 @@ declare function PluginStyleScope({ id, css }: {
|
|
|
185
191
|
css: string;
|
|
186
192
|
}): null;
|
|
187
193
|
|
|
194
|
+
/**
|
|
195
|
+
* Class on the portal container element rendered at the end of a plugin surface.
|
|
196
|
+
* `plugin-base.css` positions it; the class is exported so a plugin can target it
|
|
197
|
+
* (e.g. to raise the stacking order for one surface).
|
|
198
|
+
*/
|
|
199
|
+
declare const EHX_PLUGIN_PORTAL_CLASS = "ehx-plugin-portal-root";
|
|
200
|
+
/**
|
|
201
|
+
* Marker attribute on any element acting as a plugin portal container. Scoped
|
|
202
|
+
* plugin CSS keys off `.ehx-plugin-root` OR this attribute, so a plugin that
|
|
203
|
+
* supplies its OWN container for a specific overlay (passing `container` on the
|
|
204
|
+
* component, which beats the default set here) can mark it and keep utilities.
|
|
205
|
+
*/
|
|
206
|
+
declare const EHX_PLUGIN_PORTAL_ATTR = "data-ehx-plugin-portal";
|
|
207
|
+
/**
|
|
208
|
+
* Renders plugin content plus a portal container INSIDE the plugin's style root,
|
|
209
|
+
* and defaults MUI's portalling components to that container.
|
|
210
|
+
*
|
|
211
|
+
* Why: a plugin's compiled CSS is injected into the host document and is scoped
|
|
212
|
+
* to the plugin root, but MUI renders modals, menus, poppers and tooltips through
|
|
213
|
+
* a portal, landing wherever the host theme sends them — a sibling of the plugin
|
|
214
|
+
* root, not a descendant — so they fall outside every scoped rule. Containing
|
|
215
|
+
* them first is what lets plugin CSS be scoped at all.
|
|
216
|
+
*
|
|
217
|
+
* This is a nested `ThemeProvider` over the HOST theme (MUI is a host external,
|
|
218
|
+
* so `useTheme()` reads the host's provider through the same module instance).
|
|
219
|
+
* It adds the container defaults and changes nothing else.
|
|
220
|
+
*/
|
|
221
|
+
declare function PluginPortalScope({ children }: {
|
|
222
|
+
children: ReactNode;
|
|
223
|
+
}): ReactElement;
|
|
224
|
+
|
|
188
225
|
/**
|
|
189
226
|
* Minimal `react-router-dom` compatibility shim for lifted monolith code.
|
|
190
227
|
*
|
|
@@ -1170,4 +1207,4 @@ interface MenuConfigHostSidebarOptions {
|
|
|
1170
1207
|
*/
|
|
1171
1208
|
declare function menuConfigToHostSidebarInput(config: HeaderMenuItem[], opts: MenuConfigHostSidebarOptions): HostSidebarHookInput;
|
|
1172
1209
|
|
|
1173
|
-
export { type AuthenticatedQueryResult, BaseMcpService, DEFAULT_MAX_UPLOAD_BYTES, type DefinePlatformReactPluginOverlayOptions, type DefinePlatformReactPluginPageOptions, EHX_PLUGIN_ROOT_CLASS, HostSidebarHookInput, HostSidebarInput, type InsetLease, type ManagedLifecycle, type MenuConfigHostSidebarOptions, MissingViewFallback, OVERLAY_HOST_CONTRACT_VERSION, type OverlayHostApi, type OverlayHostCapabilities, OverlayHostContext, type PlatformReactOverlayProps, type PluginOverlayDefinerConfig, type PluginPageDefinerConfig, PluginStyleScope, type ReactRouterShimOptions, SurfaceBaseContext, type SurfaceBaseValue, TemplateContext, type TemplateManifest, type ToHostSidebarInputOptions, type ToolInvoker, type UseMcpUploadOptions, type UseMcpUploadResult, type UseMcpUploadTarget, type ViewComponent, buildSurfaceUrl, createPluginOverlayDefiner, createPluginPageDefiner, createReactRouterShim, createUseView, definePlatformReactPluginOverlay, definePlatformReactPluginPage, deriveHostEntityToken, injectPluginStyles, isComponent, menuConfigToHostSidebarInput, normaliseSlug, notViaMcp, resolveSurfaceBase, surfacePathFor, toHostSidebarInput, useAuthenticatedQueries, useAuthenticatedQuery, useManagedLifecycle, useMcpUpload, useOverlayHost, usePluginRealtime, useSurfaceUrl, useToolInvoker, useToolInvokerMap, useView };
|
|
1210
|
+
export { type AuthenticatedQueryResult, BaseMcpService, DEFAULT_MAX_UPLOAD_BYTES, type DefinePlatformReactPluginOverlayOptions, type DefinePlatformReactPluginPageOptions, EHX_PLUGIN_PORTAL_ATTR, EHX_PLUGIN_PORTAL_CLASS, EHX_PLUGIN_ROOT_CLASS, HostSidebarHookInput, HostSidebarInput, type InsetLease, type ManagedLifecycle, type MenuConfigHostSidebarOptions, MissingViewFallback, OVERLAY_HOST_CONTRACT_VERSION, type OverlayHostApi, type OverlayHostCapabilities, OverlayHostContext, type PlatformReactOverlayProps, type PluginOverlayDefinerConfig, type PluginPageDefinerConfig, PluginPortalScope, PluginStyleScope, type ReactRouterShimOptions, SurfaceBaseContext, type SurfaceBaseValue, TemplateContext, type TemplateManifest, type ToHostSidebarInputOptions, type ToolInvoker, type UseMcpUploadOptions, type UseMcpUploadResult, type UseMcpUploadTarget, type ViewComponent, buildSurfaceUrl, createPluginOverlayDefiner, createPluginPageDefiner, createReactRouterShim, createUseView, definePlatformReactPluginOverlay, definePlatformReactPluginPage, deriveHostEntityToken, injectPluginStyles, isComponent, menuConfigToHostSidebarInput, normaliseSlug, notViaMcp, resolveSurfaceBase, surfacePathFor, toHostSidebarInput, useAuthenticatedQueries, useAuthenticatedQuery, useManagedLifecycle, useMcpUpload, useOverlayHost, usePluginRealtime, useSurfaceUrl, useToolInvoker, useToolInvokerMap, useView };
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { createContext, useEffect, useContext,
|
|
1
|
+
import { createContext, useEffect, useContext, useState, useMemo, createElement, useRef, useCallback, useSyncExternalStore } from 'react';
|
|
2
2
|
import { QueryClient, useQuery, useQueries, QueryClientProvider } from '@tanstack/react-query';
|
|
3
3
|
import { definePlatformReactPage, emitNavigation } from '@ethisyscore/components-react';
|
|
4
4
|
import { useHostIdentity, useMcpTool, usePluginRealtimeSource, useExtensionRuntimeTransport } from '@ethisyscore/extension-runtime/plugin';
|
|
5
|
+
import { useTheme, ThemeProvider } from '@mui/material';
|
|
6
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
5
7
|
|
|
6
8
|
// src/platform-react/definePlatformReactPluginPage.tsx
|
|
7
9
|
var TemplateContext = createContext(null);
|
|
@@ -109,6 +111,42 @@ function isHostChromeCompatible(hostVersion) {
|
|
|
109
111
|
if (Number.isNaN(hostMajor) || Number.isNaN(sdkMajor)) return false;
|
|
110
112
|
return hostMajor === sdkMajor;
|
|
111
113
|
}
|
|
114
|
+
var EHX_PLUGIN_PORTAL_CLASS = "ehx-plugin-portal-root";
|
|
115
|
+
var EHX_PLUGIN_PORTAL_ATTR = "data-ehx-plugin-portal";
|
|
116
|
+
function withPortalContainer(theme, containerElement) {
|
|
117
|
+
const slots = theme.components ?? {};
|
|
118
|
+
const tooltip = slots.MuiTooltip;
|
|
119
|
+
const container = () => containerElement;
|
|
120
|
+
return {
|
|
121
|
+
...theme,
|
|
122
|
+
components: {
|
|
123
|
+
...slots,
|
|
124
|
+
MuiModal: { ...slots.MuiModal, defaultProps: { ...slots.MuiModal?.defaultProps, container } },
|
|
125
|
+
MuiPopper: { ...slots.MuiPopper, defaultProps: { ...slots.MuiPopper?.defaultProps, container } },
|
|
126
|
+
MuiPopover: { ...slots.MuiPopover, defaultProps: { ...slots.MuiPopover?.defaultProps, container } },
|
|
127
|
+
MuiMenu: { ...slots.MuiMenu, defaultProps: { ...slots.MuiMenu?.defaultProps, container } },
|
|
128
|
+
MuiTooltip: {
|
|
129
|
+
...tooltip,
|
|
130
|
+
defaultProps: {
|
|
131
|
+
...tooltip?.defaultProps,
|
|
132
|
+
PopperProps: { ...tooltip?.defaultProps?.PopperProps, container }
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
function PluginPortalScope({ children }) {
|
|
139
|
+
const [container, setContainer] = useState(null);
|
|
140
|
+
const hostTheme = useTheme();
|
|
141
|
+
const theme = useMemo(
|
|
142
|
+
() => container ? withPortalContainer(hostTheme, container) : hostTheme,
|
|
143
|
+
[hostTheme, container]
|
|
144
|
+
);
|
|
145
|
+
return /* @__PURE__ */ jsxs(ThemeProvider, { theme, children: [
|
|
146
|
+
children,
|
|
147
|
+
/* @__PURE__ */ jsx("div", { ref: setContainer, className: EHX_PLUGIN_PORTAL_CLASS, ...{ [EHX_PLUGIN_PORTAL_ATTR]: "" } })
|
|
148
|
+
] });
|
|
149
|
+
}
|
|
112
150
|
|
|
113
151
|
// src/platform-react/definePlatformReactPluginPage.tsx
|
|
114
152
|
function makeDefaultQueryClient() {
|
|
@@ -149,7 +187,10 @@ function definePlatformReactPluginPage(Page, options) {
|
|
|
149
187
|
createElement(
|
|
150
188
|
"div",
|
|
151
189
|
{ className: `${EHX_PLUGIN_ROOT_CLASS} ${rootClassName}` },
|
|
152
|
-
|
|
190
|
+
// PluginPortalScope sits INSIDE the style root, so the portal container
|
|
191
|
+
// it renders is a descendant of it and MUI overlays (dialogs, menus,
|
|
192
|
+
// poppers, tooltips) open inside the plugin's scoped CSS.
|
|
193
|
+
createElement(PluginPortalScope, null, body)
|
|
153
194
|
)
|
|
154
195
|
)
|
|
155
196
|
)
|
|
@@ -517,7 +558,9 @@ function definePlatformReactPluginOverlay(Overlay, options) {
|
|
|
517
558
|
createElement(
|
|
518
559
|
"div",
|
|
519
560
|
{ className: `${EHX_PLUGIN_ROOT_CLASS} ${rootClassName}` },
|
|
520
|
-
|
|
561
|
+
// Overlay surfaces open their own dialogs and menus, so they need the same
|
|
562
|
+
// portal containment as pages (see definePlatformReactPluginPage).
|
|
563
|
+
createElement(PluginPortalScope, null, createElement(Overlay, props))
|
|
521
564
|
)
|
|
522
565
|
)
|
|
523
566
|
);
|
|
@@ -820,6 +863,6 @@ function menuConfigToHostSidebarInput(config, opts) {
|
|
|
820
863
|
return { mode: "actions", actions };
|
|
821
864
|
}
|
|
822
865
|
|
|
823
|
-
export { BaseMcpService, DEFAULT_MAX_UPLOAD_BYTES, EHX_PLUGIN_ROOT_CLASS, HOST_CHROME_CONTRACT_VERSION, HostSidebarActionsContext, MissingViewFallback, OVERLAY_HOST_CONTRACT_VERSION, OverlayHostContext, PluginStyleScope, SIDEBAR_MODE, SurfaceBaseContext, TemplateContext, buildSurfaceUrl, createPluginOverlayDefiner, createPluginPageDefiner, createReactRouterShim, createUseView, definePlatformReactPluginOverlay, definePlatformReactPluginPage, deriveHostEntityToken, injectPluginStyles, isComponent, isHostChromeCompatible, menuConfigToHostSidebarInput, normaliseSlug, notViaMcp, reportHostChromeDiagnostic, resolveSurfaceBase, setHostChromeDiagnosticSink, surfacePathFor, toHostSidebarInput, useAuthenticatedQueries, useAuthenticatedQuery, useHostSidebarActions, useManagedLifecycle, useMcpUpload, useOverlayHost, usePluginRealtime, useSurfaceUrl, useToolInvoker, useToolInvokerMap, useView };
|
|
866
|
+
export { BaseMcpService, DEFAULT_MAX_UPLOAD_BYTES, EHX_PLUGIN_PORTAL_ATTR, EHX_PLUGIN_PORTAL_CLASS, EHX_PLUGIN_ROOT_CLASS, HOST_CHROME_CONTRACT_VERSION, HostSidebarActionsContext, MissingViewFallback, OVERLAY_HOST_CONTRACT_VERSION, OverlayHostContext, PluginPortalScope, PluginStyleScope, SIDEBAR_MODE, SurfaceBaseContext, TemplateContext, buildSurfaceUrl, createPluginOverlayDefiner, createPluginPageDefiner, createReactRouterShim, createUseView, definePlatformReactPluginOverlay, definePlatformReactPluginPage, deriveHostEntityToken, injectPluginStyles, isComponent, isHostChromeCompatible, menuConfigToHostSidebarInput, normaliseSlug, notViaMcp, reportHostChromeDiagnostic, resolveSurfaceBase, setHostChromeDiagnosticSink, surfacePathFor, toHostSidebarInput, useAuthenticatedQueries, useAuthenticatedQuery, useHostSidebarActions, useManagedLifecycle, useMcpUpload, useOverlayHost, usePluginRealtime, useSurfaceUrl, useToolInvoker, useToolInvokerMap, useView };
|
|
824
867
|
//# sourceMappingURL=index.js.map
|
|
825
868
|
//# sourceMappingURL=index.js.map
|