refactor: integrate StylesheetViewer into EditorPanel code tab

Move StylesheetViewer from standalone fixed panel to integrated component
within EditorPanel's "code" tab. Maintains full functionality including:
- Bidirectional sync with Pinia store and PagedJS preview
- Toggle between read/edit modes
- CSS syntax highlighting
- Debounced updates

Changes:
- EditorPanel.vue: Import and render StylesheetViewer in code tab
- EditorPanel.vue: Add flexbox layout for proper height management
- StylesheetViewer.vue: Convert from fixed positioning to flex container
- App.vue: Remove standalone StylesheetViewer component

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
isUnknown 2025-12-04 13:34:33 +01:00
parent 19077fb133
commit 7ed57d000b
3 changed files with 49 additions and 46 deletions

View file

@ -1,7 +1,6 @@
<script setup> <script setup>
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 StylesheetViewer from './components/StylesheetViewer.vue';
import ElementPopup from './components/ElementPopup.vue'; import ElementPopup from './components/ElementPopup.vue';
import { onMounted, ref, watch } from 'vue'; import { onMounted, ref, watch } from 'vue';
import { useStylesheetStore } from './stores/stylesheet'; import { useStylesheetStore } from './stores/stylesheet';
@ -42,7 +41,10 @@ const renderPreview = async (shouldReloadFromFile = false) => {
`; `;
iframe.onload = () => { iframe.onload = () => {
iframe.contentDocument.addEventListener('click', elementPopup.value.handleIframeClick); iframe.contentDocument.addEventListener(
'click',
elementPopup.value.handleIframeClick
);
setTimeout(() => { setTimeout(() => {
const scrollHeight = iframe.contentDocument.documentElement.scrollHeight; const scrollHeight = iframe.contentDocument.documentElement.scrollHeight;
@ -55,9 +57,12 @@ const renderPreview = async (shouldReloadFromFile = false) => {
}; };
}; };
watch(() => stylesheetStore.content, () => { watch(
renderPreview(); () => stylesheetStore.content,
}); () => {
renderPreview();
}
);
onMounted(() => renderPreview(true)); onMounted(() => renderPreview(true));
</script> </script>
@ -71,8 +76,6 @@ onMounted(() => renderPreview(true));
<iframe ref="previewFrame" id="preview-frame"></iframe> <iframe ref="previewFrame" id="preview-frame"></iframe>
<StylesheetViewer :stylesheet="stylesheetStore.content" />
<ElementPopup ref="elementPopup" :iframeRef="previewFrame" /> <ElementPopup ref="elementPopup" :iframeRef="previewFrame" />
</template> </template>
@ -80,8 +83,8 @@ onMounted(() => renderPreview(true));
#preview-frame { #preview-frame {
position: fixed; position: fixed;
top: 0; top: 0;
left: 250px; left: 0;
width: calc(100% - 600px); width: 100vw;
height: 100vh; height: 100vh;
border: none; border: none;
} }

View file

@ -1,5 +1,5 @@
<template> <template>
<aside id="stylesheet-viewer"> <div id="stylesheet-viewer">
<div class="header"> <div class="header">
<h3>Stylesheet</h3> <h3>Stylesheet</h3>
<label class="toggle"> <label class="toggle">
@ -17,7 +17,7 @@
@input="handleInput" @input="handleInput"
spellcheck="false" spellcheck="false"
></textarea> ></textarea>
</aside> </div>
</template> </template>
<script setup> <script setup>
@ -53,14 +53,9 @@ const handleInput = (event) => {
<style scoped> <style scoped>
#stylesheet-viewer { #stylesheet-viewer {
position: fixed; display: flex;
top: 0; flex-direction: column;
right: 0; height: 100%;
width: 350px;
height: 100vh;
padding: 1rem;
box-shadow: -2px 0 8px rgba(0, 0, 0, 0.1);
overflow-y: auto;
background: #282c34; background: #282c34;
color: #fff; color: #fff;
} }
@ -130,7 +125,7 @@ h3 {
.readonly { .readonly {
margin: 0; margin: 0;
height: calc(100vh - 5rem); flex: 1;
overflow-y: auto; overflow-y: auto;
padding: 0.5rem; padding: 0.5rem;
background: #1e1e1e; background: #1e1e1e;
@ -145,7 +140,7 @@ h3 {
textarea { textarea {
width: 100%; width: 100%;
height: calc(100vh - 5rem); flex: 1;
background: #1e1e1e; background: #1e1e1e;
color: #abb2bf; color: #abb2bf;
border: none; border: none;

View file

@ -3,6 +3,7 @@
<nav class="tabs"> <nav class="tabs">
<button <button
type="button" type="button"
class="tab"
:class="{ active: activeTab === 'document' }" :class="{ active: activeTab === 'document' }"
@click="activeTab = 'document'" @click="activeTab = 'document'"
> >
@ -10,6 +11,7 @@
</button> </button>
<button <button
type="button" type="button"
class="tab"
:class="{ active: activeTab === 'code' }" :class="{ active: activeTab === 'code' }"
@click="activeTab = 'code'" @click="activeTab = 'code'"
> >
@ -17,6 +19,7 @@
</button> </button>
<button <button
type="button" type="button"
class="tab"
:class="{ active: activeTab === 'contenu' }" :class="{ active: activeTab === 'contenu' }"
@click="activeTab = 'contenu'" @click="activeTab = 'contenu'"
> >
@ -31,7 +34,7 @@
</div> </div>
<div v-else-if="activeTab === 'code'" class="tab-panel"> <div v-else-if="activeTab === 'code'" class="tab-panel">
<!-- Code tab content --> <StylesheetViewer />
</div> </div>
<div v-else-if="activeTab === 'contenu'" class="tab-panel"> <div v-else-if="activeTab === 'contenu'" class="tab-panel">
@ -45,40 +48,42 @@
import { ref } from 'vue'; import { ref } 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';
// Tab management // Tab management
const activeTab = ref('document'); const activeTab = ref('document');
</script> </script>
<style scoped> <style lang="scss" scoped>
#editor-panel { #editor-panel {
padding: 1rem;
position: fixed; position: fixed;
top: 0; top: 0;
left: 0; left: 0;
width: 250px; width: 25rem;
height: 100vh; height: 100vh;
background: #f5f5f5; display: flex;
padding: 1rem; flex-direction: column;
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.1); z-index: 2;
background-color: var(--color-panel-bg);
box-shadow: -5px 0px 12px;
}
nav {
margin-bottom: 2rem;
display: flex;
gap: 0.5rem;
}
.tab-content {
flex: 1;
overflow: hidden;
}
.tab-panel {
height: 100%;
overflow-y: auto; overflow-y: auto;
} }
h3 {
margin-top: 0;
}
.control {
margin-bottom: 1rem;
}
.control label {
display: block;
margin-bottom: 0.25rem;
font-size: 0.875rem;
}
.control input {
width: 80px;
padding: 0.25rem;
}
</style> </style>