@plannotator/ui 0.28.0 → 0.29.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/README.md +6 -0
- package/components/AISettingsTab.tsx +5 -4
- package/components/ActionMenu.tsx +5 -1
- package/components/AgentsTab.tsx +10 -23
- package/components/AnnotationPanel.tsx +9 -5
- package/components/AnnotationToolbar.tsx +5 -13
- package/components/AnnotationToolstrip.tsx +2 -2
- package/components/ApproveDropdown.tsx +1 -1
- package/components/BlockRenderer.tsx +1 -1
- package/components/CodeFilePopout.tsx +5 -4
- package/components/CommentPopover.tsx +391 -65
- package/components/DocBadges.tsx +29 -11
- package/components/ExportModal.tsx +16 -8
- package/components/GraphvizBlock.tsx +1 -1
- package/components/InlineMarkdown.tsx +30 -13
- package/components/KeyboardShortcuts.tsx +37 -2
- package/components/Landing.tsx +7 -7
- package/components/MenuVersionSection.tsx +4 -4
- package/components/MermaidBlock.tsx +1 -1
- package/components/ModeToggle.tsx +7 -6
- package/components/OpenInAppButton.tsx +2 -5
- package/components/PinpointOverlay.tsx +9 -7
- package/components/PlanHeaderMenu.tsx +8 -8
- package/components/PopoutDialog.tsx +6 -1
- package/components/ResizeHandle.tsx +1 -0
- package/components/Settings.tsx +172 -12
- package/components/SkillReferenceMenu.tsx +260 -0
- package/components/StickyHeaderLane.tsx +7 -0
- package/components/ThemeProvider.tsx +131 -32
- package/components/ThemeTab.tsx +123 -77
- package/components/ToolbarButtons.tsx +29 -8
- package/components/Viewer.tsx +396 -130
- package/components/VimKeyHud.tsx +695 -0
- package/components/VimModeAnnouncementDialog.tsx +557 -0
- package/components/VimModeOverlay.tsx +235 -0
- package/components/VimTargetReticle.tsx +284 -0
- package/components/ai/DocumentAIChatPanel.tsx +1 -1
- package/components/blocks/CodeBlock.tsx +18 -18
- package/components/blocks/TablePopout.tsx +7 -8
- package/components/blocks/TableToolbar.tsx +7 -8
- package/components/goal-setup/GoalSetupSurface.tsx +16 -3
- package/components/html-viewer/HtmlViewer.tsx +450 -47
- package/components/html-viewer/annotationNumbering.ts +37 -0
- package/components/html-viewer/bridge-script.ts +4051 -298
- package/components/html-viewer/composerYield.ts +51 -0
- package/components/html-viewer/srcdoc.ts +18 -3
- package/components/html-viewer/useHtmlAnnotation.ts +457 -32
- package/components/icons/themeIcons.tsx +1 -1
- package/components/plan-diff/PlanCleanDiffView.tsx +9 -9
- package/components/plan-diff/PlanDiffBadge.tsx +22 -1
- package/components/settings/HooksTab.tsx +12 -8
- package/components/sidebar/FileBrowser.tsx +4 -1
- package/components/themeModes.tsx +28 -0
- package/config/configStore.ts +76 -1
- package/config/settings.ts +152 -0
- package/configure.ts +9 -0
- package/globals.d.ts +7 -1
- package/hooks/useAIChat.ts +5 -2
- package/hooks/useAIProviderActivation.ts +47 -0
- package/hooks/useAIProviderConfig.ts +5 -1
- package/hooks/useAgentSettings.ts +64 -23
- package/hooks/useAgents.ts +4 -4
- package/hooks/useAnnotationHighlighter.ts +100 -3
- package/hooks/useArchive.ts +2 -1
- package/hooks/useFenceTheme.ts +17 -0
- package/hooks/useLinkedDoc.ts +68 -1
- package/hooks/usePinpoint.ts +76 -75
- package/hooks/usePlanDiff.ts +73 -2
- package/hooks/useSkillReferenceAutocomplete.ts +239 -0
- package/hooks/useUpdateCheck.ts +1 -2
- package/hooks/useVimDocumentFocus.ts +116 -0
- package/hooks/useVimSelection.ts +1063 -0
- package/package.json +4 -4
- package/print.css +14 -13
- package/shortcuts/core.ts +38 -13
- package/shortcuts/index.ts +10 -0
- package/shortcuts/plan-review/commentPopover.shortcuts.ts +7 -0
- package/shortcuts/plan-review/vimSelection.shortcuts.ts +251 -0
- package/shortcuts/runtime.ts +111 -12
- package/styles.css +1 -1
- package/theme.css +504 -0
- package/themes/colorblind.css +89 -0
- package/themes/plannotator.css +2 -2
- package/types.ts +93 -10
- package/utils/agentSwitch.ts +33 -7
- package/utils/blockTargeting.ts +462 -178
- package/utils/clipboard.ts +110 -0
- package/utils/codeBlockMark.ts +50 -0
- package/utils/codeHighlight.ts +293 -0
- package/utils/codexModels.ts +79 -0
- package/utils/domSelection.ts +84 -0
- package/utils/htmlChrome.ts +73 -0
- package/utils/inputMethod.ts +79 -6
- package/utils/parser.ts +517 -21
- package/utils/preferenceTtl.ts +15 -0
- package/utils/sharing.ts +0 -1
- package/utils/skillCatalog.ts +269 -0
- package/utils/skillReferences.ts +475 -0
- package/utils/syntaxTheme.ts +83 -0
- package/utils/themeRegistry.ts +154 -0
- package/utils/vimHud.ts +263 -0
- package/utils/vimModeAnnouncement.ts +23 -0
- package/utils/vimNavigation.ts +417 -0
- package/utils/vimReticle.ts +88 -0
- package/utils/vimScroll.ts +162 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { useEffect, useRef } from 'react';
|
|
2
|
+
|
|
3
|
+
const VIM_DOCUMENT_FOCUS_REQUEST = 'plannotator:vim-document-focus-request';
|
|
4
|
+
|
|
5
|
+
const EDITABLE_FOCUS_SELECTOR = [
|
|
6
|
+
'input',
|
|
7
|
+
'textarea',
|
|
8
|
+
'select',
|
|
9
|
+
'[contenteditable]:not([contenteditable="false"])',
|
|
10
|
+
'[role="textbox"]',
|
|
11
|
+
'[role="combobox"]',
|
|
12
|
+
].join(',');
|
|
13
|
+
|
|
14
|
+
const BLOCKING_OVERLAY_SELECTOR = [
|
|
15
|
+
'[role="dialog"]',
|
|
16
|
+
'[aria-modal="true"]',
|
|
17
|
+
// Some legacy Plannotator modals predate explicit dialog semantics. Keep
|
|
18
|
+
// Vim from focusing the obscured document underneath those full-screen
|
|
19
|
+
// overlays while they are brought onto the shared dialog primitive.
|
|
20
|
+
'.fixed.inset-0',
|
|
21
|
+
].join(',');
|
|
22
|
+
|
|
23
|
+
/** Inputs for restoring keyboard ownership to a Vim-enabled document. */
|
|
24
|
+
export interface UseVimDocumentFocusOptions {
|
|
25
|
+
readonly enabled: boolean;
|
|
26
|
+
readonly blocked: boolean;
|
|
27
|
+
/** Focus the owning document surface and report whether focus moved to it. */
|
|
28
|
+
readonly focusDocument: () => boolean;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function pageFocusIsNeutral(): boolean {
|
|
32
|
+
return document.activeElement === document.body || document.activeElement === null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function hasBlockingOverlay(): boolean {
|
|
36
|
+
return document.querySelector(BLOCKING_OVERLAY_SELECTOR) !== null;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function targetOwnsTextInput(target: EventTarget | null): boolean {
|
|
40
|
+
return target instanceof Element && target.closest(EDITABLE_FOCUS_SELECTOR) !== null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Ask the active Vim document to reclaim focus after an owned UI closes. */
|
|
44
|
+
export function requestVimDocumentFocus(): void {
|
|
45
|
+
document.dispatchEvent(new Event(VIM_DOCUMENT_FOCUS_REQUEST, { cancelable: true }));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Give an enabled Vim document initial keyboard ownership and let Escape from
|
|
50
|
+
* neutral app chrome return to it.
|
|
51
|
+
*
|
|
52
|
+
* Editable controls and overlays retain first ownership of Escape. The hook
|
|
53
|
+
* only prevents the event after focus actually moves back to the document.
|
|
54
|
+
*/
|
|
55
|
+
export function useVimDocumentFocus({
|
|
56
|
+
enabled,
|
|
57
|
+
blocked,
|
|
58
|
+
focusDocument,
|
|
59
|
+
}: UseVimDocumentFocusOptions): void {
|
|
60
|
+
const autoFocusAttemptedRef = useRef(false);
|
|
61
|
+
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
if (!enabled) {
|
|
64
|
+
autoFocusAttemptedRef.current = false;
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
if (autoFocusAttemptedRef.current) return;
|
|
68
|
+
autoFocusAttemptedRef.current = true;
|
|
69
|
+
if (blocked || !pageFocusIsNeutral() || hasBlockingOverlay()) return;
|
|
70
|
+
focusDocument();
|
|
71
|
+
}, [blocked, enabled, focusDocument]);
|
|
72
|
+
|
|
73
|
+
useEffect(() => {
|
|
74
|
+
if (!enabled) return;
|
|
75
|
+
|
|
76
|
+
const handleFocusRequest = (event: Event) => {
|
|
77
|
+
if (
|
|
78
|
+
!event.defaultPrevented
|
|
79
|
+
&& !blocked
|
|
80
|
+
&& !hasBlockingOverlay()
|
|
81
|
+
&& focusDocument()
|
|
82
|
+
) {
|
|
83
|
+
// One visible document owns each request when a host renders multiple
|
|
84
|
+
// Viewer instances.
|
|
85
|
+
event.preventDefault();
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
const handleEscape = (event: KeyboardEvent) => {
|
|
89
|
+
if (
|
|
90
|
+
event.key !== 'Escape'
|
|
91
|
+
|| event.defaultPrevented
|
|
92
|
+
|| event.isComposing
|
|
93
|
+
|| event.ctrlKey
|
|
94
|
+
|| event.metaKey
|
|
95
|
+
|| event.altKey
|
|
96
|
+
|| event.shiftKey
|
|
97
|
+
|| blocked
|
|
98
|
+
|| targetOwnsTextInput(event.target)
|
|
99
|
+
|| hasBlockingOverlay()
|
|
100
|
+
) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (focusDocument()) {
|
|
105
|
+
event.preventDefault();
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
document.addEventListener(VIM_DOCUMENT_FOCUS_REQUEST, handleFocusRequest);
|
|
110
|
+
document.addEventListener('keydown', handleEscape);
|
|
111
|
+
return () => {
|
|
112
|
+
document.removeEventListener(VIM_DOCUMENT_FOCUS_REQUEST, handleFocusRequest);
|
|
113
|
+
document.removeEventListener('keydown', handleEscape);
|
|
114
|
+
};
|
|
115
|
+
}, [blocked, enabled, focusDocument]);
|
|
116
|
+
}
|