feat: adjust iframe layout when editor panel opens
When editor panel tab-content is open, the preview iframe now scales down (0.7) and repositions with appropriate margins to provide optimal viewing alongside the editor panel. This creates a smooth transition between full-width preview and side-by-side editing mode. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
8e3eb83431
commit
55881739ac
2 changed files with 41 additions and 16 deletions
26
src/App.vue
26
src/App.vue
|
|
@ -2,7 +2,7 @@
|
||||||
import PagedJsWrapper from './components/PagedJsWrapper.vue';
|
import PagedJsWrapper from './components/PagedJsWrapper.vue';
|
||||||
import EditorPanel from './components/editor/EditorPanel.vue';
|
import EditorPanel from './components/editor/EditorPanel.vue';
|
||||||
import ElementPopup from './components/ElementPopup.vue';
|
import ElementPopup from './components/ElementPopup.vue';
|
||||||
import { onMounted, ref, watch, computed } from 'vue';
|
import { onMounted, ref, watch, computed, provide } from 'vue';
|
||||||
import { useStylesheetStore } from './stores/stylesheet';
|
import { useStylesheetStore } from './stores/stylesheet';
|
||||||
import Coloris from '@melloware/coloris';
|
import Coloris from '@melloware/coloris';
|
||||||
|
|
||||||
|
|
@ -10,6 +10,9 @@ const stylesheetStore = useStylesheetStore();
|
||||||
const previewFrame1 = ref(null);
|
const previewFrame1 = ref(null);
|
||||||
const previewFrame2 = ref(null);
|
const previewFrame2 = ref(null);
|
||||||
const elementPopup = ref(null);
|
const elementPopup = ref(null);
|
||||||
|
const activeTab = ref('');
|
||||||
|
|
||||||
|
provide('activeTab', activeTab);
|
||||||
|
|
||||||
let savedScrollPercentage = 0;
|
let savedScrollPercentage = 0;
|
||||||
const currentFrameIndex = ref(1); // 1 or 2, which iframe is currently visible
|
const currentFrameIndex = ref(1); // 1 or 2, which iframe is currently visible
|
||||||
|
|
@ -133,8 +136,16 @@ onMounted(() => renderPreview(true));
|
||||||
|
|
||||||
<EditorPanel />
|
<EditorPanel />
|
||||||
|
|
||||||
<iframe ref="previewFrame1" class="preview-frame"></iframe>
|
<iframe
|
||||||
<iframe ref="previewFrame2" class="preview-frame"></iframe>
|
ref="previewFrame1"
|
||||||
|
class="preview-frame"
|
||||||
|
:class="{ shifted: activeTab.length > 0 }"
|
||||||
|
></iframe>
|
||||||
|
<iframe
|
||||||
|
ref="previewFrame2"
|
||||||
|
class="preview-frame"
|
||||||
|
:class="{ shifted: activeTab.length > 0 }"
|
||||||
|
></iframe>
|
||||||
|
|
||||||
<ElementPopup ref="elementPopup" :iframeRef="activeFrame" />
|
<ElementPopup ref="elementPopup" :iframeRef="activeFrame" />
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -147,7 +158,14 @@ onMounted(() => renderPreview(true));
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
border: none;
|
border: none;
|
||||||
transition: opacity 0.1s ease-in-out;
|
transition: opacity 0.1s ease-in-out, margin-left ease-in-out var(--curve),
|
||||||
|
transform ease-in-out var(--curve), height ease-in-out var(--curve);
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-frame.shifted {
|
||||||
|
margin-left: 19rem;
|
||||||
|
transform: scale(0.7) translateY(-30vh);
|
||||||
|
height: 142vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
.preview-frame:nth-of-type(1) {
|
.preview-frame:nth-of-type(1) {
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
</button>
|
</button>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<div class="tab-content">
|
<div class="tab-content" :class="{ open: activeTab.length > 0 }">
|
||||||
<div v-if="activeTab === 'document'" class="tab-panel">
|
<div v-if="activeTab === 'document'" class="tab-panel">
|
||||||
<PageSettings />
|
<PageSettings />
|
||||||
<TextSettings />
|
<TextSettings />
|
||||||
|
|
@ -45,21 +45,16 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, provide } from 'vue';
|
import { inject } from 'vue';
|
||||||
import PageSettings from './PageSettings.vue';
|
import PageSettings from './PageSettings.vue';
|
||||||
import TextSettings from './TextSettings.vue';
|
import TextSettings from './TextSettings.vue';
|
||||||
import StylesheetViewer from '../StylesheetViewer.vue';
|
import StylesheetViewer from '../StylesheetViewer.vue';
|
||||||
|
|
||||||
// Tab management
|
const activeTab = inject('activeTab');
|
||||||
const activeTab = ref('document');
|
|
||||||
|
|
||||||
// Provide activeTab to child components
|
|
||||||
provide('activeTab', activeTab);
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
#editor-panel {
|
#editor-panel {
|
||||||
padding: 1rem;
|
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
|
|
@ -68,21 +63,33 @@ provide('activeTab', activeTab);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
|
|
||||||
background-color: var(--color-panel-bg);
|
|
||||||
box-shadow: -5px 0px 12px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nav {
|
nav {
|
||||||
margin-bottom: 2rem;
|
position: absolute;
|
||||||
|
margin: 1rem 0 0 1rem;
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
|
z-index: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-content {
|
.tab-content {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
left: -35rem;
|
||||||
|
|
||||||
|
padding: 4rem 1rem 1rem 1rem;
|
||||||
|
|
||||||
|
background-color: var(--color-panel-bg);
|
||||||
|
box-shadow: -5px 0px 12px;
|
||||||
|
|
||||||
|
transition: left ease-in-out var(--curve);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-content.open {
|
||||||
|
left: 0rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-panel {
|
.tab-panel {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue