@ethisyscore/plugin-ui 1.38.0 → 1.40.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/index.cjs +139 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +133 -1
- package/dist/index.js.map +1 -1
- package/dist/platform-react/index.cjs +143 -3
- package/dist/platform-react/index.cjs.map +1 -1
- package/dist/platform-react/index.d.cts +5 -1
- package/dist/platform-react/index.d.ts +5 -1
- package/dist/platform-react/index.js +137 -4
- package/dist/platform-react/index.js.map +1 -1
- package/dist/useHostSidebarActions-DFZPen7T.d.cts +152 -0
- package/dist/useHostSidebarActions-DFZPen7T.d.ts +152 -0
- package/package.json +1 -1
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { Context } from 'react';
|
|
2
|
+
import { HostSidebarActionsApiShape } from '@ethisyscore/components-react';
|
|
3
|
+
|
|
4
|
+
/** Host-chrome / sidebar-actions contract version (semver). Host MAJOR must equal the SDK
|
|
5
|
+
* MAJOR before any publish/subscribe; otherwise the plugin hook fails closed (WI 5188 batch 2). */
|
|
6
|
+
declare const HOST_CHROME_CONTRACT_VERSION = "2.0.0";
|
|
7
|
+
type HostSidebarActionSlot = "primary" | "overflow" | "sidebar-only";
|
|
8
|
+
type HostSidebarActionVariant = "default" | "danger";
|
|
9
|
+
/** Fields common to every action. */
|
|
10
|
+
interface HostSidebarActionBase {
|
|
11
|
+
id: string;
|
|
12
|
+
label: string;
|
|
13
|
+
icon?: string;
|
|
14
|
+
slot?: HostSidebarActionSlot;
|
|
15
|
+
variant?: HostSidebarActionVariant;
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
active?: boolean;
|
|
18
|
+
/** Optional host-side double-gate: the mask is resolved against the surface extension groupCode. */
|
|
19
|
+
requiredPermission?: number;
|
|
20
|
+
}
|
|
21
|
+
/** Strictly serializable action the plugin publishes to the host sidebar — NO functions cross
|
|
22
|
+
* the boundary. Discriminated union so `href` is REQUIRED at the type level for a navigate
|
|
23
|
+
* action and FORBIDDEN for a dispatch action (spec-gate MEDIUM R1-M1 — a navigate with a
|
|
24
|
+
* missing href fails typecheck at authoring time rather than being silently dropped by the host).
|
|
25
|
+
* `kind:"dispatch"` is clicked back to the plugin by `id` via the action-emit subscription. */
|
|
26
|
+
type HostSidebarActionDescriptor = (HostSidebarActionBase & {
|
|
27
|
+
kind: "dispatch";
|
|
28
|
+
}) | (HostSidebarActionBase & {
|
|
29
|
+
kind: "navigate";
|
|
30
|
+
href: string;
|
|
31
|
+
});
|
|
32
|
+
/** A navigation leaf the plugin drives into the host detail sidebar. `href` is extension-relative;
|
|
33
|
+
* the host canonicalises + confines it to `/extensions/<slug>/…` (host-owned, never trusted). */
|
|
34
|
+
interface HostSidebarNavItem {
|
|
35
|
+
id: string;
|
|
36
|
+
label: string;
|
|
37
|
+
icon?: string;
|
|
38
|
+
href: string;
|
|
39
|
+
}
|
|
40
|
+
/** The single publish payload. `none` = contribute nothing (do NOT clobber the static manifest
|
|
41
|
+
* actions); `actions` = batch-2 Quick Actions for a detail entity; `detail` = full detail-nav
|
|
42
|
+
* REPLACEMENT (title + nav items + back-arrow + Quick Actions). `identityEpoch` is host-stamped
|
|
43
|
+
* (plan D-1), so it is not part of this plugin-published shape. */
|
|
44
|
+
type HostSidebarContribution = {
|
|
45
|
+
mode: "none";
|
|
46
|
+
} | {
|
|
47
|
+
mode: "actions";
|
|
48
|
+
entityToken: string;
|
|
49
|
+
actions: HostSidebarActionDescriptor[];
|
|
50
|
+
} | {
|
|
51
|
+
mode: "detail";
|
|
52
|
+
entityToken: string;
|
|
53
|
+
title: string;
|
|
54
|
+
navSectionLabel: string;
|
|
55
|
+
navItems: HostSidebarNavItem[];
|
|
56
|
+
backHref: string;
|
|
57
|
+
backLabel: string;
|
|
58
|
+
actions: HostSidebarActionDescriptor[];
|
|
59
|
+
};
|
|
60
|
+
interface HostSidebarActionsCapabilities {
|
|
61
|
+
readonly contractVersion: string;
|
|
62
|
+
}
|
|
63
|
+
/** Host-provided API, passed to a PlatformReact page as the `hostSidebar` prop and read via
|
|
64
|
+
* the plugin-bundled context. Additive-only. */
|
|
65
|
+
interface HostSidebarActionsApi {
|
|
66
|
+
/** Replace the surface's sidebar contribution. The host rejects a publish whose entityToken ≠
|
|
67
|
+
* its current location-derived token, rejects duplicate action ids, and — for mode:"detail" —
|
|
68
|
+
* rejects/atomically-drops an invalid or href-unsafe context (falls back to main nav). */
|
|
69
|
+
publish(contribution: HostSidebarContribution): void;
|
|
70
|
+
/** Revert to the static-manifest fallback (publication state = unpublished). */
|
|
71
|
+
clear(): void;
|
|
72
|
+
/** Subscribe to click dispatch for `kind:"dispatch"` actions. The host emits the clicked
|
|
73
|
+
* action id. Returns an unsubscribe. The plugin bridge subscribes exactly once. */
|
|
74
|
+
subscribe(onAction: (actionId: string) => void): () => void;
|
|
75
|
+
readonly capabilities: HostSidebarActionsCapabilities;
|
|
76
|
+
}
|
|
77
|
+
/** Props the host injects into a page for the sidebar-actions seam (merged into PlatformReactPageProps).
|
|
78
|
+
* Typed against the dependency-neutral `HostSidebarActionsApiShape` — the SAME type
|
|
79
|
+
* `PlatformReactPageProps.hostSidebar` uses in `@ethisyscore/components-react` — so this
|
|
80
|
+
* convenience alias never diverges from the canonical page-props declaration. The concrete
|
|
81
|
+
* `HostSidebarActionsApi` is structurally assignable to the shape; the page bridge narrows to
|
|
82
|
+
* it internally. */
|
|
83
|
+
interface HostSidebarActionsPageProps {
|
|
84
|
+
hostSidebar?: HostSidebarActionsApiShape;
|
|
85
|
+
}
|
|
86
|
+
declare const HostSidebarActionsContext: Context<HostSidebarActionsApi | null>;
|
|
87
|
+
interface HostChromeDiagnostic {
|
|
88
|
+
event: string;
|
|
89
|
+
pageId?: string;
|
|
90
|
+
detail?: unknown;
|
|
91
|
+
}
|
|
92
|
+
type DiagnosticSinkFn = (d: HostChromeDiagnostic) => void;
|
|
93
|
+
declare function setHostChromeDiagnosticSink(sink: DiagnosticSinkFn): void;
|
|
94
|
+
declare function reportHostChromeDiagnostic(d: HostChromeDiagnostic): void;
|
|
95
|
+
/** Major-equality compatibility check; fail-closed on absent/unparseable input. */
|
|
96
|
+
declare function isHostChromeCompatible(hostVersion: string | undefined): boolean;
|
|
97
|
+
|
|
98
|
+
/** Authoring shape: a descriptor plus — ONLY for `kind:"dispatch"` — an inline handler.
|
|
99
|
+
* A distributive union (not a blanket intersection over the whole descriptor union): `onSelect`
|
|
100
|
+
* is permitted only on a dispatch action. A navigate action carries no handler (the host performs
|
|
101
|
+
* the navigation from `href`), so supplying `onSelect` on a navigate action is a typecheck error
|
|
102
|
+
* rather than a silently-ignored footgun. The hook strips `onSelect` before publishing (only
|
|
103
|
+
* serializable descriptors cross to the host). */
|
|
104
|
+
type HostSidebarAction = (Extract<HostSidebarActionDescriptor, {
|
|
105
|
+
kind: "dispatch";
|
|
106
|
+
}> & {
|
|
107
|
+
onSelect?: () => void;
|
|
108
|
+
}) | Extract<HostSidebarActionDescriptor, {
|
|
109
|
+
kind: "navigate";
|
|
110
|
+
}>;
|
|
111
|
+
/** Single source for the discriminant values used across the mode checks, `toContribution`, and
|
|
112
|
+
* the content key — so the "none"/"actions"/"detail" strings live in one place. The union type
|
|
113
|
+
* below intentionally keeps its literal members (they ARE the discriminant + drive IntelliSense);
|
|
114
|
+
* `SIDEBAR_MODE.*` is `as const`, so it is type-identical to those literals. */
|
|
115
|
+
declare const SIDEBAR_MODE: {
|
|
116
|
+
readonly none: "none";
|
|
117
|
+
readonly actions: "actions";
|
|
118
|
+
readonly detail: "detail";
|
|
119
|
+
};
|
|
120
|
+
/** Discriminated input to `useHostSidebarActions`. `mode:"none"` suppresses all plugin-side
|
|
121
|
+
* contributions without clobbering the static manifest actions. `mode:"actions"` is the
|
|
122
|
+
* batch-2 Quick Actions shape. `mode:"detail"` is the full detail-nav replacement with title,
|
|
123
|
+
* navigation items, back-arrow, and Quick Actions. */
|
|
124
|
+
type HostSidebarInput = {
|
|
125
|
+
mode: "none";
|
|
126
|
+
} | {
|
|
127
|
+
mode: "actions";
|
|
128
|
+
entityToken: string;
|
|
129
|
+
actions: HostSidebarAction[];
|
|
130
|
+
} | {
|
|
131
|
+
mode: "detail";
|
|
132
|
+
entityToken: string;
|
|
133
|
+
title: string;
|
|
134
|
+
navSectionLabel: string;
|
|
135
|
+
navItems: HostSidebarNavItem[];
|
|
136
|
+
backHref: string;
|
|
137
|
+
backLabel: string;
|
|
138
|
+
actions: HostSidebarAction[];
|
|
139
|
+
};
|
|
140
|
+
/**
|
|
141
|
+
* Publish contextual sidebar contributions from a PlatformReact page to the host sidebar, and
|
|
142
|
+
* receive click dispatch by id. Accepts a discriminated `HostSidebarInput`:
|
|
143
|
+
* - `mode:"none"` — suppress all plugin contributions without clobbering the static manifest.
|
|
144
|
+
* - `mode:"actions"` — batch-2 Quick Actions for a detail entity (entity token + action list).
|
|
145
|
+
* - `mode:"detail"` — full detail-nav replacement (title, nav items, back-arrow, Quick Actions).
|
|
146
|
+
*
|
|
147
|
+
* Serializable descriptors only cross to the host; the inline `onSelect` handlers stay in a
|
|
148
|
+
* ref-map here and are always the latest closure. Fails closed (no publish/subscribe, no throw)
|
|
149
|
+
* when the host predates or is incompatible with the seam. */
|
|
150
|
+
declare function useHostSidebarActions(input: HostSidebarInput): void;
|
|
151
|
+
|
|
152
|
+
export { HOST_CHROME_CONTRACT_VERSION as H, SIDEBAR_MODE as S, type HostChromeDiagnostic as a, type HostSidebarAction as b, type HostSidebarActionDescriptor as c, type HostSidebarActionSlot as d, type HostSidebarActionVariant as e, type HostSidebarActionsApi as f, type HostSidebarActionsCapabilities as g, HostSidebarActionsContext as h, type HostSidebarActionsPageProps as i, type HostSidebarContribution as j, type HostSidebarInput as k, type HostSidebarNavItem as l, isHostChromeCompatible as m, reportHostChromeDiagnostic as r, setHostChromeDiagnosticSink as s, useHostSidebarActions as u };
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { Context } from 'react';
|
|
2
|
+
import { HostSidebarActionsApiShape } from '@ethisyscore/components-react';
|
|
3
|
+
|
|
4
|
+
/** Host-chrome / sidebar-actions contract version (semver). Host MAJOR must equal the SDK
|
|
5
|
+
* MAJOR before any publish/subscribe; otherwise the plugin hook fails closed (WI 5188 batch 2). */
|
|
6
|
+
declare const HOST_CHROME_CONTRACT_VERSION = "2.0.0";
|
|
7
|
+
type HostSidebarActionSlot = "primary" | "overflow" | "sidebar-only";
|
|
8
|
+
type HostSidebarActionVariant = "default" | "danger";
|
|
9
|
+
/** Fields common to every action. */
|
|
10
|
+
interface HostSidebarActionBase {
|
|
11
|
+
id: string;
|
|
12
|
+
label: string;
|
|
13
|
+
icon?: string;
|
|
14
|
+
slot?: HostSidebarActionSlot;
|
|
15
|
+
variant?: HostSidebarActionVariant;
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
active?: boolean;
|
|
18
|
+
/** Optional host-side double-gate: the mask is resolved against the surface extension groupCode. */
|
|
19
|
+
requiredPermission?: number;
|
|
20
|
+
}
|
|
21
|
+
/** Strictly serializable action the plugin publishes to the host sidebar — NO functions cross
|
|
22
|
+
* the boundary. Discriminated union so `href` is REQUIRED at the type level for a navigate
|
|
23
|
+
* action and FORBIDDEN for a dispatch action (spec-gate MEDIUM R1-M1 — a navigate with a
|
|
24
|
+
* missing href fails typecheck at authoring time rather than being silently dropped by the host).
|
|
25
|
+
* `kind:"dispatch"` is clicked back to the plugin by `id` via the action-emit subscription. */
|
|
26
|
+
type HostSidebarActionDescriptor = (HostSidebarActionBase & {
|
|
27
|
+
kind: "dispatch";
|
|
28
|
+
}) | (HostSidebarActionBase & {
|
|
29
|
+
kind: "navigate";
|
|
30
|
+
href: string;
|
|
31
|
+
});
|
|
32
|
+
/** A navigation leaf the plugin drives into the host detail sidebar. `href` is extension-relative;
|
|
33
|
+
* the host canonicalises + confines it to `/extensions/<slug>/…` (host-owned, never trusted). */
|
|
34
|
+
interface HostSidebarNavItem {
|
|
35
|
+
id: string;
|
|
36
|
+
label: string;
|
|
37
|
+
icon?: string;
|
|
38
|
+
href: string;
|
|
39
|
+
}
|
|
40
|
+
/** The single publish payload. `none` = contribute nothing (do NOT clobber the static manifest
|
|
41
|
+
* actions); `actions` = batch-2 Quick Actions for a detail entity; `detail` = full detail-nav
|
|
42
|
+
* REPLACEMENT (title + nav items + back-arrow + Quick Actions). `identityEpoch` is host-stamped
|
|
43
|
+
* (plan D-1), so it is not part of this plugin-published shape. */
|
|
44
|
+
type HostSidebarContribution = {
|
|
45
|
+
mode: "none";
|
|
46
|
+
} | {
|
|
47
|
+
mode: "actions";
|
|
48
|
+
entityToken: string;
|
|
49
|
+
actions: HostSidebarActionDescriptor[];
|
|
50
|
+
} | {
|
|
51
|
+
mode: "detail";
|
|
52
|
+
entityToken: string;
|
|
53
|
+
title: string;
|
|
54
|
+
navSectionLabel: string;
|
|
55
|
+
navItems: HostSidebarNavItem[];
|
|
56
|
+
backHref: string;
|
|
57
|
+
backLabel: string;
|
|
58
|
+
actions: HostSidebarActionDescriptor[];
|
|
59
|
+
};
|
|
60
|
+
interface HostSidebarActionsCapabilities {
|
|
61
|
+
readonly contractVersion: string;
|
|
62
|
+
}
|
|
63
|
+
/** Host-provided API, passed to a PlatformReact page as the `hostSidebar` prop and read via
|
|
64
|
+
* the plugin-bundled context. Additive-only. */
|
|
65
|
+
interface HostSidebarActionsApi {
|
|
66
|
+
/** Replace the surface's sidebar contribution. The host rejects a publish whose entityToken ≠
|
|
67
|
+
* its current location-derived token, rejects duplicate action ids, and — for mode:"detail" —
|
|
68
|
+
* rejects/atomically-drops an invalid or href-unsafe context (falls back to main nav). */
|
|
69
|
+
publish(contribution: HostSidebarContribution): void;
|
|
70
|
+
/** Revert to the static-manifest fallback (publication state = unpublished). */
|
|
71
|
+
clear(): void;
|
|
72
|
+
/** Subscribe to click dispatch for `kind:"dispatch"` actions. The host emits the clicked
|
|
73
|
+
* action id. Returns an unsubscribe. The plugin bridge subscribes exactly once. */
|
|
74
|
+
subscribe(onAction: (actionId: string) => void): () => void;
|
|
75
|
+
readonly capabilities: HostSidebarActionsCapabilities;
|
|
76
|
+
}
|
|
77
|
+
/** Props the host injects into a page for the sidebar-actions seam (merged into PlatformReactPageProps).
|
|
78
|
+
* Typed against the dependency-neutral `HostSidebarActionsApiShape` — the SAME type
|
|
79
|
+
* `PlatformReactPageProps.hostSidebar` uses in `@ethisyscore/components-react` — so this
|
|
80
|
+
* convenience alias never diverges from the canonical page-props declaration. The concrete
|
|
81
|
+
* `HostSidebarActionsApi` is structurally assignable to the shape; the page bridge narrows to
|
|
82
|
+
* it internally. */
|
|
83
|
+
interface HostSidebarActionsPageProps {
|
|
84
|
+
hostSidebar?: HostSidebarActionsApiShape;
|
|
85
|
+
}
|
|
86
|
+
declare const HostSidebarActionsContext: Context<HostSidebarActionsApi | null>;
|
|
87
|
+
interface HostChromeDiagnostic {
|
|
88
|
+
event: string;
|
|
89
|
+
pageId?: string;
|
|
90
|
+
detail?: unknown;
|
|
91
|
+
}
|
|
92
|
+
type DiagnosticSinkFn = (d: HostChromeDiagnostic) => void;
|
|
93
|
+
declare function setHostChromeDiagnosticSink(sink: DiagnosticSinkFn): void;
|
|
94
|
+
declare function reportHostChromeDiagnostic(d: HostChromeDiagnostic): void;
|
|
95
|
+
/** Major-equality compatibility check; fail-closed on absent/unparseable input. */
|
|
96
|
+
declare function isHostChromeCompatible(hostVersion: string | undefined): boolean;
|
|
97
|
+
|
|
98
|
+
/** Authoring shape: a descriptor plus — ONLY for `kind:"dispatch"` — an inline handler.
|
|
99
|
+
* A distributive union (not a blanket intersection over the whole descriptor union): `onSelect`
|
|
100
|
+
* is permitted only on a dispatch action. A navigate action carries no handler (the host performs
|
|
101
|
+
* the navigation from `href`), so supplying `onSelect` on a navigate action is a typecheck error
|
|
102
|
+
* rather than a silently-ignored footgun. The hook strips `onSelect` before publishing (only
|
|
103
|
+
* serializable descriptors cross to the host). */
|
|
104
|
+
type HostSidebarAction = (Extract<HostSidebarActionDescriptor, {
|
|
105
|
+
kind: "dispatch";
|
|
106
|
+
}> & {
|
|
107
|
+
onSelect?: () => void;
|
|
108
|
+
}) | Extract<HostSidebarActionDescriptor, {
|
|
109
|
+
kind: "navigate";
|
|
110
|
+
}>;
|
|
111
|
+
/** Single source for the discriminant values used across the mode checks, `toContribution`, and
|
|
112
|
+
* the content key — so the "none"/"actions"/"detail" strings live in one place. The union type
|
|
113
|
+
* below intentionally keeps its literal members (they ARE the discriminant + drive IntelliSense);
|
|
114
|
+
* `SIDEBAR_MODE.*` is `as const`, so it is type-identical to those literals. */
|
|
115
|
+
declare const SIDEBAR_MODE: {
|
|
116
|
+
readonly none: "none";
|
|
117
|
+
readonly actions: "actions";
|
|
118
|
+
readonly detail: "detail";
|
|
119
|
+
};
|
|
120
|
+
/** Discriminated input to `useHostSidebarActions`. `mode:"none"` suppresses all plugin-side
|
|
121
|
+
* contributions without clobbering the static manifest actions. `mode:"actions"` is the
|
|
122
|
+
* batch-2 Quick Actions shape. `mode:"detail"` is the full detail-nav replacement with title,
|
|
123
|
+
* navigation items, back-arrow, and Quick Actions. */
|
|
124
|
+
type HostSidebarInput = {
|
|
125
|
+
mode: "none";
|
|
126
|
+
} | {
|
|
127
|
+
mode: "actions";
|
|
128
|
+
entityToken: string;
|
|
129
|
+
actions: HostSidebarAction[];
|
|
130
|
+
} | {
|
|
131
|
+
mode: "detail";
|
|
132
|
+
entityToken: string;
|
|
133
|
+
title: string;
|
|
134
|
+
navSectionLabel: string;
|
|
135
|
+
navItems: HostSidebarNavItem[];
|
|
136
|
+
backHref: string;
|
|
137
|
+
backLabel: string;
|
|
138
|
+
actions: HostSidebarAction[];
|
|
139
|
+
};
|
|
140
|
+
/**
|
|
141
|
+
* Publish contextual sidebar contributions from a PlatformReact page to the host sidebar, and
|
|
142
|
+
* receive click dispatch by id. Accepts a discriminated `HostSidebarInput`:
|
|
143
|
+
* - `mode:"none"` — suppress all plugin contributions without clobbering the static manifest.
|
|
144
|
+
* - `mode:"actions"` — batch-2 Quick Actions for a detail entity (entity token + action list).
|
|
145
|
+
* - `mode:"detail"` — full detail-nav replacement (title, nav items, back-arrow, Quick Actions).
|
|
146
|
+
*
|
|
147
|
+
* Serializable descriptors only cross to the host; the inline `onSelect` handlers stay in a
|
|
148
|
+
* ref-map here and are always the latest closure. Fails closed (no publish/subscribe, no throw)
|
|
149
|
+
* when the host predates or is incompatible with the seam. */
|
|
150
|
+
declare function useHostSidebarActions(input: HostSidebarInput): void;
|
|
151
|
+
|
|
152
|
+
export { HOST_CHROME_CONTRACT_VERSION as H, SIDEBAR_MODE as S, type HostChromeDiagnostic as a, type HostSidebarAction as b, type HostSidebarActionDescriptor as c, type HostSidebarActionSlot as d, type HostSidebarActionVariant as e, type HostSidebarActionsApi as f, type HostSidebarActionsCapabilities as g, HostSidebarActionsContext as h, type HostSidebarActionsPageProps as i, type HostSidebarContribution as j, type HostSidebarInput as k, type HostSidebarNavItem as l, isHostChromeCompatible as m, reportHostChromeDiagnostic as r, setHostChromeDiagnosticSink as s, useHostSidebarActions as u };
|
package/package.json
CHANGED