@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.
Files changed (68) hide show
  1. package/LICENSE +21 -0
  2. package/dist/index.cjs +2 -0
  3. package/dist/index.cjs.map +1 -0
  4. package/dist/index.d.ts +1 -0
  5. package/dist/index.js +316 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/lib/actions.d.ts +25 -0
  8. package/dist/lib/commands-plugin.d.ts +31 -0
  9. package/dist/lib/index.d.ts +8 -0
  10. package/dist/lib/manifest.d.ts +4 -0
  11. package/dist/lib/reducer.d.ts +5 -0
  12. package/dist/lib/types.d.ts +98 -0
  13. package/dist/preact/adapter.d.ts +5 -0
  14. package/dist/preact/core.d.ts +1 -0
  15. package/dist/preact/index.cjs +2 -0
  16. package/dist/preact/index.cjs.map +1 -0
  17. package/dist/preact/index.d.ts +1 -0
  18. package/dist/preact/index.js +89 -0
  19. package/dist/preact/index.js.map +1 -0
  20. package/dist/react/adapter.d.ts +2 -0
  21. package/dist/react/core.d.ts +1 -0
  22. package/dist/react/index.cjs +2 -0
  23. package/dist/react/index.cjs.map +1 -0
  24. package/dist/react/index.d.ts +1 -0
  25. package/dist/react/index.js +88 -0
  26. package/dist/react/index.js.map +1 -0
  27. package/dist/shared/components/index.d.ts +1 -0
  28. package/dist/shared/components/keyboard-shortcuts.d.ts +6 -0
  29. package/dist/shared/hooks/index.d.ts +1 -0
  30. package/dist/shared/hooks/use-commands.d.ts +23 -0
  31. package/dist/shared/index.d.ts +4 -0
  32. package/dist/shared/utils/index.d.ts +1 -0
  33. package/dist/shared/utils/keyboard-handler.d.ts +10 -0
  34. package/dist/shared-preact/components/index.d.ts +1 -0
  35. package/dist/shared-preact/components/keyboard-shortcuts.d.ts +6 -0
  36. package/dist/shared-preact/hooks/index.d.ts +1 -0
  37. package/dist/shared-preact/hooks/use-commands.d.ts +23 -0
  38. package/dist/shared-preact/index.d.ts +4 -0
  39. package/dist/shared-preact/utils/index.d.ts +1 -0
  40. package/dist/shared-preact/utils/keyboard-handler.d.ts +10 -0
  41. package/dist/shared-react/components/index.d.ts +1 -0
  42. package/dist/shared-react/components/keyboard-shortcuts.d.ts +6 -0
  43. package/dist/shared-react/hooks/index.d.ts +1 -0
  44. package/dist/shared-react/hooks/use-commands.d.ts +23 -0
  45. package/dist/shared-react/index.d.ts +4 -0
  46. package/dist/shared-react/utils/index.d.ts +1 -0
  47. package/dist/shared-react/utils/keyboard-handler.d.ts +10 -0
  48. package/dist/shared-vue/utils/index.d.ts +1 -0
  49. package/dist/shared-vue/utils/keyboard-handler.d.ts +10 -0
  50. package/dist/svelte/components/KeyboardShortcuts.svelte.d.ts +18 -0
  51. package/dist/svelte/components/index.d.ts +1 -0
  52. package/dist/svelte/hooks/index.d.ts +1 -0
  53. package/dist/svelte/hooks/use-commands.svelte.d.ts +21 -0
  54. package/dist/svelte/index.cjs +2 -0
  55. package/dist/svelte/index.cjs.map +1 -0
  56. package/dist/svelte/index.d.ts +4 -0
  57. package/dist/svelte/index.js +90 -0
  58. package/dist/svelte/index.js.map +1 -0
  59. package/dist/vue/components/index.d.ts +1 -0
  60. package/dist/vue/components/keyboard-shortcuts.vue.d.ts +3 -0
  61. package/dist/vue/hooks/index.d.ts +1 -0
  62. package/dist/vue/hooks/use-commands.d.ts +46 -0
  63. package/dist/vue/index.cjs +2 -0
  64. package/dist/vue/index.cjs.map +1 -0
  65. package/dist/vue/index.d.ts +4 -0
  66. package/dist/vue/index.js +90 -0
  67. package/dist/vue/index.js.map +1 -0
  68. 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,2 @@
1
+ export { Fragment, useEffect, useRef, useState, useCallback, useMemo } from 'react';
2
+ export type { ReactNode, HTMLAttributes, CSSProperties } from 'react';
@@ -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,6 @@
1
+ /**
2
+ * Utility component that listens to keyboard events
3
+ * and executes commands based on shortcuts.
4
+ * This component doesn't render anything, it just sets up keyboard shortcuts.
5
+ */
6
+ export declare function KeyboardShortcuts(): null;
@@ -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,6 @@
1
+ /**
2
+ * Utility component that listens to keyboard events
3
+ * and executes commands based on shortcuts.
4
+ * This component doesn't render anything, it just sets up keyboard shortcuts.
5
+ */
6
+ export declare function KeyboardShortcuts(): null;
@@ -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,6 @@
1
+ /**
2
+ * Utility component that listens to keyboard events
3
+ * and executes commands based on shortcuts.
4
+ * This component doesn't render anything, it just sets up keyboard shortcuts.
5
+ */
6
+ export declare function KeyboardShortcuts(): null;
@@ -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';