UNPKG

@jager-ai/holy-editor

Version:

Rich text editor with Bible verse slash commands and PWA keyboard tracking, extracted from Holy Habit project

589 lines (456 loc) 15.4 kB
# @mvp-factory/holy-editor 성경 구절 통합 및 PWA 지원을 갖춘 리치 텍스트 에디터 ## 주요 기능 - 📖 **성경 구절 슬래시 명령어**: `/갈2:20`, `/3:16-17` 형식으로 성경 구절 자동 삽입 - ✏️ **리치 텍스트 편집**: Bold, Underline, Heading, Quote, Color 포맷팅 - 📱 **PWA 최적화**: 모바일 키보드 추적 및 UI 조정 - 🎨 **컬러 피커**: 8색 팔레트로 텍스트 색상 변경 - 🔔 **알림 시스템**: 사용자 피드백을 위한 토스트 메시지 - 💾 **자동 저장**: localStorage를 통한 주기적 내용 저장 및 복원 - 🚀 **TypeScript 지원**: 완전한 타입 정의 - 📦 **모듈화 설계**: 개별 컴포넌트 독립적 사용 가능 ## 🚀 빠른 시작 ### 설치 ```bash npm install @mvp-factory/holy-editor ``` ### 기본 사용법 ```html <!-- HTML --> <div id="myEditor" contenteditable="true"></div> ``` ```typescript // TypeScript/JavaScript import { HolyEditor } from '@mvp-factory/holy-editor'; const editor = new HolyEditor('myEditor', { enableBibleVerses: true, enableTextFormatting: true, enablePWAKeyboard: true, enableAutoSave: true, apiEndpoint: '/api/bible_verse_full.php' }); editor.initialize(); ``` ### CSS 스타일 (기본) ```css .holy-editor { min-height: 200px; padding: 16px; border: 1px solid #ddd; border-radius: 8px; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; line-height: 1.6; } .bible-verse { background: #f8f9fa; border-left: 4px solid #007bff; padding: 12px 16px; margin: 16px 0; border-radius: 4px; } .verse-reference { display: block; margin-top: 8px; font-size: 0.9em; color: #666; font-style: normal; } ``` ## 📖 성경 구절 기능 ### 슬래시 명령어 에디터에서 다음 형식으로 입력하면 자동으로 성경 구절이 삽입됩니다: ``` /2:20 갈라디아서 220/3:16 요한복음 316/23:1-3 시편 231-3절 (범위 구절) /1:1 창세기 11절 ``` ### 지원하는 성경책 (66권) **구약 39**: 창, 출, 레, 민, 신, 수, 삿, 룻, 삼상, 삼하, 왕상, 왕하, 대상, 대하, 스, 느, 에, 욥, 시, 잠, 전, 아, 사, 렘, 애, 겔, 단, 호, 욜, 암, 옵, 욘, 미, 나, 합, 습, 학, 슥, 말 **신약 27**: 마, 막, 눅, 요, 행, 롬, 고전, 고후, 갈, 엡, 빌, 골, 살전, 살후, 딤전, 딤후, 딛, 몬, 히, 약, 벧전, 벧후, 요일, 요이, 요삼, 유, 계 ### 프로그래밍 방식으로 구절 삽입 ```typescript // 특정 구절 삽입 await editor.insertVerse('갈2:20'); // 범위 구절 삽입 await editor.insertVerse('시23:1-6'); // 성공/실패 확인 const success = await editor.insertVerse('요3:16'); if (success) { console.log('구절이 성공적으로 삽입되었습니다'); } ``` ## ✏️ 텍스트 포맷팅 ### 키보드 단축키 - `Ctrl+B` / `Cmd+B`: **굵게** - `Ctrl+U` / `Cmd+U`: <u>밑줄</u> - `Ctrl+H` / `Cmd+H`: # 제목 - `Ctrl+Q` / `Cmd+Q`: > 인용구 ### 프로그래밍 방식 포맷팅 ```typescript // 포맷 토글 editor.toggleFormat('bold'); editor.toggleFormat('underline'); editor.toggleFormat('heading1'); editor.toggleFormat('quote'); // 텍스트 색상 적용 editor.applyTextColor('#ff0000'); // 컬러 피커 표시 editor.showColorPicker(); // 현재 포맷 상태 확인 const formatState = editor.getFormatState(); console.log(formatState?.bold); // true/false ``` ## 💾 자동 저장 기능 내용을 주기적으로 localStorage에 자동 저장하고, 에디터 재시작 시 복원할 수 있습니다. ### 기본 설정 ```typescript const editor = new HolyEditor('myEditor', { enableAutoSave: true, // 자동 저장 활성화 (기본: true) autoSaveInterval: 30000, // 저장 주기 (기본: 30초) autoSaveKey: 'my-custom-key' // 커스텀 저장 키 (선택사항) }); ``` ### 수동 제어 ```typescript // 즉시 저장 const saved = editor.saveContent(); if (saved) { console.log('내용이 저장되었습니다'); } // 저장된 내용 확인 if (editor.hasSavedContent()) { const info = editor.getAutoSaveInfo(); console.log('마지막 저장:', new Date(info.lastSave)); } // 저장된 내용 삭제 editor.clearSavedContent(); // 자동 저장 토글 editor.toggleAutoSave(false); // 비활성화 editor.toggleAutoSave(true); // 활성화 // 저장 주기 변경 (60초로) editor.updateAutoSaveInterval(60000); ``` ### 복원 동작 에디터 초기화 시 저장된 내용이 있으면 사용자에게 복원 여부를 확인합니다: ```text "이전에 작성하던 내용이 있습니다 (5분 전). 복원하시겠습니까?" [확인] [취소] ``` ### 모든 에디터의 저장 내용 관리 ```typescript import { AutoSaveManager } from '@mvp-factory/holy-editor'; // 저장된 모든 에디터 ID 확인 const savedEditors = AutoSaveManager.getAllSavedEditors(); console.log('저장된 에디터:', savedEditors); // 모든 저장 내용 삭제 const cleared = AutoSaveManager.clearAll(); console.log(`${cleared}개의 에디터 저장 내용을 삭제했습니다`); ``` ## 📱 PWA 지원 모바일 환경에서 가상 키보드가 나타날 때 자동으로 UI를 조정합니다. ```typescript const editor = new HolyEditor('myEditor', { enablePWAKeyboard: true, keyboardSettings: { threshold: 10, // 감지 임계값 (px) keyboardMin: 150, // 최소 키보드 높이 (px) debounceTime: 0 // 디바운스 시간 (ms) } }); ``` ### PWA 환경 감지 ```typescript import { PWAKeyboardTracker } from '@mvp-factory/holy-editor'; const tracker = new PWAKeyboardTracker(); const env = tracker.getEnvironmentInfo(); console.log('PWA 환경:', env.isPWA); console.log('iOS 기기:', env.isIOS); console.log('Android 기기:', env.isAndroid); console.log('Visual Viewport API 지원:', env.hasVisualViewport); ``` ## ⚙️ 설정 옵션 ```typescript interface EditorConfig { // 기능 활성화/비활성화 enableBibleVerses?: boolean; // 성경 구절 기능 (기본: true) enableTextFormatting?: boolean; // 텍스트 포맷팅 (기본: true) enablePWAKeyboard?: boolean; // PWA 키보드 추적 (기본: true) enableColorPicker?: boolean; // 컬러 피커 (기본: true) enableAutoSave?: boolean; // 자동 저장 (기본: true) // API 설정 apiEndpoint?: string; // 성경 API 엔드포인트 debounceMs?: number; // 입력 디바운스 시간 (기본: 300ms) // 자동 저장 설정 autoSaveInterval?: number; // 자동 저장 주기 (기본: 30000ms) autoSaveKey?: string; // localStorage 키 (기본: 'holy-editor-autosave-{editorId}') // PWA 키보드 설정 keyboardSettings?: { threshold?: number; // 감지 임계값 (기본: 10px) keyboardMin?: number; // 최소 키보드 높이 (기본: 150px) debounceTime?: number; // 디바운스 시간 (기본: 0ms) }; } ``` ## 🎨 스타일링 가이드 ### CSS 클래스 에디터에서 사용하는 주요 CSS 클래스들: ```css /* 에디터 본체 */ .holy-editor { /* 기본 에디터 스타일 */ } .holy-editor-focused { /* 포커스 상태 */ } /* 성경 구절 */ .bible-verse { /* 단일 구절 */ } .bible-verse-range { /* 범위 구절 */ } .verse-text { /* 구절 텍스트 */ } .verse-reference { /* 구절 참조 */ } /* 포맷팅 */ .inline-quote { /* 인라인 인용구 */ } /* 알림 */ .holy-toast { /* 토스트 메시지 */ } .holy-toast-success { /* 성공 메시지 */ } .holy-toast-error { /* 오류 메시지 */ } /* 컬러 피커 */ .holy-color-picker { /* 컬러 피커 다이얼로그 */ } /* PWA */ .keyboard-active { /* 키보드 활성화 상태 */ } .keyboard-tracking { /* 키보드 추적 중 */ } ``` ### 테마 커스터마이징 ```css /* 다크 테마 예시 */ .holy-editor.dark-theme { background-color: #1a1a1a; color: #ffffff; border-color: #444; } .dark-theme .bible-verse { background-color: #2d2d2d; border-left-color: #0d7377; } .dark-theme .verse-reference { color: #aaa; } ``` ## 🔧 API 참조 ### HolyEditor 클래스 #### 생성자 ```typescript new HolyEditor(editorId: string, config?: Partial<EditorConfig>) ``` #### 메서드 ```typescript // 초기화 및 해제 initialize(): void // 에디터 초기화 destroy(): void // 에디터 해제 및 정리 // 내용 관리 getContent(): string // HTML 내용 가져오기 setContent(html: string): void // HTML 내용 설정 getTextContent(): string // 텍스트만 가져오기 clear(): void // 내용 지우기 // 포커스 관리 focus(): void // 에디터 포커스 isFocused(): boolean // 포커스 상태 확인 // 포맷팅 toggleFormat(action: FormatAction): void // 포맷 토글 applyTextColor(color: string): void // 색상 적용 showColorPicker(): void // 컬러 피커 표시 getFormatState(): FormatState | null // 현재 포맷 상태 // 성경 구절 insertVerse(ref: string): Promise<boolean> // 구절 삽입 // 자동 저장 saveContent(): boolean // 즉시 저장 clearSavedContent(): boolean // 저장 내용 삭제 hasSavedContent(): boolean // 저장 내용 존재 여부 getAutoSaveInfo(): object // 자동 저장 정보 updateAutoSaveInterval(ms: number): void // 저장 주기 변경 toggleAutoSave(enable?: boolean): void // 자동 저장 토글 ``` ### 개별 컴포넌트 사용 ```typescript import { BibleVerseEngine, TextFormatter, PWAKeyboardTracker, ToastManager, ColorPicker, AutoSaveManager } from '@mvp-factory/holy-editor'; // 성경 구절 엔진만 사용 const bibleEngine = BibleVerseEngine.getInstance(); const isValid = bibleEngine.isValidBibleRef('갈2:20'); const verseData = await bibleEngine.loadVerse('갈2:20'); // 토스트 메시지만 사용 const toast = ToastManager.getInstance(); toast.success('성공적으로 저장되었습니다'); toast.error('오류가 발생했습니다'); // 컬러 피커만 사용 const colorPicker = ColorPicker.getInstance(); colorPicker.show((color) => { console.log('Selected color:', color); }); // 자동 저장 관리만 사용 const autoSave = new AutoSaveManager('myEditor', { interval: 60000, // 1분마다 저장 onSave: (data) => console.log('저장됨:', data), onError: (error) => console.error('저장 실패:', error) }); // 에디터 내용 가져오기 함수 const getContent = () => document.getElementById('myEditor').innerHTML; // 자동 저장 시작 autoSave.start(getContent); // 나중에 중지 autoSave.stop(); ``` ## 🚀 고급 사용법 ### 커스텀 성경 API 연동 ```typescript const editor = new HolyEditor('myEditor', { apiEndpoint: 'https://api.mybible.com/verse', debounceMs: 500 }); // API 응답 형식 interface BibleApiResponse { success: boolean; verses: Array<{ book: string; chapter: number; verse: number; text: string; }>; } ``` ### 이벤트 리스너 ```typescript const editorElement = document.getElementById('myEditor'); // 포맷 상태 변경 이벤트 editorElement?.addEventListener('holyeditor:formatstatechange', (event) => { const formatState = event.detail; updateToolbarButtons(formatState); }); // 커스텀 이벤트 리스너 함수 function updateToolbarButtons(formatState: FormatState) { document.getElementById('boldBtn')?.classList.toggle('active', formatState.bold); document.getElementById('underlineBtn')?.classList.toggle('active', formatState.underline); // ... } ``` ### 툴바 통합 예시 ```html <div class="editor-toolbar"> <button id="boldBtn" onclick="editor.toggleFormat('bold')">굵게</button> <button id="underlineBtn" onclick="editor.toggleFormat('underline')">밑줄</button> <button id="headingBtn" onclick="editor.toggleFormat('heading1')">제목</button> <button id="quoteBtn" onclick="editor.toggleFormat('quote')">인용</button> <button id="colorBtn" onclick="editor.showColorPicker()">색상</button> </div> <div id="myEditor" contenteditable="true"></div> ``` ```css .editor-toolbar { display: flex; gap: 8px; margin-bottom: 8px; padding: 8px; border-bottom: 1px solid #ddd; } .editor-toolbar button { padding: 8px 12px; border: 1px solid #ddd; background: white; border-radius: 4px; cursor: pointer; } .editor-toolbar button.active { background: #007bff; color: white; } ``` ## 🛠️ 개발 환경 설정 ### 타입스크립트 프로젝트에서 사용 ```json // tsconfig.json { "compilerOptions": { "target": "ES2020", "lib": ["DOM", "DOM.Iterable", "ES2020"], "module": "ESNext", "moduleResolution": "node", "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true } } ``` ### 번들러 설정 (Webpack/Vite) ```javascript // vite.config.js export default { optimizeDeps: { include: ['@mvp-factory/holy-editor'] } } ``` ## 🐛 문제 해결 ### 일반적인 문제들 **1. 성경 구절이 로드되지 않는 경우** ```typescript // API 엔드포인트 확인 const editor = new HolyEditor('myEditor', { apiEndpoint: '/your-api-endpoint.php' // 올바른 엔드포인트 설정 }); // 네트워크 탭에서 API 응답 확인 // CORS 설정 확인 ``` **2. PWA에서 키보드 추적이 작동하지 않는 경우** ```typescript // Visual Viewport API 지원 확인 const tracker = new PWAKeyboardTracker(); console.log('Visual Viewport 지원:', tracker.hasVisualViewport()); // 매뉴얼 업데이트 tracker.forceUpdate(); ``` **3. 스타일이 적용되지 않는 경우** ```css /* CSS 우선순위 확인 */ .holy-editor { /* !important 사용 시 주의 */ } /* 또는 더 구체적인 선택자 사용 */ #myEditor.holy-editor { /* 스타일 */ } ``` **4. 자동 저장이 작동하지 않는 경우** ```typescript // localStorage 사용 가능 여부 확인 try { localStorage.setItem('test', 'test'); localStorage.removeItem('test'); console.log('localStorage 사용 가능'); } catch (e) { console.error('localStorage 사용 불가:', e); } // 저장 용량 확인 const info = editor.getAutoSaveInfo(); if (!info.isRunning) { console.log('자동 저장이 비활성화되어 있습니다'); } ``` ## 📄 라이센스 MIT License ## 🤝 기여하기 1. 이 저장소를 Fork 하세요 2. 새로운 기능 브랜치를 생성하세요 (`git checkout -b feature/AmazingFeature`) 3. 변경 사항을 커밋하세요 (`git commit -m 'Add some AmazingFeature'`) 4. 브랜치에 Push 하세요 (`git push origin feature/AmazingFeature`) 5. Pull Request를 열어주세요 ## 📞 지원 - GitHub Issues: [이슈 생성](https://github.com/mvp-factory/holy-editor/issues) - 문서: [전체 문서 보기](https://docs.mvp-factory.com/holy-editor) --- **@mvp-factory/holy-editor** - 성경 중심 리치 텍스트 에디터 🙏