diff --git a/src/App.vue b/src/App.vue index 63fc895..efd64cb 100644 --- a/src/App.vue +++ b/src/App.vue @@ -5,7 +5,7 @@ import ElementPopup from './components/ElementPopup.vue'; import PagePopup from './components/PagePopup.vue'; import PreviewLoader from './components/PreviewLoader.vue'; import SaveButton from './components/SaveButton.vue'; -import { onMounted, ref, watch, computed, provide } from 'vue'; +import { onMounted, onUnmounted, ref, watch, computed, provide } from 'vue'; import { useStylesheetStore } from './stores/stylesheet'; import { useNarrativeStore } from './stores/narrative'; import Coloris from '@melloware/coloris'; @@ -38,6 +38,19 @@ const activeFrame = computed(() => { : previewFrame2.value; }); +// Handle keyboard shortcuts (Cmd/Ctrl+S for save) +const handleKeyboardShortcut = (event) => { + // Check for Cmd+S (Mac) or Ctrl+S (Windows/Linux) + 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(); + } + } +}; + // Check if mouse position is near the edges of a page element const isNearPageEdge = (pageElement, mouseX, mouseY) => { const rect = pageElement.getBoundingClientRect(); @@ -436,6 +449,9 @@ const renderPreview = async (shouldReloadFromFile = false) => { ); hiddenFrame.contentDocument.addEventListener('click', handleIframeClick); + // Add keyboard shortcut listener to iframe (for when focus is inside iframe) + hiddenFrame.contentDocument.addEventListener('keydown', handleKeyboardShortcut); + // Close Coloris when clicking in the iframe hiddenFrame.contentDocument.addEventListener('click', () => { Coloris.close(); @@ -563,9 +579,17 @@ onMounted(async () => { await stylesheetStore.initializeFromNarrative(narrativeStore.data); } + // Add keyboard shortcut listener to document (for when focus is outside iframe) + document.addEventListener('keydown', handleKeyboardShortcut); + // Render preview after data is loaded renderPreview(true); }); + +onUnmounted(() => { + // Clean up keyboard shortcut listener + document.removeEventListener('keydown', handleKeyboardShortcut); +});