고정 페이지 HTML 문서 모드 추가 v1.5.1

This commit is contained in:
2026-05-26 11:03:33 +09:00
parent 0ad2ab3f9d
commit a25306389b
15 changed files with 169 additions and 14 deletions

View File

@@ -18,6 +18,7 @@ const emit = defineEmits(['submit'])
const slugTouched = ref(Boolean(props.initialPage.slug))
const blockEditor = ref(null)
const htmlEditor = ref(null)
const mediaItems = ref([])
const isMediaPickerOpen = ref(false)
const isLoadingMedia = ref(false)
@@ -26,6 +27,7 @@ const isUploadingFeaturedImage = ref(false)
const form = reactive({
title: props.initialPage.title || '',
slug: props.initialPage.slug || '',
renderMode: props.initialPage.renderMode || 'markdown',
content: props.initialPage.content || '',
featuredImage: props.initialPage.featuredImage || ''
})
@@ -140,9 +142,23 @@ const uploadFeaturedImage = async (event) => {
* @returns {void}
*/
const focusContentEditor = () => {
if (form.renderMode === 'html_document') {
htmlEditor.value?.focus()
return
}
blockEditor.value?.focusFirstBlock()
}
/**
* 페이지 작성 모드를 변경한다.
* @param {'markdown'|'html_document'} mode - 페이지 작성 모드
* @returns {void}
*/
const setRenderMode = (mode) => {
form.renderMode = mode
}
/**
* 페이지 입력값 제출
* @returns {void}
@@ -151,6 +167,7 @@ const submitPage = () => {
emit('submit', {
title: form.title.trim(),
slug: toSlug(form.slug || form.title),
renderMode: form.renderMode,
content: form.content,
featuredImage: form.featuredImage.trim() || null
})
@@ -170,12 +187,58 @@ const submitPage = () => {
@keydown.enter.prevent="focusContentEditor"
>
<div class="admin-page-form__field grid gap-2 text-sm">
<div v-if="form.renderMode === 'markdown'" class="admin-page-form__field grid gap-2 text-sm">
<AdminBlockEditor ref="blockEditor" v-model="form.content" />
</div>
<label v-else class="admin-page-form__field admin-page-form__html-field grid gap-2 text-sm">
<span class="admin-page-form__label font-medium">HTML 문서</span>
<textarea
ref="htmlEditor"
v-model="form.content"
class="admin-page-form__html-editor min-h-[68vh] resize-y rounded border border-line bg-[#15171a] px-4 py-4 font-mono text-sm leading-6 text-white outline-none placeholder:text-white/35 focus:border-[#8e9cac]"
spellcheck="false"
placeholder="<!doctype html>
<html lang=&quot;ko&quot;>
<head>
<meta charset=&quot;utf-8&quot;>
<title>Landing</title>
<style>
body { margin: 0; }
</style>
</head>
<body>
</body>
</html>"
/>
<span class="admin-page-form__hint text-xs text-muted">
모드는 공개 URL에서 저장한 HTML을 그대로 응답합니다.
</span>
</label>
</section>
<aside class="admin-page-form__settings grid content-start gap-4">
<div class="admin-page-form__field grid gap-2 text-sm">
<span class="admin-page-form__label font-medium">페이지 형식</span>
<div class="admin-page-form__mode-control grid grid-cols-2 rounded border border-line bg-white p-1">
<button
class="admin-page-form__mode-button rounded px-3 py-2 text-sm font-semibold transition"
:class="form.renderMode === 'markdown' ? 'bg-[#15171a] text-white' : 'text-muted hover:bg-surface hover:text-ink'"
type="button"
@click="setRenderMode('markdown')"
>
기본
</button>
<button
class="admin-page-form__mode-button rounded px-3 py-2 text-sm font-semibold transition"
:class="form.renderMode === 'html_document' ? 'bg-[#15171a] text-white' : 'text-muted hover:bg-surface hover:text-ink'"
type="button"
@click="setRenderMode('html_document')"
>
HTML
</button>
</div>
</div>
<label class="admin-page-form__field grid gap-2 text-sm">
<span class="admin-page-form__label font-medium">슬러그</span>
<input