@ethisyscore/plugin-ui 1.59.0 → 1.62.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.
@@ -1,5 +1,5 @@
1
1
  import * as react from 'react';
2
- import { ComponentType, ReactElement, AnchorHTMLAttributes, ReactNode, MouseEvent } from 'react';
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, AnchorHTMLAttributes, ReactNode, MouseEvent } from 'react';
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, createElement, useMemo, useRef, useState, useCallback, useSyncExternalStore } from 'react';
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,41 @@ 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, container) {
117
+ const slots = theme.components ?? {};
118
+ const tooltip = slots.MuiTooltip;
119
+ return {
120
+ ...theme,
121
+ components: {
122
+ ...slots,
123
+ MuiModal: { ...slots.MuiModal, defaultProps: { ...slots.MuiModal?.defaultProps, container } },
124
+ MuiPopper: { ...slots.MuiPopper, defaultProps: { ...slots.MuiPopper?.defaultProps, container } },
125
+ MuiPopover: { ...slots.MuiPopover, defaultProps: { ...slots.MuiPopover?.defaultProps, container } },
126
+ MuiMenu: { ...slots.MuiMenu, defaultProps: { ...slots.MuiMenu?.defaultProps, container } },
127
+ MuiTooltip: {
128
+ ...tooltip,
129
+ defaultProps: {
130
+ ...tooltip?.defaultProps,
131
+ PopperProps: { ...tooltip?.defaultProps?.PopperProps, container }
132
+ }
133
+ }
134
+ }
135
+ };
136
+ }
137
+ function PluginPortalScope({ children }) {
138
+ const [container, setContainer] = useState(null);
139
+ const hostTheme = useTheme();
140
+ const theme = useMemo(
141
+ () => container ? withPortalContainer(hostTheme, container) : hostTheme,
142
+ [hostTheme, container]
143
+ );
144
+ return /* @__PURE__ */ jsxs(ThemeProvider, { theme, children: [
145
+ children,
146
+ /* @__PURE__ */ jsx("div", { ref: setContainer, className: EHX_PLUGIN_PORTAL_CLASS, ...{ [EHX_PLUGIN_PORTAL_ATTR]: "" } })
147
+ ] });
148
+ }
112
149
 
113
150
  // src/platform-react/definePlatformReactPluginPage.tsx
114
151
  function makeDefaultQueryClient() {
@@ -149,7 +186,10 @@ function definePlatformReactPluginPage(Page, options) {
149
186
  createElement(
150
187
  "div",
151
188
  { className: `${EHX_PLUGIN_ROOT_CLASS} ${rootClassName}` },
152
- body
189
+ // PluginPortalScope sits INSIDE the style root, so the portal container
190
+ // it renders is a descendant of it and MUI overlays (dialogs, menus,
191
+ // poppers, tooltips) open inside the plugin's scoped CSS.
192
+ createElement(PluginPortalScope, null, body)
153
193
  )
154
194
  )
155
195
  )
@@ -517,7 +557,9 @@ function definePlatformReactPluginOverlay(Overlay, options) {
517
557
  createElement(
518
558
  "div",
519
559
  { className: `${EHX_PLUGIN_ROOT_CLASS} ${rootClassName}` },
520
- createElement(Overlay, props)
560
+ // Overlay surfaces open their own dialogs and menus, so they need the same
561
+ // portal containment as pages (see definePlatformReactPluginPage).
562
+ createElement(PluginPortalScope, null, createElement(Overlay, props))
521
563
  )
522
564
  )
523
565
  );
@@ -820,6 +862,6 @@ function menuConfigToHostSidebarInput(config, opts) {
820
862
  return { mode: "actions", actions };
821
863
  }
822
864
 
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 };
865
+ 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
866
  //# sourceMappingURL=index.js.map
825
867
  //# sourceMappingURL=index.js.map