refactor: extract App.vue logic into composables (762→230 lines)
All checks were successful
Deploy / Build and Deploy to Production (push) Successful in 14s
All checks were successful
Deploy / Build and Deploy to Production (push) Successful in 14s
Extracted complex logic from App.vue into focused, reusable composables: New composables: - useKeyboardShortcuts.js (~80 lines): Keyboard shortcuts (Cmd/Ctrl+S, P, Escape, \) - useIframeInteractions.js (~370 lines): Page/element hover, labels, clicks, popups - usePreviewRenderer.js (~160 lines): Double buffering, transitions, scroll persistence - usePrintPreview.js (~70 lines): Print dialog and style collection Benefits: - 70% reduction in App.vue size (532 lines extracted) - Better separation of concerns - Improved maintainability and testability - Clearer code organization Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
dac532a932
commit
be7bb66e70
5 changed files with 729 additions and 581 deletions
81
src/composables/useKeyboardShortcuts.js
Normal file
81
src/composables/useKeyboardShortcuts.js
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
import { onMounted, onUnmounted } from 'vue';
|
||||
|
||||
/**
|
||||
* Composable for managing global keyboard shortcuts
|
||||
* Handles Cmd/Ctrl+S (save), Cmd/Ctrl+P (print), Escape (close popups), \ (toggle panel)
|
||||
*/
|
||||
export function useKeyboardShortcuts({
|
||||
stylesheetStore,
|
||||
elementPopup,
|
||||
pagePopup,
|
||||
activeTab,
|
||||
printPreview
|
||||
}) {
|
||||
// Detect platform for keyboard shortcut display
|
||||
const isMac = typeof navigator !== 'undefined' && navigator.platform.toUpperCase().indexOf('MAC') >= 0;
|
||||
|
||||
// Handle keyboard shortcuts
|
||||
const handleKeyboardShortcut = (event) => {
|
||||
// Escape key - close any open popup
|
||||
if (event.key === 'Escape') {
|
||||
if (elementPopup.value?.visible) {
|
||||
elementPopup.value.close();
|
||||
return;
|
||||
}
|
||||
if (pagePopup.value?.visible) {
|
||||
pagePopup.value.close();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Backslash key - toggle editor panel
|
||||
if (event.key === '\\') {
|
||||
event.preventDefault();
|
||||
// Toggle: if panel is closed, open to 'document' tab; if open, close it
|
||||
activeTab.value = activeTab.value.length > 0 ? '' : 'document';
|
||||
return;
|
||||
}
|
||||
|
||||
// Cmd+P (Mac) or Ctrl+P (Windows/Linux) - print
|
||||
if ((event.metaKey || event.ctrlKey) && event.key === 'p') {
|
||||
event.preventDefault();
|
||||
printPreview();
|
||||
return;
|
||||
}
|
||||
|
||||
// Cmd+S (Mac) or Ctrl+S (Windows/Linux) - save
|
||||
if ((event.metaKey || event.ctrlKey) && event.key === 's') {
|
||||
event.preventDefault();
|
||||
|
||||
// Only save if there are changes and not currently saving
|
||||
if (stylesheetStore.isDirty && !stylesheetStore.isSaving) {
|
||||
stylesheetStore.saveCustomCss();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Attach keyboard listener to iframe document
|
||||
const attachToIframe = (iframe) => {
|
||||
if (iframe && iframe.contentDocument) {
|
||||
iframe.contentDocument.addEventListener('keydown', handleKeyboardShortcut);
|
||||
}
|
||||
};
|
||||
|
||||
// Setup keyboard listeners on mount
|
||||
onMounted(() => {
|
||||
// Add keyboard shortcut listener to document (for when focus is outside iframe)
|
||||
document.addEventListener('keydown', handleKeyboardShortcut);
|
||||
});
|
||||
|
||||
// Cleanup on unmount
|
||||
onUnmounted(() => {
|
||||
// Clean up keyboard shortcut listener
|
||||
document.removeEventListener('keydown', handleKeyboardShortcut);
|
||||
});
|
||||
|
||||
return {
|
||||
handleKeyboardShortcut,
|
||||
attachToIframe,
|
||||
isMac
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue