From 2f9ef0d0a236146b40835cf266eaec789ac34e89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=B3=B4=EA=B3=A4?= Date: Sat, 7 Mar 2026 23:19:16 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20[planning-design]=20=EC=8A=A4=ED=86=A0?= =?UTF-8?q?=EB=A6=AC=EB=B3=B4=EB=93=9C=20=EB=B8=94=EB=A1=9D=20=ED=8E=B8?= =?UTF-8?q?=EC=A7=91=EA=B8=B0=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 노션 스타일 블록 기반 화면 설계 편집기 - 15종 블록: 제목(H1/H2), 텍스트, 테이블, 콜아웃, 체크리스트, 코드, 버튼, 입력필드, 셀렉트, 카드, 뱃지, 이미지, 구분선 - 드래그 앤 드롭 블록 순서 변경 - 블록 복제, 위/아래 이동, 삭제 지원 - HTML 내보내기에 블록 렌더링 반영 --- .../views/rd/planning-design/index.blade.php | 573 ++++++++++++++++-- 1 file changed, 533 insertions(+), 40 deletions(-) diff --git a/resources/views/rd/planning-design/index.blade.php b/resources/views/rd/planning-design/index.blade.php index 89e01318..e999d9c4 100644 --- a/resources/views/rd/planning-design/index.blade.php +++ b/resources/views/rd/planning-design/index.blade.php @@ -621,6 +621,121 @@ } .sb-desc-remove:hover { color: #ef4444; background: #fef2f2; } +/* Block Editor (Wireframe) */ +.sb-block-toolbar { + display: flex; align-items: center; gap: 4px; padding: 6px 12px; + border-bottom: 1px solid #e2e8f0; background: #fafbfc; flex-wrap: wrap; +} +.sb-block-toolbar-btn { + padding: 3px 8px; border: 1px solid #e2e8f0; border-radius: 5px; + font-size: 10px; cursor: pointer; background: #fff; color: #475569; + display: flex; align-items: center; gap: 3px; white-space: nowrap; + transition: all .12s; +} +.sb-block-toolbar-btn:hover { border-color: var(--pc-indigo); color: var(--pc-indigo); background: #eef2ff; } +.sb-block-toolbar-sep { width: 1px; height: 18px; background: #e2e8f0; margin: 0 2px; } +.sb-blocks-area { flex: 1; padding: 16px; overflow-y: auto; min-height: 300px; } +.sb-block { + position: relative; border: 1.5px solid transparent; border-radius: 6px; + margin-bottom: 2px; padding: 0; transition: border-color .12s; + group: true; +} +.sb-block:hover { border-color: #c7d2fe; } +.sb-block.selected { border-color: var(--pc-indigo); background: #fafafe; } +.sb-block-handle { + position: absolute; left: -22px; top: 50%; transform: translateY(-50%); + width: 18px; height: 18px; display: flex; align-items: center; justify-content: center; + color: #cbd5e1; cursor: grab; font-size: 12px; opacity: 0; transition: opacity .12s; + user-select: none; +} +.sb-block:hover .sb-block-handle { opacity: 1; } +.sb-block-handle:active { cursor: grabbing; color: #6366f1; } +.sb-block-actions { + position: absolute; right: 4px; top: 4px; display: flex; gap: 2px; + opacity: 0; transition: opacity .12s; +} +.sb-block:hover .sb-block-actions { opacity: 1; } +.sb-block-action-btn { + width: 20px; height: 20px; border: none; background: #f1f5f9; color: #94a3b8; + border-radius: 4px; cursor: pointer; font-size: 11px; display: flex; + align-items: center; justify-content: center; +} +.sb-block-action-btn:hover { background: #e2e8f0; color: #475569; } +.sb-block-action-btn.danger:hover { background: #fef2f2; color: #ef4444; } +.sb-block-drop-indicator { + height: 3px; background: var(--pc-indigo); border-radius: 2px; margin: -2px 0; + transition: opacity .12s; opacity: 0; +} +.sb-block-drop-indicator.active { opacity: 1; } + +/* Block type styles */ +.sb-blk-text { padding: 6px 8px; font-size: 13px; line-height: 1.7; min-height: 24px; outline: none; color: #334155; } +.sb-blk-text:empty::before { content: attr(data-placeholder); color: #cbd5e1; } +.sb-blk-heading { padding: 8px 8px 4px; font-size: 18px; font-weight: 700; line-height: 1.4; outline: none; color: #1e293b; } +.sb-blk-heading:empty::before { content: '제목을 입력하세요'; color: #cbd5e1; } +.sb-blk-h2 { font-size: 15px; font-weight: 600; } +.sb-blk-divider { border: none; border-top: 1px solid #e2e8f0; margin: 8px 0; } +.sb-blk-callout { + display: flex; gap: 8px; padding: 10px 12px; background: #eff6ff; + border-radius: 6px; border-left: 3px solid #3b82f6; +} +.sb-blk-callout-icon { font-size: 16px; flex-shrink: 0; } +.sb-blk-callout-text { flex: 1; font-size: 12px; line-height: 1.6; outline: none; color: #334155; } +.sb-blk-callout-text:empty::before { content: '콜아웃 내용을 입력하세요'; color: #93c5fd; } +.sb-blk-table-wrap { overflow-x: auto; padding: 4px; } +.sb-blk-table { width: 100%; border-collapse: collapse; font-size: 12px; } +.sb-blk-table th { background: #f1f5f9; font-weight: 600; color: #475569; text-align: left; } +.sb-blk-table th, .sb-blk-table td { + border: 1px solid #e2e8f0; padding: 6px 8px; min-width: 60px; outline: none; +} +.sb-blk-table td:focus { background: #f8fafc; } +.sb-blk-mockup { padding: 8px; } +.sb-blk-mockup-label { font-size: 9px; color: #94a3b8; font-weight: 600; text-transform: uppercase; margin-bottom: 4px; } +.sb-blk-mock-btn { + display: inline-block; padding: 6px 16px; border-radius: 6px; font-size: 12px; + font-weight: 600; cursor: default; +} +.sb-blk-mock-input { + width: 100%; padding: 7px 10px; border: 1px solid #d1d5db; border-radius: 6px; + font-size: 12px; color: #6b7280; background: #f9fafb; +} +.sb-blk-mock-select { + padding: 7px 10px; border: 1px solid #d1d5db; border-radius: 6px; + font-size: 12px; color: #6b7280; background: #f9fafb; +} +.sb-blk-mock-card { + border: 1px solid #e2e8f0; border-radius: 8px; padding: 12px; background: #fff; +} +.sb-blk-mock-card-title { font-size: 13px; font-weight: 600; color: #1e293b; margin-bottom: 4px; outline: none; } +.sb-blk-mock-card-body { font-size: 11px; color: #64748b; line-height: 1.5; outline: none; } +.sb-blk-image-wrap { text-align: center; } +.sb-blk-image-wrap img { max-width: 100%; border-radius: 6px; } +.sb-blk-image-placeholder { + border: 2px dashed #d1d5db; border-radius: 6px; padding: 24px; + color: #94a3b8; font-size: 12px; cursor: pointer; text-align: center; +} +.sb-blk-image-placeholder:hover { border-color: var(--pc-indigo); } +.sb-blk-todo { display: flex; align-items: flex-start; gap: 6px; padding: 4px 8px; } +.sb-blk-todo input[type=checkbox] { margin-top: 4px; accent-color: var(--pc-indigo); } +.sb-blk-todo-text { flex: 1; font-size: 12px; outline: none; line-height: 1.6; } +.sb-blk-todo-text:empty::before { content: '할 일을 입력하세요'; color: #cbd5e1; } +.sb-blk-badge-row { display: flex; gap: 6px; flex-wrap: wrap; padding: 4px 8px; } +.sb-blk-badge { + padding: 3px 10px; border-radius: 12px; font-size: 10px; font-weight: 600; +} +.sb-blk-code { + padding: 10px 12px; background: #1e293b; border-radius: 6px; color: #e2e8f0; + font-family: 'Fira Code', monospace; font-size: 12px; line-height: 1.6; + outline: none; white-space: pre-wrap; +} +.sb-blk-code:empty::before { content: '코드를 입력하세요'; color: #64748b; } +.sb-blk-empty-area { + border: 2px dashed #e2e8f0; border-radius: 8px; min-height: 200px; + display: flex; flex-direction: column; align-items: center; justify-content: center; + color: #94a3b8; font-size: 12px; gap: 8px; cursor: pointer; transition: all .15s; +} +.sb-blk-empty-area:hover { border-color: var(--pc-indigo); background: #fafafe; } + /* Menu Tree Editor Modal */ .sb-menu-modal-overlay { position: fixed; inset: 0; z-index: 9999; background: rgba(0,0,0,0.4); @@ -1223,38 +1338,235 @@ {{-- Content + Description --}}
- {{-- Wireframe Area --}} -
-