@deepseek-ai/dsh-client-ui-context-menu 0.0.0-stage → 0.2.2-alpha.3

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/lib/index.js ADDED
@@ -0,0 +1,6 @@
1
+ //#region lib/types/index.js
2
+ /** Host Loader entry; menus belong to the Client. */
3
+ /** Register the browser plugin without Host behavior. */
4
+ function apply() {}
5
+ //#endregion
6
+ export { apply };
@@ -0,0 +1,26 @@
1
+ import type { MenuEntry } from '@deepseek-ai/dsh-client-ui-primitives';
2
+ import type { InjectFace, PropsStore, PropsRenderSlots } from '@deepseek-ai/dsh-client-ui-slots';
3
+ import type { Shortcuts, ShortcutCatalogEntry } from '@deepseek-ai/dsh-client-shortcuts/client';
4
+ import type { createMenuStore } from './store.ts';
5
+ import type { MenuActionView } from './types.ts';
6
+ /**
7
+ * @param actions - plain presentation.
8
+ * @param catalog - effective user shortcuts.
9
+ * @param renderSlot - owner-authorized keyed icon renderer.
10
+ * @returns Existing Menu entries.
11
+ */
12
+ export declare function menuEntries(actions: readonly MenuActionView[], catalog: readonly ShortcutCatalogEntry[], renderSlot: PropsRenderSlots<'contextMenu.icon'>['renderSlot']): MenuEntry[];
13
+ /** Shared overlay callbacks. */
14
+ export interface MenuOverlayInjected {
15
+ hooks: {
16
+ catalog: Shortcuts['catalog'];
17
+ };
18
+ close: () => void;
19
+ returnFocus?: () => HTMLElement | null;
20
+ select: (id: string) => void;
21
+ }
22
+ type Props = PropsStore<ReturnType<typeof createMenuStore>> & PropsRenderSlots<'contextMenu.content' | 'contextMenu.icon'> & InjectFace<MenuOverlayInjected>;
23
+ /** @param props - registered state, target-specific legacy rows, and actions. @returns one menu and persistent feedback. */
24
+ export declare function MenuOverlay({ useStore, actions, renderSlot, close, select, returnFocus, useCatalog }: Props): import("react").JSX.Element;
25
+ export {};
26
+ //# sourceMappingURL=View.d.ts.map
@@ -0,0 +1,52 @@
1
+ import type { Context } from '@deepseek-ai/cordis';
2
+ import z from '@deepseek-ai/schemastery';
3
+ import type { ContextMenus, ContextMenuTarget, ContextMenuIcon, UseContextMenu } from './types.ts';
4
+ export type { ContextMenus, ContextMenuTarget, ContextMenuTargetMap, MenuPoint, MenuAction, MenuActionView, MenuContribution, MenuResolution } from './types.ts';
5
+ export type { ContextMenuBindings, ContextMenuTriggerProps, UseContextMenu } from './types.ts';
6
+ export type { ContextMenuIcon } from './types.ts';
7
+ export { createMenuStore } from './store.ts';
8
+ declare module '@deepseek-ai/cordis' {
9
+ interface Context {
10
+ contextMenus: ContextMenus;
11
+ }
12
+ }
13
+ declare module '@deepseek-ai/dsh-client-ui-slots' {
14
+ interface GlobalStandardProps {
15
+ /** Menu bindings for explicit objects, available in every Slot scope. */
16
+ useContextMenu: UseContextMenu;
17
+ }
18
+ interface SlotMap {
19
+ /** Business-owned glyph or image selected by the action's icon key. */
20
+ 'contextMenu.icon': {
21
+ kind: 'keyed';
22
+ scope: 'root';
23
+ inline: true;
24
+ owner: {
25
+ icon: ContextMenuIcon;
26
+ };
27
+ };
28
+ /** Optional React rows for existing extension positions; data contributions need no renderer. */
29
+ 'contextMenu.content': {
30
+ kind: 'keyed';
31
+ scope: 'root';
32
+ owner: {
33
+ target: ContextMenuTarget;
34
+ dismiss: () => void;
35
+ };
36
+ };
37
+ }
38
+ interface LocaleNamespaceMap {
39
+ contextMenu: 'failed';
40
+ }
41
+ }
42
+ /** Maximum time to prepare each contribution before omitting its pending actions. */
43
+ export interface Config {
44
+ resolutionTimeoutMs?: number;
45
+ }
46
+ /** Validated Client menu preparation budget. */
47
+ export declare const Config: z<Config>;
48
+ /** Required overlay and localization services. */
49
+ export declare const inject: string[];
50
+ /** @param ctx - plugin-owned Client context. @param config - validated preparation budget. */
51
+ export declare function apply(ctx: Context, config?: Config): void;
52
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,28 @@
1
+ /** Context-menu operation feedback, separate from plugin display metadata. */
2
+ export declare const dictionaries: {
3
+ zh: {
4
+ failed: string;
5
+ };
6
+ en: {
7
+ failed: string;
8
+ };
9
+ ja: {
10
+ failed: string;
11
+ };
12
+ es: {
13
+ failed: string;
14
+ };
15
+ fr: {
16
+ failed: string;
17
+ };
18
+ de: {
19
+ failed: string;
20
+ };
21
+ ru: {
22
+ failed: string;
23
+ };
24
+ pt: {
25
+ failed: string;
26
+ };
27
+ };
28
+ //# sourceMappingURL=locales.d.ts.map
@@ -0,0 +1,25 @@
1
+ import type { MenuContribution, MenuResolution, ContextMenuTarget, ContextMenuTargetMap } from './types.ts';
2
+ /** React-free registry; each occurrence captures the providers registered at opening. */
3
+ export declare class MenuRegistry {
4
+ private readonly failed;
5
+ private readonly timeoutMs?;
6
+ private readonly providers;
7
+ private readonly occurrences;
8
+ private disposed;
9
+ constructor(failed: (message?: string) => void, timeoutMs?: number | undefined);
10
+ /**
11
+ * Register actions for subsequent openings.
12
+ * @param input - provider definition.
13
+ * @returns removal of this contribution and its pending resolutions.
14
+ */
15
+ register<K extends keyof ContextMenuTargetMap>(input: MenuContribution<K>): () => void;
16
+ /**
17
+ * Resolve an independently owned occurrence.
18
+ * @param target - captured clicked identity.
19
+ * @returns presentation, selection, and disposal.
20
+ */
21
+ resolve(target: ContextMenuTarget): MenuResolution;
22
+ /** Cancel every occurrence and reject further registrations or resolutions. */
23
+ dispose(): void;
24
+ }
25
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1,35 @@
1
+ /** Single-popup viewing state and feedback retained outside trigger components. */
2
+ import { type EngineStoreHandle } from '@deepseek-ai/dsh-client-store';
3
+ import type { MenuActionView, MenuPoint, ContextMenuTarget } from './types.ts';
4
+ interface Notice {
5
+ id: number;
6
+ text: string;
7
+ success: boolean;
8
+ action?: {
9
+ label: string;
10
+ onClick: () => void;
11
+ };
12
+ }
13
+ interface MenuState {
14
+ occurrence: number;
15
+ closing: boolean;
16
+ replacing: boolean;
17
+ target: ContextMenuTarget | null;
18
+ point: MenuPoint;
19
+ items: readonly MenuActionView[];
20
+ notice: Notice | null;
21
+ }
22
+ type MenuActions = {
23
+ open(draft: MenuState, target: ContextMenuTarget, point: MenuPoint): void;
24
+ items(draft: MenuState, items: readonly MenuActionView[]): void;
25
+ exit(draft: MenuState, replacing: boolean): void;
26
+ close(draft: MenuState): void;
27
+ notify(draft: MenuState, notice: Notice | null): void;
28
+ };
29
+ /**
30
+ * Create the root popup store.
31
+ * @returns the presentation and its mutation actions.
32
+ */
33
+ export declare function createMenuStore(): EngineStoreHandle<MenuState, MenuActions>;
34
+ export {};
35
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1,9 @@
1
+ /** Stable equality for the JSON-compatible target vocabulary, independent of object insertion order. */
2
+ import type { ContextMenuTarget } from './types.ts';
3
+ /**
4
+ * Compare captured JSON targets independently of object key insertion order.
5
+ * @param target - captured immutable target.
6
+ * @returns canonical JSON identity.
7
+ */
8
+ export declare function menuTargetKey(target: ContextMenuTarget): string;
9
+ //# sourceMappingURL=target-key.d.ts.map
@@ -0,0 +1,11 @@
1
+ import type { ContextMenuTriggerProps, MenuPoint, ContextMenuTarget } from './types.ts';
2
+ /**
3
+ * Create stable bindings for the plugin's injected hook.
4
+ * @param open - Open against the supplied captured target and viewport position.
5
+ * @param active - Whether the plugin still owns its service.
6
+ * @returns Ordinary trigger-prop factory; no React subscription or context is created.
7
+ */
8
+ export declare function createContextMenuBindings<Target extends object = ContextMenuTarget>(open: (target: Target, point: MenuPoint) => void, active: () => boolean): {
9
+ getTriggerProps: (target: Target | (() => Target) | undefined, handlers?: ContextMenuTriggerProps) => ContextMenuTriggerProps;
10
+ };
11
+ //# sourceMappingURL=trigger.d.ts.map
@@ -0,0 +1,161 @@
1
+ /** Client menu contributions and explicit gesture targets. */
2
+ import type { ShortcutCommandId } from '@deepseek-ai/dsh-client-shortcuts/client';
3
+ import type { ObservableSnapshot } from '@deepseek-ai/dsh-client-store';
4
+ import type { SessionId } from '@deepseek-ai/dsh-session/types';
5
+ import type { PaneId, TabRecord } from '@deepseek-ai/dsh-client-ui-dockkit';
6
+ import type { HTMLAttributes } from 'react';
7
+ /** DOM handlers bound to an explicit object; existing handlers can prevent menu activation. */
8
+ export type ContextMenuTriggerProps = Pick<HTMLAttributes<HTMLElement>, 'onContextMenu' | 'onKeyDown' | 'tabIndex'>;
9
+ /** Functions supplied by the globally injected useContextMenu hook. */
10
+ export interface ContextMenuBindings {
11
+ /**
12
+ * Bind an object or deferred business target to one element. This is an ordinary function, safe in loops.
13
+ * @param target - Object captured when the gesture runs; undefined retains native behavior.
14
+ * @param handlers - Existing handlers run first and can cancel with preventDefault().
15
+ * @returns Combined pointer and keyboard handlers plus a keyboard focus stop.
16
+ */
17
+ getTriggerProps: (target: ContextMenuTarget | (() => ContextMenuTarget) | undefined, handlers?: ContextMenuTriggerProps) => ContextMenuTriggerProps;
18
+ }
19
+ /** Read menu gesture bindings owned by the current menu plugin lifetime. */
20
+ export type UseContextMenu = () => ContextMenuBindings;
21
+ /** External plugins extend this map with their own target families. */
22
+ export interface ContextMenuTargetMap {
23
+ session: {
24
+ readonly sessionId: SessionId;
25
+ readonly displayTitle: string;
26
+ };
27
+ file: {
28
+ readonly sessionId: SessionId;
29
+ readonly path: string;
30
+ readonly line?: number;
31
+ readonly paneId?: PaneId;
32
+ };
33
+ directory: {
34
+ readonly sessionId: SessionId;
35
+ readonly path: string;
36
+ };
37
+ url: {
38
+ readonly sessionId: SessionId;
39
+ readonly url: string;
40
+ };
41
+ image: {
42
+ readonly sessionId?: SessionId;
43
+ readonly url: string;
44
+ readonly name?: string;
45
+ readonly mediaType?: string;
46
+ readonly path?: string;
47
+ };
48
+ tab: {
49
+ readonly sessionId: SessionId;
50
+ readonly paneId: PaneId;
51
+ readonly tab: TabRecord;
52
+ };
53
+ }
54
+ /** Captured target; changing selection never changes an open menu's target. */
55
+ export type ContextMenuTarget = {
56
+ [K in keyof ContextMenuTargetMap]: {
57
+ readonly kind: K;
58
+ readonly value: ContextMenuTargetMap[K];
59
+ };
60
+ }[keyof ContextMenuTargetMap];
61
+ /** Pointer position in CSS pixels; keyboard gestures use the trigger's bottom edge. */
62
+ export interface MenuPoint {
63
+ readonly x: number;
64
+ readonly y: number;
65
+ }
66
+ /** Keyed icon renderer and optional image URL captured with the action. */
67
+ export interface ContextMenuIcon {
68
+ readonly key: string;
69
+ readonly src?: string;
70
+ }
71
+ /** Client presentation fields; callbacks stay in the registry. */
72
+ export interface MenuActionView {
73
+ readonly id: string;
74
+ readonly label: string;
75
+ /** Command identity for live shortcut display only; selection still invokes this action’s run callback. */
76
+ readonly commandId?: ShortcutCommandId;
77
+ readonly disabled?: boolean;
78
+ readonly icon?: ContextMenuIcon;
79
+ readonly danger?: boolean;
80
+ readonly separatorBefore?: boolean;
81
+ /** Render after legacy component contributions in the shared Web popup. */
82
+ readonly afterContent?: boolean;
83
+ readonly children?: readonly MenuActionView[];
84
+ }
85
+ /** A contribution can decline, return actions immediately, or resolve metadata asynchronously. */
86
+ export interface MenuAction extends Omit<MenuActionView, 'children'> {
87
+ readonly children?: readonly MenuAction[];
88
+ /** Localized operation and recovery guidance when execution rejects. */
89
+ readonly failureLabel?: string;
90
+ /** Execute against the captured target. Reject for a visible failure; cancellation resolves normally. */
91
+ readonly run?: () => void | Promise<void>;
92
+ }
93
+ /** A namespaced contribution, ordered within its target family. */
94
+ export interface MenuContribution<K extends keyof ContextMenuTargetMap> {
95
+ readonly id: string;
96
+ readonly target: K;
97
+ readonly order: number;
98
+ /**
99
+ * Reactive inputs that re-resolve actions for the same captured target.
100
+ * @param target - clicked object.
101
+ * @returns sources owned by the contributing feature; unsubscribed on dismissal or unload.
102
+ */
103
+ observe?(target: ContextMenuTargetMap[K]): readonly ObservableSnapshot<unknown>[];
104
+ /**
105
+ * @param target - clicked object.
106
+ * @param signal - aborted on dismissal, plugin unload, or a newer observed preparation.
107
+ * @returns available actions.
108
+ */
109
+ resolve(target: ContextMenuTargetMap[K], signal: AbortSignal): readonly MenuAction[] | Promise<readonly MenuAction[]>;
110
+ }
111
+ /** Independent menu occurrence used by custom renderers and embedded menus. */
112
+ export interface MenuResolution {
113
+ /** Read a new immutable presentation after each provider settles, updates, or is withdrawn. */
114
+ readonly source: ObservableSnapshot<readonly MenuActionView[]>;
115
+ /** Settles when all opening contributions have completed or been withdrawn. */
116
+ readonly ready: Promise<void>;
117
+ /**
118
+ * Select once; disposed or removed contributions cannot execute.
119
+ * @param id - resolved action id.
120
+ */
121
+ select(id: string): void;
122
+ /** Cancel metadata queries and discard callbacks. */
123
+ dispose(): void;
124
+ }
125
+ /** Client capability used equally by built-in and external plugins. */
126
+ export interface ContextMenus {
127
+ /** Captured target of the shared popup; null after dismissal. */
128
+ readonly active: ObservableSnapshot<ContextMenuTarget | null>;
129
+ /**
130
+ * Register for subsequent openings; unloading withdraws actions and aborts their queries. Duplicate ids within a target fail.
131
+ * @param contribution - target provider.
132
+ * @returns unregister.
133
+ */
134
+ register<K extends keyof ContextMenuTargetMap>(contribution: MenuContribution<K>): () => void;
135
+ /**
136
+ * Open the single shared popup.
137
+ * @param target - captured object.
138
+ * @param point - viewport position.
139
+ */
140
+ open(target: ContextMenuTarget, point: MenuPoint): void;
141
+ /**
142
+ * Resolve an embedded menu without opening the shared popup.
143
+ * @param target - captured object.
144
+ * @returns owned occurrence.
145
+ */
146
+ resolve(target: ContextMenuTarget): MenuResolution;
147
+ /** Close the shared popup and cancel its metadata queries. */
148
+ close(): void;
149
+ /**
150
+ * Show localized feedback outside the originating surface.
151
+ * @param text - localized message.
152
+ * @param success - successful action.
153
+ * @param action - optional text action retained by this notice; rejects with localized failure feedback.
154
+ */
155
+ notify(text: string, success?: boolean, action?: {
156
+ readonly label: string;
157
+ readonly run: () => void | Promise<void>;
158
+ readonly failureLabel: string;
159
+ }): void;
160
+ }
161
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1,4 @@
1
+ /** Host Loader entry; menus belong to the Client. */
2
+ /** Register the browser plugin without Host behavior. */
3
+ export declare function apply(): void;
4
+ //# sourceMappingURL=index.d.ts.map
package/locale/de.json ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "meta": {
3
+ "title": "Kontextmenüs"
4
+ }
5
+ }
package/locale/en.json ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "meta": {
3
+ "title": "Context menus"
4
+ }
5
+ }
package/locale/es.json ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "meta": {
3
+ "title": "Menús contextuales"
4
+ }
5
+ }
package/locale/fr.json ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "meta": {
3
+ "title": "Menus contextuels"
4
+ }
5
+ }
package/locale/ja.json ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "meta": {
3
+ "title": "コンテキストメニュー"
4
+ }
5
+ }
package/locale/pt.json ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "meta": {
3
+ "title": "Menus de contexto"
4
+ }
5
+ }
package/locale/ru.json ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "meta": {
3
+ "title": "Контекстные меню"
4
+ }
5
+ }
package/locale/zh.json ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "meta": {
3
+ "title": "右键菜单"
4
+ }
5
+ }
package/package.json CHANGED
@@ -1,6 +1,70 @@
1
1
  {
2
2
  "name": "@deepseek-ai/dsh-client-ui-context-menu",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "description": "Typed, plugin-extensible context menus with captured targets and shared Web presentation",
4
+ "version": "0.2.2-alpha.3",
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/deepseek-ai/deepseek-harness.git",
11
+ "directory": "packages/client/ui-context-menu"
12
+ },
13
+ "type": "module",
14
+ "main": "lib/index.js",
15
+ "types": "lib/types/index.d.ts",
16
+ "exports": {
17
+ ".": {
18
+ "types": "./lib/types/index.d.ts",
19
+ "default": "./lib/index.js"
20
+ },
21
+ "./client": {
22
+ "types": "./lib/types/client/index.d.ts",
23
+ "default": "./lib/client.js"
24
+ },
25
+ "./src/*": "./src/*",
26
+ "./package.json": "./package.json",
27
+ "./locale/*.json": "./locale/*.json"
28
+ },
29
+ "dsh": {
30
+ "client": {
31
+ "inject": [
32
+ "@deepseek-ai/dsh-client-locale",
33
+ "@deepseek-ai/dsh-client-ui-layout",
34
+ "@deepseek-ai/dsh-client-shortcuts"
35
+ ],
36
+ "platform": "web"
37
+ }
38
+ },
39
+ "license": "MIT",
40
+ "peerDependencies": {
41
+ "@deepseek-ai/cordis": "~4.0.6-alpha.2"
42
+ },
43
+ "devDependencies": {
44
+ "@deepseek-ai/schemastery": "~3.18.6-alpha.2",
45
+ "@deepseek-ai/cordis": "~4.0.6-alpha.2",
46
+ "@deepseek-ai/dsh-client-locale": "0.2.2-alpha.3",
47
+ "@deepseek-ai/dsh-client-store": "0.2.2-alpha.3",
48
+ "@deepseek-ai/dsh-client-ui-slots": "0.2.2-alpha.3",
49
+ "@deepseek-ai/dsh-client-ui-primitives": "0.2.2-alpha.3",
50
+ "@deepseek-ai/dsh-client-ui-renderer": "0.2.2-alpha.3",
51
+ "@deepseek-ai/dsh-client-ui-layout": "0.2.2-alpha.3",
52
+ "@deepseek-ai/dsh-brand": "0.2.2-alpha.3",
53
+ "react": "^18.2.0",
54
+ "react-dom": "^18.2.0",
55
+ "@deepseek-ai/dsh-client-test-runtime": "0.2.2-alpha.3",
56
+ "@deepseek-ai/dsh-session": "0.2.2-alpha.3",
57
+ "@deepseek-ai/dsh-client-ui-dockkit": "0.2.2-alpha.3",
58
+ "@deepseek-ai/dsh-client-shortcuts": "0.2.2-alpha.3"
59
+ },
60
+ "files": [
61
+ "locale/*.json",
62
+ "lib/index.js",
63
+ "lib/client.js",
64
+ "lib/types/**/*.d.ts"
65
+ ],
66
+ "scripts": {
67
+ "bundle": "tsdown",
68
+ "watch": "tsdown --watch"
69
+ }
6
70
  }