@embedpdf/plugin-commands 2.0.0-next.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/LICENSE +21 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +316 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/actions.d.ts +25 -0
- package/dist/lib/commands-plugin.d.ts +31 -0
- package/dist/lib/index.d.ts +8 -0
- package/dist/lib/manifest.d.ts +4 -0
- package/dist/lib/reducer.d.ts +5 -0
- package/dist/lib/types.d.ts +98 -0
- package/dist/preact/adapter.d.ts +5 -0
- package/dist/preact/core.d.ts +1 -0
- package/dist/preact/index.cjs +2 -0
- package/dist/preact/index.cjs.map +1 -0
- package/dist/preact/index.d.ts +1 -0
- package/dist/preact/index.js +89 -0
- package/dist/preact/index.js.map +1 -0
- package/dist/react/adapter.d.ts +2 -0
- package/dist/react/core.d.ts +1 -0
- package/dist/react/index.cjs +2 -0
- package/dist/react/index.cjs.map +1 -0
- package/dist/react/index.d.ts +1 -0
- package/dist/react/index.js +88 -0
- package/dist/react/index.js.map +1 -0
- package/dist/shared/components/index.d.ts +1 -0
- package/dist/shared/components/keyboard-shortcuts.d.ts +6 -0
- package/dist/shared/hooks/index.d.ts +1 -0
- package/dist/shared/hooks/use-commands.d.ts +23 -0
- package/dist/shared/index.d.ts +4 -0
- package/dist/shared/utils/index.d.ts +1 -0
- package/dist/shared/utils/keyboard-handler.d.ts +10 -0
- package/dist/shared-preact/components/index.d.ts +1 -0
- package/dist/shared-preact/components/keyboard-shortcuts.d.ts +6 -0
- package/dist/shared-preact/hooks/index.d.ts +1 -0
- package/dist/shared-preact/hooks/use-commands.d.ts +23 -0
- package/dist/shared-preact/index.d.ts +4 -0
- package/dist/shared-preact/utils/index.d.ts +1 -0
- package/dist/shared-preact/utils/keyboard-handler.d.ts +10 -0
- package/dist/shared-react/components/index.d.ts +1 -0
- package/dist/shared-react/components/keyboard-shortcuts.d.ts +6 -0
- package/dist/shared-react/hooks/index.d.ts +1 -0
- package/dist/shared-react/hooks/use-commands.d.ts +23 -0
- package/dist/shared-react/index.d.ts +4 -0
- package/dist/shared-react/utils/index.d.ts +1 -0
- package/dist/shared-react/utils/keyboard-handler.d.ts +10 -0
- package/dist/shared-vue/utils/index.d.ts +1 -0
- package/dist/shared-vue/utils/keyboard-handler.d.ts +10 -0
- package/dist/svelte/components/KeyboardShortcuts.svelte.d.ts +18 -0
- package/dist/svelte/components/index.d.ts +1 -0
- package/dist/svelte/hooks/index.d.ts +1 -0
- package/dist/svelte/hooks/use-commands.svelte.d.ts +21 -0
- package/dist/svelte/index.cjs +2 -0
- package/dist/svelte/index.cjs.map +1 -0
- package/dist/svelte/index.d.ts +4 -0
- package/dist/svelte/index.js +90 -0
- package/dist/svelte/index.js.map +1 -0
- package/dist/vue/components/index.d.ts +1 -0
- package/dist/vue/components/keyboard-shortcuts.vue.d.ts +3 -0
- package/dist/vue/hooks/index.d.ts +1 -0
- package/dist/vue/hooks/use-commands.d.ts +46 -0
- package/dist/vue/index.cjs +2 -0
- package/dist/vue/index.cjs.map +1 -0
- package/dist/vue/index.d.ts +4 -0
- package/dist/vue/index.js +90 -0
- package/dist/vue/index.js.map +1 -0
- package/package.json +82 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { BasePluginConfig, CoreState, EventHook, PluginRegistry } from '@embedpdf/core';
|
|
2
|
+
import { TranslationKey } from '@embedpdf/plugin-i18n';
|
|
3
|
+
export type Dynamic<TStore, T> = T | ((context: {
|
|
4
|
+
state: TStore;
|
|
5
|
+
documentId: string;
|
|
6
|
+
}) => T);
|
|
7
|
+
export interface IconProps {
|
|
8
|
+
primaryColor?: string;
|
|
9
|
+
secondaryColor?: string;
|
|
10
|
+
className?: string;
|
|
11
|
+
title?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface Command<TStore = any> {
|
|
14
|
+
id: string;
|
|
15
|
+
label?: string;
|
|
16
|
+
labelKey?: TranslationKey;
|
|
17
|
+
labelParams?: Dynamic<TStore, Record<string, string | number>>;
|
|
18
|
+
icon?: Dynamic<TStore, string>;
|
|
19
|
+
iconProps?: Dynamic<TStore, IconProps>;
|
|
20
|
+
action: (context: {
|
|
21
|
+
registry: PluginRegistry;
|
|
22
|
+
state: TStore;
|
|
23
|
+
documentId: string;
|
|
24
|
+
}) => void;
|
|
25
|
+
active?: Dynamic<TStore, boolean>;
|
|
26
|
+
disabled?: Dynamic<TStore, boolean>;
|
|
27
|
+
visible?: Dynamic<TStore, boolean>;
|
|
28
|
+
shortcuts?: string | string[];
|
|
29
|
+
shortcutLabel?: string;
|
|
30
|
+
category?: string;
|
|
31
|
+
description?: string;
|
|
32
|
+
}
|
|
33
|
+
export interface ResolvedCommand {
|
|
34
|
+
id: string;
|
|
35
|
+
label: string;
|
|
36
|
+
icon?: string;
|
|
37
|
+
iconProps?: IconProps;
|
|
38
|
+
active: boolean;
|
|
39
|
+
disabled: boolean;
|
|
40
|
+
visible: boolean;
|
|
41
|
+
shortcuts?: string[];
|
|
42
|
+
shortcutLabel?: string;
|
|
43
|
+
category?: string;
|
|
44
|
+
description?: string;
|
|
45
|
+
execute: () => void;
|
|
46
|
+
}
|
|
47
|
+
export interface GlobalStoreState<TPlugins extends Record<string, any> = {}> {
|
|
48
|
+
core: CoreState;
|
|
49
|
+
plugins: TPlugins;
|
|
50
|
+
}
|
|
51
|
+
export interface CommandsPluginConfig extends BasePluginConfig {
|
|
52
|
+
commands: Record<string, Command>;
|
|
53
|
+
}
|
|
54
|
+
export interface CommandsState {
|
|
55
|
+
changedCommands: Set<string>;
|
|
56
|
+
}
|
|
57
|
+
export interface CommandExecutedEvent {
|
|
58
|
+
commandId: string;
|
|
59
|
+
documentId: string;
|
|
60
|
+
source: 'keyboard' | 'ui' | 'api';
|
|
61
|
+
}
|
|
62
|
+
export interface CommandStateChangedEvent {
|
|
63
|
+
commandId: string;
|
|
64
|
+
documentId: string;
|
|
65
|
+
changes: {
|
|
66
|
+
active?: boolean;
|
|
67
|
+
disabled?: boolean;
|
|
68
|
+
visible?: boolean;
|
|
69
|
+
label?: string;
|
|
70
|
+
iconProps?: IconProps;
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
export interface ShortcutExecutedEvent {
|
|
74
|
+
shortcut: string;
|
|
75
|
+
commandId: string;
|
|
76
|
+
documentId: string;
|
|
77
|
+
}
|
|
78
|
+
export interface CommandScope {
|
|
79
|
+
resolve(commandId: string): ResolvedCommand;
|
|
80
|
+
execute(commandId: string, source?: 'keyboard' | 'ui' | 'api'): void;
|
|
81
|
+
getAllCommands(): ResolvedCommand[];
|
|
82
|
+
getCommandsByCategory(category: string): ResolvedCommand[];
|
|
83
|
+
onCommandStateChanged: EventHook<Omit<CommandStateChangedEvent, 'documentId'>>;
|
|
84
|
+
}
|
|
85
|
+
export interface CommandsCapability {
|
|
86
|
+
resolve(commandId: string, documentId?: string): ResolvedCommand;
|
|
87
|
+
execute(commandId: string, documentId?: string, source?: 'keyboard' | 'ui' | 'api'): void;
|
|
88
|
+
getAllCommands(documentId?: string): ResolvedCommand[];
|
|
89
|
+
getCommandsByCategory(category: string, documentId?: string): ResolvedCommand[];
|
|
90
|
+
getCommandByShortcut(shortcut: string): Command | null;
|
|
91
|
+
getAllShortcuts(): Map<string, string>;
|
|
92
|
+
forDocument(documentId: string): CommandScope;
|
|
93
|
+
registerCommand(command: Command): void;
|
|
94
|
+
unregisterCommand(commandId: string): void;
|
|
95
|
+
onCommandExecuted: EventHook<CommandExecutedEvent>;
|
|
96
|
+
onCommandStateChanged: EventHook<CommandStateChangedEvent>;
|
|
97
|
+
onShortcutExecuted: EventHook<ShortcutExecutedEvent>;
|
|
98
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { Fragment } from 'preact';
|
|
2
|
+
export { useEffect, useRef, useState, useCallback, useMemo } from 'preact/hooks';
|
|
3
|
+
export type { ComponentChildren as ReactNode } from 'preact';
|
|
4
|
+
export type CSSProperties = import('preact').JSX.CSSProperties;
|
|
5
|
+
export type HTMLAttributes<T = any> = import('preact').JSX.HTMLAttributes<T extends EventTarget ? T : never>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '@embedpdf/core/preact';
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core"),t=require("@embedpdf/plugin-commands");require("preact");const r=require("preact/hooks"),o=require("@embedpdf/core/preact"),n=()=>o.useCapability(t.CommandsPlugin.id);function s(){const{provides:e}=n();return r.useEffect(()=>{if(!e)return;const t=function(e){return t=>{const r=t.target;if("INPUT"===r.tagName||"TEXTAREA"===r.tagName||r.isContentEditable)return;const o=function(e){const t=[];e.ctrlKey&&t.push("ctrl"),e.shiftKey&&t.push("shift"),e.altKey&&t.push("alt"),e.metaKey&&t.push("meta");const r=e.key.toLowerCase();return["control","shift","alt","meta"].includes(r)?null:[...t,r].sort().join("+")}(t);if(!o)return;const n=e.getCommandByShortcut(o);if(!n)return;const s=e.resolve(n.id);!s.disabled&&s.visible&&(t.preventDefault(),t.stopPropagation(),e.execute(n.id,void 0,"keyboard"))}}(e);return document.addEventListener("keydown",t),()=>document.removeEventListener("keydown",t)},[e]),null}const u=e.createPluginPackage(t.CommandsPluginPackage).addUtility(s).build();exports.CommandsPluginPackage=u,exports.KeyboardShortcuts=s,exports.useCommand=(e,t)=>{const{provides:o}=n(),[s,u]=r.useState(()=>o?o.resolve(e,t):null);return r.useEffect(()=>{if(!o)return void u(null);u(o.resolve(e,t));return o.onCommandStateChanged(r=>{r.commandId===e&&r.documentId===t&&u(o.resolve(e,t))})},[o,e,t]),s},exports.useCommandExecutor=e=>{const{provides:t}=n();return r=>{t&&t.execute(r,e,"ui")}},exports.useCommandsCapability=n,exports.useCommandsPlugin=()=>o.usePlugin(t.CommandsPlugin.id),Object.keys(t).forEach(e=>{"default"===e||Object.prototype.hasOwnProperty.call(exports,e)||Object.defineProperty(exports,e,{enumerable:!0,get:()=>t[e]})});
|
|
2
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../src/shared/hooks/use-commands.ts","../../src/shared/components/keyboard-shortcuts.tsx","../../src/shared/utils/keyboard-handler.ts","../../src/shared/index.ts"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport { CommandsPlugin, ResolvedCommand } from '@embedpdf/plugin-commands';\nimport { useState, useEffect } from '@framework';\n\nexport const useCommandsCapability = () => useCapability<CommandsPlugin>(CommandsPlugin.id);\nexport const useCommandsPlugin = () => usePlugin<CommandsPlugin>(CommandsPlugin.id);\n\n/**\n * Hook to get a reactive command for a specific document\n * Automatically updates when command state changes\n * @param commandId Command ID\n * @param documentId Document ID\n * @returns ResolvedCommand or null if not available\n */\nexport const useCommand = (commandId: string, documentId: string): ResolvedCommand | null => {\n const { provides } = useCommandsCapability();\n const [command, setCommand] = useState<ResolvedCommand | null>(() =>\n provides ? provides.resolve(commandId, documentId) : null,\n );\n\n useEffect(() => {\n if (!provides) {\n setCommand(null);\n return;\n }\n\n // Initial resolve\n setCommand(provides.resolve(commandId, documentId));\n\n // Subscribe to state changes for this command + document\n const unsubscribe = provides.onCommandStateChanged((event) => {\n if (event.commandId === commandId && event.documentId === documentId) {\n setCommand(provides.resolve(commandId, documentId));\n }\n });\n\n return unsubscribe;\n }, [provides, commandId, documentId]);\n\n return command;\n};\n\n/**\n * Hook to execute a command\n */\nexport const useCommandExecutor = (documentId: string) => {\n const { provides } = useCommandsCapability();\n\n return (commandId: string) => {\n if (provides) {\n provides.execute(commandId, documentId, 'ui');\n }\n };\n};\n","import { useEffect } from '@framework';\nimport { useCommandsCapability } from '../hooks';\nimport { createKeyDownHandler } from '../utils';\n\n/**\n * Utility component that listens to keyboard events\n * and executes commands based on shortcuts.\n * This component doesn't render anything, it just sets up keyboard shortcuts.\n */\nexport function KeyboardShortcuts() {\n const { provides: commands } = useCommandsCapability();\n\n useEffect(() => {\n if (!commands) return;\n\n const handleKeyDown = createKeyDownHandler(commands);\n\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [commands]);\n\n // This component is only used to set up keyboard shortcuts when the plugin is initialized.\n return null;\n}\n","import { CommandsCapability } from '../../lib/types';\n\n/**\n * Build a shortcut string from a keyboard event\n * @example Ctrl+Shift+A -> \"ctrl+shift+a\"\n */\nexport function buildShortcutString(event: KeyboardEvent): string | null {\n const modifiers: string[] = [];\n\n if (event.ctrlKey) modifiers.push('ctrl');\n if (event.shiftKey) modifiers.push('shift');\n if (event.altKey) modifiers.push('alt');\n if (event.metaKey) modifiers.push('meta');\n\n // Only add non-modifier keys\n const key = event.key.toLowerCase();\n const isModifier = ['control', 'shift', 'alt', 'meta'].includes(key);\n\n if (isModifier) {\n return null; // Just a modifier, no command\n }\n\n const parts = [...modifiers, key];\n return parts.sort().join('+');\n}\n\n/**\n * Handle keyboard events and execute commands based on shortcuts\n */\nexport function createKeyDownHandler(commands: CommandsCapability) {\n return (event: KeyboardEvent) => {\n // Don't handle shortcuts if target is an input, textarea, or contentEditable\n const target = event.target as HTMLElement;\n if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable) {\n return;\n }\n\n const shortcut = buildShortcutString(event);\n if (!shortcut) return;\n\n const command = commands.getCommandByShortcut(shortcut);\n if (!command) return;\n\n // Resolve without document ID - will use active document\n const resolved = commands.resolve(command.id);\n\n if (resolved.disabled || !resolved.visible) {\n return;\n }\n\n // Execute and prevent default (documentId is optional now)\n event.preventDefault();\n event.stopPropagation();\n commands.execute(command.id, undefined, 'keyboard');\n };\n}\n","import { createPluginPackage } from '@embedpdf/core';\nimport { CommandsPluginPackage as BaseCommandsPackage } from '@embedpdf/plugin-commands';\n\nimport { KeyboardShortcuts } from './components';\n\nexport * from './hooks';\nexport * from './components';\nexport * from '@embedpdf/plugin-commands';\n\nexport const CommandsPluginPackage = createPluginPackage(BaseCommandsPackage)\n .addUtility(KeyboardShortcuts)\n .build();\n"],"names":["useCommandsCapability","useCapability","CommandsPlugin","id","KeyboardShortcuts","provides","commands","useEffect","handleKeyDown","event","target","tagName","isContentEditable","shortcut","modifiers","ctrlKey","push","shiftKey","altKey","metaKey","key","toLowerCase","includes","sort","join","buildShortcutString","command","getCommandByShortcut","resolved","resolve","disabled","visible","preventDefault","stopPropagation","execute","createKeyDownHandler","document","addEventListener","removeEventListener","CommandsPluginPackage","createPluginPackage","BaseCommandsPackage","addUtility","build","commandId","documentId","setCommand","useState","onCommandStateChanged","usePlugin"],"mappings":"8OAIaA,EAAwB,IAAMC,gBAA8BC,EAAAA,eAAeC,ICKjF,SAASC,IACd,MAAQC,SAAUC,GAAaN,IAY/B,OAVAO,EAAAA,UAAU,KACR,IAAKD,EAAU,OAEf,MAAME,ECcH,SAA8BF,GACnC,OAAQG,IAEN,MAAMC,EAASD,EAAMC,OACrB,GAAuB,UAAnBA,EAAOC,SAA0C,aAAnBD,EAAOC,SAA0BD,EAAOE,kBACxE,OAGF,MAAMC,EA/BH,SAA6BJ,GAClC,MAAMK,EAAsB,GAExBL,EAAMM,SAASD,EAAUE,KAAK,QAC9BP,EAAMQ,UAAUH,EAAUE,KAAK,SAC/BP,EAAMS,QAAQJ,EAAUE,KAAK,OAC7BP,EAAMU,SAASL,EAAUE,KAAK,QAGlC,MAAMI,EAAMX,EAAMW,IAAIC,cAGtB,MAFmB,CAAC,UAAW,QAAS,MAAO,QAAQC,SAASF,GAGvD,KAGK,IAAIN,EAAWM,GAChBG,OAAOC,KAAK,IAC3B,CAaqBC,CAAoBhB,GACrC,IAAKI,EAAU,OAEf,MAAMa,EAAUpB,EAASqB,qBAAqBd,GAC9C,IAAKa,EAAS,OAGd,MAAME,EAAWtB,EAASuB,QAAQH,EAAQvB,KAEtCyB,EAASE,UAAaF,EAASG,UAKnCtB,EAAMuB,iBACNvB,EAAMwB,kBACN3B,EAAS4B,QAAQR,EAAQvB,QAAI,EAAW,aAE5C,CDxC0BgC,CAAqB7B,GAG3C,OADA8B,SAASC,iBAAiB,UAAW7B,GAC9B,IAAM4B,SAASE,oBAAoB,UAAW9B,IACpD,CAACF,IAGG,IACT,CEdO,MAAMiC,EAAwBC,EAAAA,oBAAoBC,EAAAA,uBACtDC,WAAWtC,GACXuC,uFHGuB,CAACC,EAAmBC,KAC5C,MAAMxC,SAAEA,GAAaL,KACd0B,EAASoB,GAAcC,EAAAA,SAAiC,IAC7D1C,EAAWA,EAASwB,QAAQe,EAAWC,GAAc,MAsBvD,OAnBAtC,EAAAA,UAAU,KACR,IAAKF,EAEH,YADAyC,EAAW,MAKbA,EAAWzC,EAASwB,QAAQe,EAAWC,IASvC,OANoBxC,EAAS2C,sBAAuBvC,IAC9CA,EAAMmC,YAAcA,GAAanC,EAAMoC,aAAeA,GACxDC,EAAWzC,EAASwB,QAAQe,EAAWC,OAK1C,CAACxC,EAAUuC,EAAWC,IAElBnB,8BAM0BmB,IACjC,MAAMxC,SAAEA,GAAaL,IAErB,OAAQ4C,IACFvC,GACFA,EAAS6B,QAAQU,EAAWC,EAAY,kEA7Cb,IAAMI,YAA0B/C,EAAAA,eAAeC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '../shared-preact';
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { createPluginPackage } from "@embedpdf/core";
|
|
2
|
+
import { CommandsPlugin, CommandsPluginPackage as CommandsPluginPackage$1 } from "@embedpdf/plugin-commands";
|
|
3
|
+
export * from "@embedpdf/plugin-commands";
|
|
4
|
+
import "preact";
|
|
5
|
+
import { useState, useEffect } from "preact/hooks";
|
|
6
|
+
import { useCapability, usePlugin } from "@embedpdf/core/preact";
|
|
7
|
+
const useCommandsCapability = () => useCapability(CommandsPlugin.id);
|
|
8
|
+
const useCommandsPlugin = () => usePlugin(CommandsPlugin.id);
|
|
9
|
+
const useCommand = (commandId, documentId) => {
|
|
10
|
+
const { provides } = useCommandsCapability();
|
|
11
|
+
const [command, setCommand] = useState(
|
|
12
|
+
() => provides ? provides.resolve(commandId, documentId) : null
|
|
13
|
+
);
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
if (!provides) {
|
|
16
|
+
setCommand(null);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
setCommand(provides.resolve(commandId, documentId));
|
|
20
|
+
const unsubscribe = provides.onCommandStateChanged((event) => {
|
|
21
|
+
if (event.commandId === commandId && event.documentId === documentId) {
|
|
22
|
+
setCommand(provides.resolve(commandId, documentId));
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
return unsubscribe;
|
|
26
|
+
}, [provides, commandId, documentId]);
|
|
27
|
+
return command;
|
|
28
|
+
};
|
|
29
|
+
const useCommandExecutor = (documentId) => {
|
|
30
|
+
const { provides } = useCommandsCapability();
|
|
31
|
+
return (commandId) => {
|
|
32
|
+
if (provides) {
|
|
33
|
+
provides.execute(commandId, documentId, "ui");
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
function buildShortcutString(event) {
|
|
38
|
+
const modifiers = [];
|
|
39
|
+
if (event.ctrlKey) modifiers.push("ctrl");
|
|
40
|
+
if (event.shiftKey) modifiers.push("shift");
|
|
41
|
+
if (event.altKey) modifiers.push("alt");
|
|
42
|
+
if (event.metaKey) modifiers.push("meta");
|
|
43
|
+
const key = event.key.toLowerCase();
|
|
44
|
+
const isModifier = ["control", "shift", "alt", "meta"].includes(key);
|
|
45
|
+
if (isModifier) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
const parts = [...modifiers, key];
|
|
49
|
+
return parts.sort().join("+");
|
|
50
|
+
}
|
|
51
|
+
function createKeyDownHandler(commands) {
|
|
52
|
+
return (event) => {
|
|
53
|
+
const target = event.target;
|
|
54
|
+
if (target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.isContentEditable) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const shortcut = buildShortcutString(event);
|
|
58
|
+
if (!shortcut) return;
|
|
59
|
+
const command = commands.getCommandByShortcut(shortcut);
|
|
60
|
+
if (!command) return;
|
|
61
|
+
const resolved = commands.resolve(command.id);
|
|
62
|
+
if (resolved.disabled || !resolved.visible) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
event.preventDefault();
|
|
66
|
+
event.stopPropagation();
|
|
67
|
+
commands.execute(command.id, void 0, "keyboard");
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
function KeyboardShortcuts() {
|
|
71
|
+
const { provides: commands } = useCommandsCapability();
|
|
72
|
+
useEffect(() => {
|
|
73
|
+
if (!commands) return;
|
|
74
|
+
const handleKeyDown = createKeyDownHandler(commands);
|
|
75
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
76
|
+
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
77
|
+
}, [commands]);
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
const CommandsPluginPackage = createPluginPackage(CommandsPluginPackage$1).addUtility(KeyboardShortcuts).build();
|
|
81
|
+
export {
|
|
82
|
+
CommandsPluginPackage,
|
|
83
|
+
KeyboardShortcuts,
|
|
84
|
+
useCommand,
|
|
85
|
+
useCommandExecutor,
|
|
86
|
+
useCommandsCapability,
|
|
87
|
+
useCommandsPlugin
|
|
88
|
+
};
|
|
89
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/shared/hooks/use-commands.ts","../../src/shared/utils/keyboard-handler.ts","../../src/shared/components/keyboard-shortcuts.tsx","../../src/shared/index.ts"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport { CommandsPlugin, ResolvedCommand } from '@embedpdf/plugin-commands';\nimport { useState, useEffect } from '@framework';\n\nexport const useCommandsCapability = () => useCapability<CommandsPlugin>(CommandsPlugin.id);\nexport const useCommandsPlugin = () => usePlugin<CommandsPlugin>(CommandsPlugin.id);\n\n/**\n * Hook to get a reactive command for a specific document\n * Automatically updates when command state changes\n * @param commandId Command ID\n * @param documentId Document ID\n * @returns ResolvedCommand or null if not available\n */\nexport const useCommand = (commandId: string, documentId: string): ResolvedCommand | null => {\n const { provides } = useCommandsCapability();\n const [command, setCommand] = useState<ResolvedCommand | null>(() =>\n provides ? provides.resolve(commandId, documentId) : null,\n );\n\n useEffect(() => {\n if (!provides) {\n setCommand(null);\n return;\n }\n\n // Initial resolve\n setCommand(provides.resolve(commandId, documentId));\n\n // Subscribe to state changes for this command + document\n const unsubscribe = provides.onCommandStateChanged((event) => {\n if (event.commandId === commandId && event.documentId === documentId) {\n setCommand(provides.resolve(commandId, documentId));\n }\n });\n\n return unsubscribe;\n }, [provides, commandId, documentId]);\n\n return command;\n};\n\n/**\n * Hook to execute a command\n */\nexport const useCommandExecutor = (documentId: string) => {\n const { provides } = useCommandsCapability();\n\n return (commandId: string) => {\n if (provides) {\n provides.execute(commandId, documentId, 'ui');\n }\n };\n};\n","import { CommandsCapability } from '../../lib/types';\n\n/**\n * Build a shortcut string from a keyboard event\n * @example Ctrl+Shift+A -> \"ctrl+shift+a\"\n */\nexport function buildShortcutString(event: KeyboardEvent): string | null {\n const modifiers: string[] = [];\n\n if (event.ctrlKey) modifiers.push('ctrl');\n if (event.shiftKey) modifiers.push('shift');\n if (event.altKey) modifiers.push('alt');\n if (event.metaKey) modifiers.push('meta');\n\n // Only add non-modifier keys\n const key = event.key.toLowerCase();\n const isModifier = ['control', 'shift', 'alt', 'meta'].includes(key);\n\n if (isModifier) {\n return null; // Just a modifier, no command\n }\n\n const parts = [...modifiers, key];\n return parts.sort().join('+');\n}\n\n/**\n * Handle keyboard events and execute commands based on shortcuts\n */\nexport function createKeyDownHandler(commands: CommandsCapability) {\n return (event: KeyboardEvent) => {\n // Don't handle shortcuts if target is an input, textarea, or contentEditable\n const target = event.target as HTMLElement;\n if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable) {\n return;\n }\n\n const shortcut = buildShortcutString(event);\n if (!shortcut) return;\n\n const command = commands.getCommandByShortcut(shortcut);\n if (!command) return;\n\n // Resolve without document ID - will use active document\n const resolved = commands.resolve(command.id);\n\n if (resolved.disabled || !resolved.visible) {\n return;\n }\n\n // Execute and prevent default (documentId is optional now)\n event.preventDefault();\n event.stopPropagation();\n commands.execute(command.id, undefined, 'keyboard');\n };\n}\n","import { useEffect } from '@framework';\nimport { useCommandsCapability } from '../hooks';\nimport { createKeyDownHandler } from '../utils';\n\n/**\n * Utility component that listens to keyboard events\n * and executes commands based on shortcuts.\n * This component doesn't render anything, it just sets up keyboard shortcuts.\n */\nexport function KeyboardShortcuts() {\n const { provides: commands } = useCommandsCapability();\n\n useEffect(() => {\n if (!commands) return;\n\n const handleKeyDown = createKeyDownHandler(commands);\n\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [commands]);\n\n // This component is only used to set up keyboard shortcuts when the plugin is initialized.\n return null;\n}\n","import { createPluginPackage } from '@embedpdf/core';\nimport { CommandsPluginPackage as BaseCommandsPackage } from '@embedpdf/plugin-commands';\n\nimport { KeyboardShortcuts } from './components';\n\nexport * from './hooks';\nexport * from './components';\nexport * from '@embedpdf/plugin-commands';\n\nexport const CommandsPluginPackage = createPluginPackage(BaseCommandsPackage)\n .addUtility(KeyboardShortcuts)\n .build();\n"],"names":["BaseCommandsPackage"],"mappings":";;;;;;AAIO,MAAM,wBAAwB,MAAM,cAA8B,eAAe,EAAE;AACnF,MAAM,oBAAoB,MAAM,UAA0B,eAAe,EAAE;AAS3E,MAAM,aAAa,CAAC,WAAmB,eAA+C;AAC3F,QAAM,EAAE,SAAA,IAAa,sBAAA;AACrB,QAAM,CAAC,SAAS,UAAU,IAAI;AAAA,IAAiC,MAC7D,WAAW,SAAS,QAAQ,WAAW,UAAU,IAAI;AAAA,EAAA;AAGvD,YAAU,MAAM;AACd,QAAI,CAAC,UAAU;AACb,iBAAW,IAAI;AACf;AAAA,IACF;AAGA,eAAW,SAAS,QAAQ,WAAW,UAAU,CAAC;AAGlD,UAAM,cAAc,SAAS,sBAAsB,CAAC,UAAU;AAC5D,UAAI,MAAM,cAAc,aAAa,MAAM,eAAe,YAAY;AACpE,mBAAW,SAAS,QAAQ,WAAW,UAAU,CAAC;AAAA,MACpD;AAAA,IACF,CAAC;AAED,WAAO;AAAA,EACT,GAAG,CAAC,UAAU,WAAW,UAAU,CAAC;AAEpC,SAAO;AACT;AAKO,MAAM,qBAAqB,CAAC,eAAuB;AACxD,QAAM,EAAE,SAAA,IAAa,sBAAA;AAErB,SAAO,CAAC,cAAsB;AAC5B,QAAI,UAAU;AACZ,eAAS,QAAQ,WAAW,YAAY,IAAI;AAAA,IAC9C;AAAA,EACF;AACF;AC/CO,SAAS,oBAAoB,OAAqC;AACvE,QAAM,YAAsB,CAAA;AAE5B,MAAI,MAAM,QAAS,WAAU,KAAK,MAAM;AACxC,MAAI,MAAM,SAAU,WAAU,KAAK,OAAO;AAC1C,MAAI,MAAM,OAAQ,WAAU,KAAK,KAAK;AACtC,MAAI,MAAM,QAAS,WAAU,KAAK,MAAM;AAGxC,QAAM,MAAM,MAAM,IAAI,YAAA;AACtB,QAAM,aAAa,CAAC,WAAW,SAAS,OAAO,MAAM,EAAE,SAAS,GAAG;AAEnE,MAAI,YAAY;AACd,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,CAAC,GAAG,WAAW,GAAG;AAChC,SAAO,MAAM,OAAO,KAAK,GAAG;AAC9B;AAKO,SAAS,qBAAqB,UAA8B;AACjE,SAAO,CAAC,UAAyB;AAE/B,UAAM,SAAS,MAAM;AACrB,QAAI,OAAO,YAAY,WAAW,OAAO,YAAY,cAAc,OAAO,mBAAmB;AAC3F;AAAA,IACF;AAEA,UAAM,WAAW,oBAAoB,KAAK;AAC1C,QAAI,CAAC,SAAU;AAEf,UAAM,UAAU,SAAS,qBAAqB,QAAQ;AACtD,QAAI,CAAC,QAAS;AAGd,UAAM,WAAW,SAAS,QAAQ,QAAQ,EAAE;AAE5C,QAAI,SAAS,YAAY,CAAC,SAAS,SAAS;AAC1C;AAAA,IACF;AAGA,UAAM,eAAA;AACN,UAAM,gBAAA;AACN,aAAS,QAAQ,QAAQ,IAAI,QAAW,UAAU;AAAA,EACpD;AACF;AC9CO,SAAS,oBAAoB;AAClC,QAAM,EAAE,UAAU,SAAA,IAAa,sBAAA;AAE/B,YAAU,MAAM;AACd,QAAI,CAAC,SAAU;AAEf,UAAM,gBAAgB,qBAAqB,QAAQ;AAEnD,aAAS,iBAAiB,WAAW,aAAa;AAClD,WAAO,MAAM,SAAS,oBAAoB,WAAW,aAAa;AAAA,EACpE,GAAG,CAAC,QAAQ,CAAC;AAGb,SAAO;AACT;ACdO,MAAM,wBAAwB,oBAAoBA,uBAAmB,EACzE,WAAW,iBAAiB,EAC5B,MAAA;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '@embedpdf/core/react';
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core"),t=require("@embedpdf/plugin-commands"),r=require("react"),o=require("@embedpdf/core/react"),n=()=>o.useCapability(t.CommandsPlugin.id);function s(){const{provides:e}=n();return r.useEffect(()=>{if(!e)return;const t=function(e){return t=>{const r=t.target;if("INPUT"===r.tagName||"TEXTAREA"===r.tagName||r.isContentEditable)return;const o=function(e){const t=[];e.ctrlKey&&t.push("ctrl"),e.shiftKey&&t.push("shift"),e.altKey&&t.push("alt"),e.metaKey&&t.push("meta");const r=e.key.toLowerCase();return["control","shift","alt","meta"].includes(r)?null:[...t,r].sort().join("+")}(t);if(!o)return;const n=e.getCommandByShortcut(o);if(!n)return;const s=e.resolve(n.id);!s.disabled&&s.visible&&(t.preventDefault(),t.stopPropagation(),e.execute(n.id,void 0,"keyboard"))}}(e);return document.addEventListener("keydown",t),()=>document.removeEventListener("keydown",t)},[e]),null}const u=e.createPluginPackage(t.CommandsPluginPackage).addUtility(s).build();exports.CommandsPluginPackage=u,exports.KeyboardShortcuts=s,exports.useCommand=(e,t)=>{const{provides:o}=n(),[s,u]=r.useState(()=>o?o.resolve(e,t):null);return r.useEffect(()=>{if(!o)return void u(null);u(o.resolve(e,t));return o.onCommandStateChanged(r=>{r.commandId===e&&r.documentId===t&&u(o.resolve(e,t))})},[o,e,t]),s},exports.useCommandExecutor=e=>{const{provides:t}=n();return r=>{t&&t.execute(r,e,"ui")}},exports.useCommandsCapability=n,exports.useCommandsPlugin=()=>o.usePlugin(t.CommandsPlugin.id),Object.keys(t).forEach(e=>{"default"===e||Object.prototype.hasOwnProperty.call(exports,e)||Object.defineProperty(exports,e,{enumerable:!0,get:()=>t[e]})});
|
|
2
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../src/shared/hooks/use-commands.ts","../../src/shared/components/keyboard-shortcuts.tsx","../../src/shared/utils/keyboard-handler.ts","../../src/shared/index.ts"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport { CommandsPlugin, ResolvedCommand } from '@embedpdf/plugin-commands';\nimport { useState, useEffect } from '@framework';\n\nexport const useCommandsCapability = () => useCapability<CommandsPlugin>(CommandsPlugin.id);\nexport const useCommandsPlugin = () => usePlugin<CommandsPlugin>(CommandsPlugin.id);\n\n/**\n * Hook to get a reactive command for a specific document\n * Automatically updates when command state changes\n * @param commandId Command ID\n * @param documentId Document ID\n * @returns ResolvedCommand or null if not available\n */\nexport const useCommand = (commandId: string, documentId: string): ResolvedCommand | null => {\n const { provides } = useCommandsCapability();\n const [command, setCommand] = useState<ResolvedCommand | null>(() =>\n provides ? provides.resolve(commandId, documentId) : null,\n );\n\n useEffect(() => {\n if (!provides) {\n setCommand(null);\n return;\n }\n\n // Initial resolve\n setCommand(provides.resolve(commandId, documentId));\n\n // Subscribe to state changes for this command + document\n const unsubscribe = provides.onCommandStateChanged((event) => {\n if (event.commandId === commandId && event.documentId === documentId) {\n setCommand(provides.resolve(commandId, documentId));\n }\n });\n\n return unsubscribe;\n }, [provides, commandId, documentId]);\n\n return command;\n};\n\n/**\n * Hook to execute a command\n */\nexport const useCommandExecutor = (documentId: string) => {\n const { provides } = useCommandsCapability();\n\n return (commandId: string) => {\n if (provides) {\n provides.execute(commandId, documentId, 'ui');\n }\n };\n};\n","import { useEffect } from '@framework';\nimport { useCommandsCapability } from '../hooks';\nimport { createKeyDownHandler } from '../utils';\n\n/**\n * Utility component that listens to keyboard events\n * and executes commands based on shortcuts.\n * This component doesn't render anything, it just sets up keyboard shortcuts.\n */\nexport function KeyboardShortcuts() {\n const { provides: commands } = useCommandsCapability();\n\n useEffect(() => {\n if (!commands) return;\n\n const handleKeyDown = createKeyDownHandler(commands);\n\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [commands]);\n\n // This component is only used to set up keyboard shortcuts when the plugin is initialized.\n return null;\n}\n","import { CommandsCapability } from '../../lib/types';\n\n/**\n * Build a shortcut string from a keyboard event\n * @example Ctrl+Shift+A -> \"ctrl+shift+a\"\n */\nexport function buildShortcutString(event: KeyboardEvent): string | null {\n const modifiers: string[] = [];\n\n if (event.ctrlKey) modifiers.push('ctrl');\n if (event.shiftKey) modifiers.push('shift');\n if (event.altKey) modifiers.push('alt');\n if (event.metaKey) modifiers.push('meta');\n\n // Only add non-modifier keys\n const key = event.key.toLowerCase();\n const isModifier = ['control', 'shift', 'alt', 'meta'].includes(key);\n\n if (isModifier) {\n return null; // Just a modifier, no command\n }\n\n const parts = [...modifiers, key];\n return parts.sort().join('+');\n}\n\n/**\n * Handle keyboard events and execute commands based on shortcuts\n */\nexport function createKeyDownHandler(commands: CommandsCapability) {\n return (event: KeyboardEvent) => {\n // Don't handle shortcuts if target is an input, textarea, or contentEditable\n const target = event.target as HTMLElement;\n if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable) {\n return;\n }\n\n const shortcut = buildShortcutString(event);\n if (!shortcut) return;\n\n const command = commands.getCommandByShortcut(shortcut);\n if (!command) return;\n\n // Resolve without document ID - will use active document\n const resolved = commands.resolve(command.id);\n\n if (resolved.disabled || !resolved.visible) {\n return;\n }\n\n // Execute and prevent default (documentId is optional now)\n event.preventDefault();\n event.stopPropagation();\n commands.execute(command.id, undefined, 'keyboard');\n };\n}\n","import { createPluginPackage } from '@embedpdf/core';\nimport { CommandsPluginPackage as BaseCommandsPackage } from '@embedpdf/plugin-commands';\n\nimport { KeyboardShortcuts } from './components';\n\nexport * from './hooks';\nexport * from './components';\nexport * from '@embedpdf/plugin-commands';\n\nexport const CommandsPluginPackage = createPluginPackage(BaseCommandsPackage)\n .addUtility(KeyboardShortcuts)\n .build();\n"],"names":["useCommandsCapability","useCapability","CommandsPlugin","id","KeyboardShortcuts","provides","commands","useEffect","handleKeyDown","event","target","tagName","isContentEditable","shortcut","modifiers","ctrlKey","push","shiftKey","altKey","metaKey","key","toLowerCase","includes","sort","join","buildShortcutString","command","getCommandByShortcut","resolved","resolve","disabled","visible","preventDefault","stopPropagation","execute","createKeyDownHandler","document","addEventListener","removeEventListener","CommandsPluginPackage","createPluginPackage","BaseCommandsPackage","addUtility","build","commandId","documentId","setCommand","useState","onCommandStateChanged","usePlugin"],"mappings":"8MAIaA,EAAwB,IAAMC,gBAA8BC,EAAAA,eAAeC,ICKjF,SAASC,IACd,MAAQC,SAAUC,GAAaN,IAY/B,OAVAO,EAAAA,UAAU,KACR,IAAKD,EAAU,OAEf,MAAME,ECcH,SAA8BF,GACnC,OAAQG,IAEN,MAAMC,EAASD,EAAMC,OACrB,GAAuB,UAAnBA,EAAOC,SAA0C,aAAnBD,EAAOC,SAA0BD,EAAOE,kBACxE,OAGF,MAAMC,EA/BH,SAA6BJ,GAClC,MAAMK,EAAsB,GAExBL,EAAMM,SAASD,EAAUE,KAAK,QAC9BP,EAAMQ,UAAUH,EAAUE,KAAK,SAC/BP,EAAMS,QAAQJ,EAAUE,KAAK,OAC7BP,EAAMU,SAASL,EAAUE,KAAK,QAGlC,MAAMI,EAAMX,EAAMW,IAAIC,cAGtB,MAFmB,CAAC,UAAW,QAAS,MAAO,QAAQC,SAASF,GAGvD,KAGK,IAAIN,EAAWM,GAChBG,OAAOC,KAAK,IAC3B,CAaqBC,CAAoBhB,GACrC,IAAKI,EAAU,OAEf,MAAMa,EAAUpB,EAASqB,qBAAqBd,GAC9C,IAAKa,EAAS,OAGd,MAAME,EAAWtB,EAASuB,QAAQH,EAAQvB,KAEtCyB,EAASE,UAAaF,EAASG,UAKnCtB,EAAMuB,iBACNvB,EAAMwB,kBACN3B,EAAS4B,QAAQR,EAAQvB,QAAI,EAAW,aAE5C,CDxC0BgC,CAAqB7B,GAG3C,OADA8B,SAASC,iBAAiB,UAAW7B,GAC9B,IAAM4B,SAASE,oBAAoB,UAAW9B,IACpD,CAACF,IAGG,IACT,CEdO,MAAMiC,EAAwBC,EAAAA,oBAAoBC,EAAAA,uBACtDC,WAAWtC,GACXuC,uFHGuB,CAACC,EAAmBC,KAC5C,MAAMxC,SAAEA,GAAaL,KACd0B,EAASoB,GAAcC,EAAAA,SAAiC,IAC7D1C,EAAWA,EAASwB,QAAQe,EAAWC,GAAc,MAsBvD,OAnBAtC,EAAAA,UAAU,KACR,IAAKF,EAEH,YADAyC,EAAW,MAKbA,EAAWzC,EAASwB,QAAQe,EAAWC,IASvC,OANoBxC,EAAS2C,sBAAuBvC,IAC9CA,EAAMmC,YAAcA,GAAanC,EAAMoC,aAAeA,GACxDC,EAAWzC,EAASwB,QAAQe,EAAWC,OAK1C,CAACxC,EAAUuC,EAAWC,IAElBnB,8BAM0BmB,IACjC,MAAMxC,SAAEA,GAAaL,IAErB,OAAQ4C,IACFvC,GACFA,EAAS6B,QAAQU,EAAWC,EAAY,kEA7Cb,IAAMI,YAA0B/C,EAAAA,eAAeC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '../shared-react';
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { createPluginPackage } from "@embedpdf/core";
|
|
2
|
+
import { CommandsPlugin, CommandsPluginPackage as CommandsPluginPackage$1 } from "@embedpdf/plugin-commands";
|
|
3
|
+
export * from "@embedpdf/plugin-commands";
|
|
4
|
+
import { useState, useEffect } from "react";
|
|
5
|
+
import { useCapability, usePlugin } from "@embedpdf/core/react";
|
|
6
|
+
const useCommandsCapability = () => useCapability(CommandsPlugin.id);
|
|
7
|
+
const useCommandsPlugin = () => usePlugin(CommandsPlugin.id);
|
|
8
|
+
const useCommand = (commandId, documentId) => {
|
|
9
|
+
const { provides } = useCommandsCapability();
|
|
10
|
+
const [command, setCommand] = useState(
|
|
11
|
+
() => provides ? provides.resolve(commandId, documentId) : null
|
|
12
|
+
);
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
if (!provides) {
|
|
15
|
+
setCommand(null);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
setCommand(provides.resolve(commandId, documentId));
|
|
19
|
+
const unsubscribe = provides.onCommandStateChanged((event) => {
|
|
20
|
+
if (event.commandId === commandId && event.documentId === documentId) {
|
|
21
|
+
setCommand(provides.resolve(commandId, documentId));
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
return unsubscribe;
|
|
25
|
+
}, [provides, commandId, documentId]);
|
|
26
|
+
return command;
|
|
27
|
+
};
|
|
28
|
+
const useCommandExecutor = (documentId) => {
|
|
29
|
+
const { provides } = useCommandsCapability();
|
|
30
|
+
return (commandId) => {
|
|
31
|
+
if (provides) {
|
|
32
|
+
provides.execute(commandId, documentId, "ui");
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
function buildShortcutString(event) {
|
|
37
|
+
const modifiers = [];
|
|
38
|
+
if (event.ctrlKey) modifiers.push("ctrl");
|
|
39
|
+
if (event.shiftKey) modifiers.push("shift");
|
|
40
|
+
if (event.altKey) modifiers.push("alt");
|
|
41
|
+
if (event.metaKey) modifiers.push("meta");
|
|
42
|
+
const key = event.key.toLowerCase();
|
|
43
|
+
const isModifier = ["control", "shift", "alt", "meta"].includes(key);
|
|
44
|
+
if (isModifier) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
const parts = [...modifiers, key];
|
|
48
|
+
return parts.sort().join("+");
|
|
49
|
+
}
|
|
50
|
+
function createKeyDownHandler(commands) {
|
|
51
|
+
return (event) => {
|
|
52
|
+
const target = event.target;
|
|
53
|
+
if (target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.isContentEditable) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const shortcut = buildShortcutString(event);
|
|
57
|
+
if (!shortcut) return;
|
|
58
|
+
const command = commands.getCommandByShortcut(shortcut);
|
|
59
|
+
if (!command) return;
|
|
60
|
+
const resolved = commands.resolve(command.id);
|
|
61
|
+
if (resolved.disabled || !resolved.visible) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
event.preventDefault();
|
|
65
|
+
event.stopPropagation();
|
|
66
|
+
commands.execute(command.id, void 0, "keyboard");
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function KeyboardShortcuts() {
|
|
70
|
+
const { provides: commands } = useCommandsCapability();
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
if (!commands) return;
|
|
73
|
+
const handleKeyDown = createKeyDownHandler(commands);
|
|
74
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
75
|
+
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
76
|
+
}, [commands]);
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
const CommandsPluginPackage = createPluginPackage(CommandsPluginPackage$1).addUtility(KeyboardShortcuts).build();
|
|
80
|
+
export {
|
|
81
|
+
CommandsPluginPackage,
|
|
82
|
+
KeyboardShortcuts,
|
|
83
|
+
useCommand,
|
|
84
|
+
useCommandExecutor,
|
|
85
|
+
useCommandsCapability,
|
|
86
|
+
useCommandsPlugin
|
|
87
|
+
};
|
|
88
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/shared/hooks/use-commands.ts","../../src/shared/utils/keyboard-handler.ts","../../src/shared/components/keyboard-shortcuts.tsx","../../src/shared/index.ts"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport { CommandsPlugin, ResolvedCommand } from '@embedpdf/plugin-commands';\nimport { useState, useEffect } from '@framework';\n\nexport const useCommandsCapability = () => useCapability<CommandsPlugin>(CommandsPlugin.id);\nexport const useCommandsPlugin = () => usePlugin<CommandsPlugin>(CommandsPlugin.id);\n\n/**\n * Hook to get a reactive command for a specific document\n * Automatically updates when command state changes\n * @param commandId Command ID\n * @param documentId Document ID\n * @returns ResolvedCommand or null if not available\n */\nexport const useCommand = (commandId: string, documentId: string): ResolvedCommand | null => {\n const { provides } = useCommandsCapability();\n const [command, setCommand] = useState<ResolvedCommand | null>(() =>\n provides ? provides.resolve(commandId, documentId) : null,\n );\n\n useEffect(() => {\n if (!provides) {\n setCommand(null);\n return;\n }\n\n // Initial resolve\n setCommand(provides.resolve(commandId, documentId));\n\n // Subscribe to state changes for this command + document\n const unsubscribe = provides.onCommandStateChanged((event) => {\n if (event.commandId === commandId && event.documentId === documentId) {\n setCommand(provides.resolve(commandId, documentId));\n }\n });\n\n return unsubscribe;\n }, [provides, commandId, documentId]);\n\n return command;\n};\n\n/**\n * Hook to execute a command\n */\nexport const useCommandExecutor = (documentId: string) => {\n const { provides } = useCommandsCapability();\n\n return (commandId: string) => {\n if (provides) {\n provides.execute(commandId, documentId, 'ui');\n }\n };\n};\n","import { CommandsCapability } from '../../lib/types';\n\n/**\n * Build a shortcut string from a keyboard event\n * @example Ctrl+Shift+A -> \"ctrl+shift+a\"\n */\nexport function buildShortcutString(event: KeyboardEvent): string | null {\n const modifiers: string[] = [];\n\n if (event.ctrlKey) modifiers.push('ctrl');\n if (event.shiftKey) modifiers.push('shift');\n if (event.altKey) modifiers.push('alt');\n if (event.metaKey) modifiers.push('meta');\n\n // Only add non-modifier keys\n const key = event.key.toLowerCase();\n const isModifier = ['control', 'shift', 'alt', 'meta'].includes(key);\n\n if (isModifier) {\n return null; // Just a modifier, no command\n }\n\n const parts = [...modifiers, key];\n return parts.sort().join('+');\n}\n\n/**\n * Handle keyboard events and execute commands based on shortcuts\n */\nexport function createKeyDownHandler(commands: CommandsCapability) {\n return (event: KeyboardEvent) => {\n // Don't handle shortcuts if target is an input, textarea, or contentEditable\n const target = event.target as HTMLElement;\n if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable) {\n return;\n }\n\n const shortcut = buildShortcutString(event);\n if (!shortcut) return;\n\n const command = commands.getCommandByShortcut(shortcut);\n if (!command) return;\n\n // Resolve without document ID - will use active document\n const resolved = commands.resolve(command.id);\n\n if (resolved.disabled || !resolved.visible) {\n return;\n }\n\n // Execute and prevent default (documentId is optional now)\n event.preventDefault();\n event.stopPropagation();\n commands.execute(command.id, undefined, 'keyboard');\n };\n}\n","import { useEffect } from '@framework';\nimport { useCommandsCapability } from '../hooks';\nimport { createKeyDownHandler } from '../utils';\n\n/**\n * Utility component that listens to keyboard events\n * and executes commands based on shortcuts.\n * This component doesn't render anything, it just sets up keyboard shortcuts.\n */\nexport function KeyboardShortcuts() {\n const { provides: commands } = useCommandsCapability();\n\n useEffect(() => {\n if (!commands) return;\n\n const handleKeyDown = createKeyDownHandler(commands);\n\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [commands]);\n\n // This component is only used to set up keyboard shortcuts when the plugin is initialized.\n return null;\n}\n","import { createPluginPackage } from '@embedpdf/core';\nimport { CommandsPluginPackage as BaseCommandsPackage } from '@embedpdf/plugin-commands';\n\nimport { KeyboardShortcuts } from './components';\n\nexport * from './hooks';\nexport * from './components';\nexport * from '@embedpdf/plugin-commands';\n\nexport const CommandsPluginPackage = createPluginPackage(BaseCommandsPackage)\n .addUtility(KeyboardShortcuts)\n .build();\n"],"names":["BaseCommandsPackage"],"mappings":";;;;;AAIO,MAAM,wBAAwB,MAAM,cAA8B,eAAe,EAAE;AACnF,MAAM,oBAAoB,MAAM,UAA0B,eAAe,EAAE;AAS3E,MAAM,aAAa,CAAC,WAAmB,eAA+C;AAC3F,QAAM,EAAE,SAAA,IAAa,sBAAA;AACrB,QAAM,CAAC,SAAS,UAAU,IAAI;AAAA,IAAiC,MAC7D,WAAW,SAAS,QAAQ,WAAW,UAAU,IAAI;AAAA,EAAA;AAGvD,YAAU,MAAM;AACd,QAAI,CAAC,UAAU;AACb,iBAAW,IAAI;AACf;AAAA,IACF;AAGA,eAAW,SAAS,QAAQ,WAAW,UAAU,CAAC;AAGlD,UAAM,cAAc,SAAS,sBAAsB,CAAC,UAAU;AAC5D,UAAI,MAAM,cAAc,aAAa,MAAM,eAAe,YAAY;AACpE,mBAAW,SAAS,QAAQ,WAAW,UAAU,CAAC;AAAA,MACpD;AAAA,IACF,CAAC;AAED,WAAO;AAAA,EACT,GAAG,CAAC,UAAU,WAAW,UAAU,CAAC;AAEpC,SAAO;AACT;AAKO,MAAM,qBAAqB,CAAC,eAAuB;AACxD,QAAM,EAAE,SAAA,IAAa,sBAAA;AAErB,SAAO,CAAC,cAAsB;AAC5B,QAAI,UAAU;AACZ,eAAS,QAAQ,WAAW,YAAY,IAAI;AAAA,IAC9C;AAAA,EACF;AACF;AC/CO,SAAS,oBAAoB,OAAqC;AACvE,QAAM,YAAsB,CAAA;AAE5B,MAAI,MAAM,QAAS,WAAU,KAAK,MAAM;AACxC,MAAI,MAAM,SAAU,WAAU,KAAK,OAAO;AAC1C,MAAI,MAAM,OAAQ,WAAU,KAAK,KAAK;AACtC,MAAI,MAAM,QAAS,WAAU,KAAK,MAAM;AAGxC,QAAM,MAAM,MAAM,IAAI,YAAA;AACtB,QAAM,aAAa,CAAC,WAAW,SAAS,OAAO,MAAM,EAAE,SAAS,GAAG;AAEnE,MAAI,YAAY;AACd,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,CAAC,GAAG,WAAW,GAAG;AAChC,SAAO,MAAM,OAAO,KAAK,GAAG;AAC9B;AAKO,SAAS,qBAAqB,UAA8B;AACjE,SAAO,CAAC,UAAyB;AAE/B,UAAM,SAAS,MAAM;AACrB,QAAI,OAAO,YAAY,WAAW,OAAO,YAAY,cAAc,OAAO,mBAAmB;AAC3F;AAAA,IACF;AAEA,UAAM,WAAW,oBAAoB,KAAK;AAC1C,QAAI,CAAC,SAAU;AAEf,UAAM,UAAU,SAAS,qBAAqB,QAAQ;AACtD,QAAI,CAAC,QAAS;AAGd,UAAM,WAAW,SAAS,QAAQ,QAAQ,EAAE;AAE5C,QAAI,SAAS,YAAY,CAAC,SAAS,SAAS;AAC1C;AAAA,IACF;AAGA,UAAM,eAAA;AACN,UAAM,gBAAA;AACN,aAAS,QAAQ,QAAQ,IAAI,QAAW,UAAU;AAAA,EACpD;AACF;AC9CO,SAAS,oBAAoB;AAClC,QAAM,EAAE,UAAU,SAAA,IAAa,sBAAA;AAE/B,YAAU,MAAM;AACd,QAAI,CAAC,SAAU;AAEf,UAAM,gBAAgB,qBAAqB,QAAQ;AAEnD,aAAS,iBAAiB,WAAW,aAAa;AAClD,WAAO,MAAM,SAAS,oBAAoB,WAAW,aAAa;AAAA,EACpE,GAAG,CAAC,QAAQ,CAAC;AAGb,SAAO;AACT;ACdO,MAAM,wBAAwB,oBAAoBA,uBAAmB,EACzE,WAAW,iBAAiB,EAC5B,MAAA;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { KeyboardShortcuts } from './keyboard-shortcuts';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './use-commands';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { CommandsPlugin, ResolvedCommand } from '../../index.ts';
|
|
2
|
+
export declare const useCommandsCapability: () => {
|
|
3
|
+
provides: Readonly<import('../../index.ts').CommandsCapability> | null;
|
|
4
|
+
isLoading: boolean;
|
|
5
|
+
ready: Promise<void>;
|
|
6
|
+
};
|
|
7
|
+
export declare const useCommandsPlugin: () => {
|
|
8
|
+
plugin: CommandsPlugin | null;
|
|
9
|
+
isLoading: boolean;
|
|
10
|
+
ready: Promise<void>;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Hook to get a reactive command for a specific document
|
|
14
|
+
* Automatically updates when command state changes
|
|
15
|
+
* @param commandId Command ID
|
|
16
|
+
* @param documentId Document ID
|
|
17
|
+
* @returns ResolvedCommand or null if not available
|
|
18
|
+
*/
|
|
19
|
+
export declare const useCommand: (commandId: string, documentId: string) => ResolvedCommand | null;
|
|
20
|
+
/**
|
|
21
|
+
* Hook to execute a command
|
|
22
|
+
*/
|
|
23
|
+
export declare const useCommandExecutor: (documentId: string) => (commandId: string) => void;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export * from './hooks';
|
|
2
|
+
export * from './components';
|
|
3
|
+
export * from '../index.ts';
|
|
4
|
+
export declare const CommandsPluginPackage: import('@embedpdf/core').WithAutoMount<import('@embedpdf/core').PluginPackage<import('../index.ts').CommandsPlugin, import('../index.ts').CommandsPluginConfig, import('../index.ts').CommandsState, import('../lib/actions').CommandsAction>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './keyboard-handler';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { CommandsCapability } from '../../lib/types';
|
|
2
|
+
/**
|
|
3
|
+
* Build a shortcut string from a keyboard event
|
|
4
|
+
* @example Ctrl+Shift+A -> "ctrl+shift+a"
|
|
5
|
+
*/
|
|
6
|
+
export declare function buildShortcutString(event: KeyboardEvent): string | null;
|
|
7
|
+
/**
|
|
8
|
+
* Handle keyboard events and execute commands based on shortcuts
|
|
9
|
+
*/
|
|
10
|
+
export declare function createKeyDownHandler(commands: CommandsCapability): (event: KeyboardEvent) => void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { KeyboardShortcuts } from './keyboard-shortcuts';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './use-commands';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { CommandsPlugin, ResolvedCommand } from '../../lib/index.ts';
|
|
2
|
+
export declare const useCommandsCapability: () => {
|
|
3
|
+
provides: Readonly<import('../../lib/index.ts').CommandsCapability> | null;
|
|
4
|
+
isLoading: boolean;
|
|
5
|
+
ready: Promise<void>;
|
|
6
|
+
};
|
|
7
|
+
export declare const useCommandsPlugin: () => {
|
|
8
|
+
plugin: CommandsPlugin | null;
|
|
9
|
+
isLoading: boolean;
|
|
10
|
+
ready: Promise<void>;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Hook to get a reactive command for a specific document
|
|
14
|
+
* Automatically updates when command state changes
|
|
15
|
+
* @param commandId Command ID
|
|
16
|
+
* @param documentId Document ID
|
|
17
|
+
* @returns ResolvedCommand or null if not available
|
|
18
|
+
*/
|
|
19
|
+
export declare const useCommand: (commandId: string, documentId: string) => ResolvedCommand | null;
|
|
20
|
+
/**
|
|
21
|
+
* Hook to execute a command
|
|
22
|
+
*/
|
|
23
|
+
export declare const useCommandExecutor: (documentId: string) => (commandId: string) => void;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export * from './hooks';
|
|
2
|
+
export * from './components';
|
|
3
|
+
export * from '../lib/index.ts';
|
|
4
|
+
export declare const CommandsPluginPackage: import('@embedpdf/core').WithAutoMount<import('@embedpdf/core').PluginPackage<import('../lib/index.ts').CommandsPlugin, import('../lib/index.ts').CommandsPluginConfig, import('../lib/index.ts').CommandsState, import('../lib/actions').CommandsAction>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './keyboard-handler';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { CommandsCapability } from '../../lib/types';
|
|
2
|
+
/**
|
|
3
|
+
* Build a shortcut string from a keyboard event
|
|
4
|
+
* @example Ctrl+Shift+A -> "ctrl+shift+a"
|
|
5
|
+
*/
|
|
6
|
+
export declare function buildShortcutString(event: KeyboardEvent): string | null;
|
|
7
|
+
/**
|
|
8
|
+
* Handle keyboard events and execute commands based on shortcuts
|
|
9
|
+
*/
|
|
10
|
+
export declare function createKeyDownHandler(commands: CommandsCapability): (event: KeyboardEvent) => void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { KeyboardShortcuts } from './keyboard-shortcuts';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './use-commands';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { CommandsPlugin, ResolvedCommand } from '../../lib/index.ts';
|
|
2
|
+
export declare const useCommandsCapability: () => {
|
|
3
|
+
provides: Readonly<import('../../lib/index.ts').CommandsCapability> | null;
|
|
4
|
+
isLoading: boolean;
|
|
5
|
+
ready: Promise<void>;
|
|
6
|
+
};
|
|
7
|
+
export declare const useCommandsPlugin: () => {
|
|
8
|
+
plugin: CommandsPlugin | null;
|
|
9
|
+
isLoading: boolean;
|
|
10
|
+
ready: Promise<void>;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Hook to get a reactive command for a specific document
|
|
14
|
+
* Automatically updates when command state changes
|
|
15
|
+
* @param commandId Command ID
|
|
16
|
+
* @param documentId Document ID
|
|
17
|
+
* @returns ResolvedCommand or null if not available
|
|
18
|
+
*/
|
|
19
|
+
export declare const useCommand: (commandId: string, documentId: string) => ResolvedCommand | null;
|
|
20
|
+
/**
|
|
21
|
+
* Hook to execute a command
|
|
22
|
+
*/
|
|
23
|
+
export declare const useCommandExecutor: (documentId: string) => (commandId: string) => void;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export * from './hooks';
|
|
2
|
+
export * from './components';
|
|
3
|
+
export * from '../lib/index.ts';
|
|
4
|
+
export declare const CommandsPluginPackage: import('@embedpdf/core').WithAutoMount<import('@embedpdf/core').PluginPackage<import('../lib/index.ts').CommandsPlugin, import('../lib/index.ts').CommandsPluginConfig, import('../lib/index.ts').CommandsState, import('../lib/actions').CommandsAction>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './keyboard-handler';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { CommandsCapability } from '../../lib/types';
|
|
2
|
+
/**
|
|
3
|
+
* Build a shortcut string from a keyboard event
|
|
4
|
+
* @example Ctrl+Shift+A -> "ctrl+shift+a"
|
|
5
|
+
*/
|
|
6
|
+
export declare function buildShortcutString(event: KeyboardEvent): string | null;
|
|
7
|
+
/**
|
|
8
|
+
* Handle keyboard events and execute commands based on shortcuts
|
|
9
|
+
*/
|
|
10
|
+
export declare function createKeyDownHandler(commands: CommandsCapability): (event: KeyboardEvent) => void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './keyboard-handler';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { CommandsCapability } from '../../lib/types';
|
|
2
|
+
/**
|
|
3
|
+
* Build a shortcut string from a keyboard event
|
|
4
|
+
* @example Ctrl+Shift+A -> "ctrl+shift+a"
|
|
5
|
+
*/
|
|
6
|
+
export declare function buildShortcutString(event: KeyboardEvent): string | null;
|
|
7
|
+
/**
|
|
8
|
+
* Handle keyboard events and execute commands based on shortcuts
|
|
9
|
+
*/
|
|
10
|
+
export declare function createKeyDownHandler(commands: CommandsCapability): (event: KeyboardEvent) => void;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
2
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
3
|
+
$$bindings?: Bindings;
|
|
4
|
+
} & Exports;
|
|
5
|
+
(internal: unknown, props: {
|
|
6
|
+
$$events?: Events;
|
|
7
|
+
$$slots?: Slots;
|
|
8
|
+
}): Exports & {
|
|
9
|
+
$set?: any;
|
|
10
|
+
$on?: any;
|
|
11
|
+
};
|
|
12
|
+
z_$$bindings?: Bindings;
|
|
13
|
+
}
|
|
14
|
+
declare const KeyboardShortcuts: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
|
|
15
|
+
[evt: string]: CustomEvent<any>;
|
|
16
|
+
}, {}, {}, string>;
|
|
17
|
+
type KeyboardShortcuts = InstanceType<typeof KeyboardShortcuts>;
|
|
18
|
+
export default KeyboardShortcuts;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as KeyboardShortcuts } from './KeyboardShortcuts.svelte';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './use-commands.svelte';
|