diff --git a/components/admin/AdminMarkdownPreview.vue b/components/admin/AdminMarkdownPreview.vue new file mode 100644 index 0000000..aa27b6c --- /dev/null +++ b/components/admin/AdminMarkdownPreview.vue @@ -0,0 +1,152 @@ + + + diff --git a/components/admin/AdminPostForm.vue b/components/admin/AdminPostForm.vue index d5332e5..a1f1462 100644 --- a/components/admin/AdminPostForm.vue +++ b/components/admin/AdminPostForm.vue @@ -17,6 +17,8 @@ const props = defineProps({ const emit = defineEmits(['submit']) const slugTouched = ref(Boolean(props.initialPost.slug)) +const editorMode = ref('write') +const contentTextarea = ref(null) const form = reactive({ title: props.initialPost.title || '', @@ -66,6 +68,77 @@ const parseTags = (value) => [...new Set(value .map((tag) => toSlug(tag)) .filter(Boolean))] +/** + * 본문 선택 영역에 마크다운 문법 삽입 + * @param {string} before - 선택 영역 앞에 넣을 문자열 + * @param {string} after - 선택 영역 뒤에 넣을 문자열 + * @param {string} fallback - 선택 영역이 없을 때 넣을 문자열 + * @returns {void} + */ +const insertMarkdown = (before, after = '', fallback = '') => { + const textarea = contentTextarea.value + + if (!textarea) { + form.content += fallback || before + return + } + + const start = textarea.selectionStart + const end = textarea.selectionEnd + const selectedText = form.content.slice(start, end) + const insertText = selectedText + ? `${before}${selectedText}${after}` + : (fallback || `${before}${after}`) + + form.content = `${form.content.slice(0, start)}${insertText}${form.content.slice(end)}` + + nextTick(() => { + textarea.focus() + const cursor = start + insertText.length + textarea.setSelectionRange(cursor, cursor) + }) +} + +/** + * 제목 문법 삽입 + * @returns {void} + */ +const insertHeading = () => { + insertMarkdown('## ', '', '## 제목') +} + +/** + * 굵게 문법 삽입 + * @returns {void} + */ +const insertBold = () => { + insertMarkdown('**', '**', '**강조**') +} + +/** + * 목록 문법 삽입 + * @returns {void} + */ +const insertList = () => { + insertMarkdown('- ', '', '- 목록') +} + +/** + * 인용 문법 삽입 + * @returns {void} + */ +const insertQuote = () => { + insertMarkdown('> ', '', '> 인용') +} + +/** + * 코드 블록 문법 삽입 + * @returns {void} + */ +const insertCodeBlock = () => { + insertMarkdown('```\n', '\n```', '```\n코드\n```') +} + /** * 게시물 입력값 제출 * @returns {void} @@ -102,14 +175,57 @@ const submitPost = () => { > -