@growgroup/visual-editor 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/NOTICE +52 -0
- package/README.md +143 -0
- package/dist/editor.css +2 -0
- package/package.json +94 -0
- package/src/components/DeckSlideRender.tsx +21 -0
- package/src/components/SaveNote.tsx +21 -0
- package/src/components/auth/AuthProvider.tsx +44 -0
- package/src/components/ui/accordion.tsx +57 -0
- package/src/components/ui/alert-dialog.tsx +141 -0
- package/src/components/ui/badge.tsx +36 -0
- package/src/components/ui/button.tsx +56 -0
- package/src/components/ui/card.tsx +76 -0
- package/src/components/ui/checkbox.tsx +30 -0
- package/src/components/ui/collapsible.tsx +11 -0
- package/src/components/ui/context-menu.tsx +200 -0
- package/src/components/ui/dialog.tsx +122 -0
- package/src/components/ui/dropdown-menu.tsx +201 -0
- package/src/components/ui/input.tsx +22 -0
- package/src/components/ui/label.tsx +26 -0
- package/src/components/ui/popover.tsx +33 -0
- package/src/components/ui/scroll-area.tsx +48 -0
- package/src/components/ui/scrubbable-label.tsx +95 -0
- package/src/components/ui/select.tsx +159 -0
- package/src/components/ui/separator.tsx +31 -0
- package/src/components/ui/slider.tsx +28 -0
- package/src/components/ui/switch.tsx +29 -0
- package/src/components/ui/tabs.tsx +55 -0
- package/src/components/ui/textarea.tsx +22 -0
- package/src/components/ui/tooltip.tsx +32 -0
- package/src/components/viewer/useDeck.ts +58 -0
- package/src/editor/EditorContext.tsx +632 -0
- package/src/editor/EditorToolbar.tsx +446 -0
- package/src/editor/FrontendVisualEditor.tsx +2595 -0
- package/src/editor/autosave.ts +34 -0
- package/src/editor/components/AiPromptPopover.tsx +378 -0
- package/src/editor/components/BreakpointGuides.tsx +323 -0
- package/src/editor/components/BreakpointSelector.tsx +180 -0
- package/src/editor/components/ComponentPropertyEditor.tsx +426 -0
- package/src/editor/components/CssEditorDialog.tsx +168 -0
- package/src/editor/components/EditorCanvas.tsx +987 -0
- package/src/editor/components/EditorContextMenu.tsx +515 -0
- package/src/editor/components/EditorFooter.tsx +81 -0
- package/src/editor/components/EditorHeader.tsx +524 -0
- package/src/editor/components/EditorLayerPanel.tsx +1197 -0
- package/src/editor/components/EditorPropertyPanel.tsx +2996 -0
- package/src/editor/components/EditorSidebar.tsx +226 -0
- package/src/editor/components/FigmaColorPicker.tsx +1577 -0
- package/src/editor/components/HtmlEditorDialog.tsx +71 -0
- package/src/editor/components/HtmlImportDialog.tsx +346 -0
- package/src/editor/components/JsEditorDialog.tsx +175 -0
- package/src/editor/components/LayerTreeItem.tsx +494 -0
- package/src/editor/components/MasterComponentEditor.tsx +846 -0
- package/src/editor/components/MediaLibraryDialog.tsx +447 -0
- package/src/editor/components/PageSettingsDialog.tsx +776 -0
- package/src/editor/components/VariablePicker.tsx +355 -0
- package/src/editor/components/VariablesDialog.tsx +564 -0
- package/src/editor/components/VariantEditor.tsx +687 -0
- package/src/editor/components/VariantMatrix.tsx +507 -0
- package/src/editor/components/component-panel/CategoryAccordion.tsx +139 -0
- package/src/editor/components/component-panel/ComponentGrid.tsx +51 -0
- package/src/editor/components/component-panel/ComponentItem.tsx +368 -0
- package/src/editor/components/component-panel/ComponentPanel.tsx +275 -0
- package/src/editor/components/component-panel/ComponentSearch.tsx +82 -0
- package/src/editor/components/component-panel/VariantList.tsx +260 -0
- package/src/editor/components/component-panel/index.ts +12 -0
- package/src/editor/components/index.ts +48 -0
- package/src/editor/components/multi-page/CanvasZoomControls.tsx +71 -0
- package/src/editor/components/multi-page/InfiniteCanvas.tsx +95 -0
- package/src/editor/components/multi-page/MultiPageCanvasView.tsx +1404 -0
- package/src/editor/components/multi-page/PageFrameOverlay.tsx +76 -0
- package/src/editor/components/multi-page/PageLabel.tsx +34 -0
- package/src/editor/components/multi-page/PageLivePreview.tsx +242 -0
- package/src/editor/components/multi-page/PageThumbnail.tsx +59 -0
- package/src/editor/components/multi-page/index.ts +7 -0
- package/src/editor/components/ppt/PptChrome.tsx +2508 -0
- package/src/editor/components/ppt/PptComments.tsx +589 -0
- package/src/editor/components/ppt/PptDesignProposals.tsx +275 -0
- package/src/editor/components/ppt/PptFormatPane.tsx +320 -0
- package/src/editor/components/ppt/PptNotes.tsx +246 -0
- package/src/editor/components/property-panel/AlignmentPanel.tsx +110 -0
- package/src/editor/components/property-panel/AutoLayoutPanel.tsx +615 -0
- package/src/editor/components/property-panel/BorderSection.tsx +104 -0
- package/src/editor/components/property-panel/CompactNumberInput.tsx +237 -0
- package/src/editor/components/property-panel/CompactSizeInput.tsx +148 -0
- package/src/editor/components/property-panel/EffectSection.tsx +157 -0
- package/src/editor/components/property-panel/FillSection.tsx +69 -0
- package/src/editor/components/property-panel/GoogleFontPicker.tsx +192 -0
- package/src/editor/components/property-panel/ImageSection.tsx +206 -0
- package/src/editor/components/property-panel/ImgSrcSection.tsx +125 -0
- package/src/editor/components/property-panel/InstanceOverrideSection.tsx +413 -0
- package/src/editor/components/property-panel/LayoutSection.tsx +105 -0
- package/src/editor/components/property-panel/LinkSection.tsx +103 -0
- package/src/editor/components/property-panel/PropertyVariablePicker.tsx +311 -0
- package/src/editor/components/property-panel/ScalePanel.tsx +212 -0
- package/src/editor/components/property-panel/TypographySection.tsx +230 -0
- package/src/editor/components/property-panel/UnitAwareNumberInput.tsx +238 -0
- package/src/editor/components/property-panel/VariableAwareColorInput.tsx +477 -0
- package/src/editor/components/property-panel/VariableAwareInput.tsx +606 -0
- package/src/editor/components/property-panel/VariableAwareSizeInput.tsx +588 -0
- package/src/editor/components/property-panel/VariableAwareUnitInput.tsx +546 -0
- package/src/editor/components/property-panel/index.ts +24 -0
- package/src/editor/components/property-panel/unit-utils.ts +261 -0
- package/src/editor/components/shell/EditorTopBar.tsx +392 -0
- package/src/editor/components/shell/LeftPanel.tsx +47 -0
- package/src/editor/components/shell/PagesPanel.tsx +118 -0
- package/src/editor/components/variables-panel/ColorValueCell.tsx +165 -0
- package/src/editor/components/variables-panel/TextValueCell.tsx +116 -0
- package/src/editor/components/variables-panel/VariablesPanel.tsx +518 -0
- package/src/editor/components/variables-panel/index.ts +7 -0
- package/src/editor/constants.ts +468 -0
- package/src/editor/contexts/EditorArtboardContext.tsx +229 -0
- package/src/editor/contexts/EditorComponentsContext.tsx +1320 -0
- package/src/editor/contexts/EditorDocumentContext.tsx +113 -0
- package/src/editor/contexts/EditorHistoryContext.tsx +516 -0
- package/src/editor/contexts/EditorRefsContext.tsx +204 -0
- package/src/editor/contexts/EditorSelectionContext.tsx +54 -0
- package/src/editor/contexts/EditorToolContext.tsx +58 -0
- package/src/editor/contexts/EditorUIStateContext.tsx +122 -0
- package/src/editor/contexts/EditorVariablesContext.tsx +397 -0
- package/src/editor/contexts/EditorViewContext.tsx +101 -0
- package/src/editor/contexts/MultiPageCanvasContext.tsx +498 -0
- package/src/editor/contexts/index.ts +17 -0
- package/src/editor/editor-skin.css +122 -0
- package/src/editor/hooks/index.ts +38 -0
- package/src/editor/hooks/useAiReplace.ts +397 -0
- package/src/editor/hooks/useAltMeasure.ts +67 -0
- package/src/editor/hooks/useBrowserZoomPrevention.ts +121 -0
- package/src/editor/hooks/useCanvasControls.ts +1222 -0
- package/src/editor/hooks/useComponentEditMode.ts +658 -0
- package/src/editor/hooks/useComponentInstances.ts +515 -0
- package/src/editor/hooks/useContextMenuHandler.ts +157 -0
- package/src/editor/hooks/useCoordinateTransform.ts +207 -0
- package/src/editor/hooks/useDragResize.ts +1317 -0
- package/src/editor/hooks/useDrawingMode.ts +472 -0
- package/src/editor/hooks/useEditorColors.ts +144 -0
- package/src/editor/hooks/useEditorMessages.ts +108 -0
- package/src/editor/hooks/useElementActions.ts +1754 -0
- package/src/editor/hooks/useElementSelection.ts +1573 -0
- package/src/editor/hooks/useFocusManagement.ts +249 -0
- package/src/editor/hooks/useGoogleFonts.ts +305 -0
- package/src/editor/hooks/useIframeInitializer.ts +584 -0
- package/src/editor/hooks/useIframeSetup.ts +360 -0
- package/src/editor/hooks/useImageUpload.ts +270 -0
- package/src/editor/hooks/useInfiniteCanvas.ts +301 -0
- package/src/editor/hooks/useKeyboardShortcuts.ts +205 -0
- package/src/editor/hooks/useMarqueeSelection.ts +388 -0
- package/src/editor/hooks/useMediaLibrary.ts +129 -0
- package/src/editor/hooks/usePageSettingsManager.ts +739 -0
- package/src/editor/hooks/useResizablePanel.ts +163 -0
- package/src/editor/hooks/useRichPaste.ts +255 -0
- package/src/editor/hooks/useTouchGestures.ts +197 -0
- package/src/editor/index.ts +27 -0
- package/src/editor/types/page-settings.ts +513 -0
- package/src/editor/types.ts +382 -0
- package/src/editor/utils/align-elements.ts +169 -0
- package/src/editor/utils/api-json.ts +21 -0
- package/src/editor/utils/aspect-lock.ts +50 -0
- package/src/editor/utils/component-renderer.ts +702 -0
- package/src/editor/utils/component-sync.ts +845 -0
- package/src/editor/utils/crop-mode.ts +265 -0
- package/src/editor/utils/dom-utils.ts +2238 -0
- package/src/editor/utils/element-effects.ts +218 -0
- package/src/editor/utils/eyedropper.ts +35 -0
- package/src/editor/utils/figma-export.ts +560 -0
- package/src/editor/utils/figma-kiwi-decoder.ts +722 -0
- package/src/editor/utils/figma-kiwi-encoder.ts +583 -0
- package/src/editor/utils/figma-paste.ts +2262 -0
- package/src/editor/utils/flex-reorder.ts +231 -0
- package/src/editor/utils/flex-utils.ts +1230 -0
- package/src/editor/utils/geometry.ts +232 -0
- package/src/editor/utils/grid-layout.ts +210 -0
- package/src/editor/utils/html-utils.ts +470 -0
- package/src/editor/utils/index.ts +11 -0
- package/src/editor/utils/ink-style.ts +57 -0
- package/src/editor/utils/inline-format.ts +236 -0
- package/src/editor/utils/measure-distance.ts +120 -0
- package/src/editor/utils/override-apply.ts +526 -0
- package/src/editor/utils/override-detection.ts +613 -0
- package/src/editor/utils/paste-processors.ts +609 -0
- package/src/editor/utils/paste-sanitizer.ts +244 -0
- package/src/editor/utils/restore-flow.ts +188 -0
- package/src/editor/utils/shape-library.ts +171 -0
- package/src/editor/utils/slide-root.ts +29 -0
- package/src/editor/utils/smart-guides.ts +218 -0
- package/src/editor/utils/style-utils.ts +685 -0
- package/src/editor/utils/table-edit.ts +151 -0
- package/src/editor/utils/tailwind-mappings.ts +778 -0
- package/src/editor/utils/tailwind-utils.ts +804 -0
- package/src/editor/utils/text-highlight.ts +216 -0
- package/src/editor/utils/theme-to-variables.ts +341 -0
- package/src/editor/utils/variant-resolver.ts +456 -0
- package/src/editor/utils/viewport-utils.ts +295 -0
- package/src/hooks/useEditorHistory.ts +195 -0
- package/src/hooks/useEditorShortcuts.ts +260 -0
- package/src/index.ts +40 -0
- package/src/io.ts +134 -0
- package/src/lib/agent/slide-agent/types.ts +547 -0
- package/src/lib/agent/website-agent/types.ts +805 -0
- package/src/lib/api/auth-fetch.ts +58 -0
- package/src/lib/deck.ts +69 -0
- package/src/lib/export.ts +47 -0
- package/src/lib/firebase/config.ts +29 -0
- package/src/lib/firebase/css-variables.ts +378 -0
- package/src/lib/firebase/editor-components.ts +677 -0
- package/src/lib/firebase/storage.ts +469 -0
- package/src/lib/utils.ts +6 -0
- package/src/styles/editor.css +52 -0
- package/src/styles/skin.css +122 -0
- package/src/types/css-variables.ts +645 -0
- package/src/types/editor-components.ts +944 -0
- package/src/types/editor.ts +420 -0
- package/src/types/page-master.ts +197 -0
- package/src/types/page.ts +419 -0
- package/src/types/slide.ts +402 -0
- package/src/types/website-theme.ts +788 -0
- package/src/types/website.ts +374 -0
- package/src/vendor/firebase-firestore.ts +13 -0
- package/src/vendor/firebase-functions.ts +17 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 表(<table>)の行・列の挿入と削除。
|
|
3
|
+
*
|
|
4
|
+
* 右クリックしたセルを起点に、そのセルの見た目(style / class)を写して増やす。
|
|
5
|
+
* PowerPointの「行を上に挿入」等と同じ操作面を、素のHTMLの表に対して行う。
|
|
6
|
+
*
|
|
7
|
+
* 【対応範囲】rowspan / colspan は考慮しない(挿入した表は常に矩形)。
|
|
8
|
+
* 崩れた表に対しては、行ごとにセル数が違っても落ちないよう index を丸めて扱う。
|
|
9
|
+
*
|
|
10
|
+
* 【なぜ data-shape-type を見ないか】
|
|
11
|
+
* 保存時に data-shape-type は取り除かれる(html-utils.ts の getCleanHtml)。
|
|
12
|
+
* 一度保存して開き直した表でも同じように編集できるよう、判定は <table> の有無で行う。
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* 右クリック位置などから表のセルを取り出す(表の外なら null)。
|
|
17
|
+
*
|
|
18
|
+
* ここで instanceof を使わないのは、対象が iframe の中の要素だから。
|
|
19
|
+
* iframe は別realmなので、親ページの HTMLTableCellElement とは別のコンストラクタになり、
|
|
20
|
+
* `el instanceof Element` すら常に false になる。タグ名で見るのが唯一確実。
|
|
21
|
+
*/
|
|
22
|
+
export function findTableCell(el: EventTarget | Element | null): HTMLTableCellElement | null {
|
|
23
|
+
const node = el as Element | null;
|
|
24
|
+
if (!node || typeof node.closest !== 'function') return null;
|
|
25
|
+
const cell = node.closest('td,th') as HTMLTableCellElement | null;
|
|
26
|
+
return cell && cell.closest('table') ? cell : null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** セルが属する表 */
|
|
30
|
+
function tableOf(cell: HTMLTableCellElement): HTMLTableElement | null {
|
|
31
|
+
return cell.closest('table');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** その行が置かれているセクション(thead / tbody / tfoot) */
|
|
35
|
+
function sectionOf(row: HTMLTableRowElement): HTMLTableSectionElement | null {
|
|
36
|
+
const p = row.parentElement;
|
|
37
|
+
return p && ['THEAD', 'TBODY', 'TFOOT'].includes(p.tagName)
|
|
38
|
+
? (p as HTMLTableSectionElement)
|
|
39
|
+
: null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** セクションに応じたセルのタグ。見出し行は th、本文行は td */
|
|
43
|
+
function cellTagFor(section: HTMLTableSectionElement | null): 'th' | 'td' {
|
|
44
|
+
return section?.tagName === 'THEAD' ? 'th' : 'td';
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** 見た目(style / class)だけ写した空セルを作る */
|
|
48
|
+
function makeCell(ref: HTMLTableCellElement, tag: 'th' | 'td'): HTMLTableCellElement {
|
|
49
|
+
const cell = ref.ownerDocument.createElement(tag) as HTMLTableCellElement;
|
|
50
|
+
const style = ref.getAttribute('style');
|
|
51
|
+
if (style) cell.setAttribute('style', style);
|
|
52
|
+
if (ref.className) cell.className = ref.className;
|
|
53
|
+
cell.textContent = '';
|
|
54
|
+
return cell;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** 行 row の中で、列 index に相当するセル(短い行なら末尾で丸める) */
|
|
58
|
+
function cellAt(row: HTMLTableRowElement, index: number): HTMLTableCellElement | null {
|
|
59
|
+
if (!row.cells.length) return null;
|
|
60
|
+
return row.cells[Math.min(index, row.cells.length - 1)];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** 列数(先頭行の基準。rowspan/colspanは見ない) */
|
|
64
|
+
function columnCount(table: HTMLTableElement): number {
|
|
65
|
+
return table.rows.length ? table.rows[0].cells.length : 0;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* 行を挿入する。戻り値は挿入した行(できなければ null)。
|
|
70
|
+
*
|
|
71
|
+
* 見出し行の「下に挿入」だけは本文側の先頭へ入れる。見出しが2行になるのは
|
|
72
|
+
* まず意図と違うため(PowerPointでも見出しの下は本文行になる)。
|
|
73
|
+
*/
|
|
74
|
+
export function insertRow(cell: HTMLTableCellElement, where: 'above' | 'below'): HTMLTableRowElement | null {
|
|
75
|
+
const table = tableOf(cell);
|
|
76
|
+
const row = cell.parentElement as HTMLTableRowElement | null;
|
|
77
|
+
if (!table || row?.tagName !== 'TR') return null;
|
|
78
|
+
|
|
79
|
+
const doc = table.ownerDocument;
|
|
80
|
+
let section = sectionOf(row);
|
|
81
|
+
let before: Node | null = where === 'above' ? row : row.nextSibling;
|
|
82
|
+
|
|
83
|
+
if (where === 'below' && section?.tagName === 'THEAD' && !row.nextElementSibling) {
|
|
84
|
+
// 見出しの最終行の下 = 本文の先頭
|
|
85
|
+
let body = table.tBodies[0] as HTMLTableSectionElement | undefined;
|
|
86
|
+
if (!body) {
|
|
87
|
+
body = doc.createElement('tbody');
|
|
88
|
+
table.appendChild(body);
|
|
89
|
+
}
|
|
90
|
+
section = body;
|
|
91
|
+
before = body.firstChild;
|
|
92
|
+
}
|
|
93
|
+
if (!section) return null;
|
|
94
|
+
|
|
95
|
+
// 見た目の雛形は挿入先セクションの既存行(無ければ元の行)
|
|
96
|
+
const template = section.rows[0] ?? row;
|
|
97
|
+
const tag = cellTagFor(section);
|
|
98
|
+
const width = columnCount(table) || row.cells.length;
|
|
99
|
+
|
|
100
|
+
const newRow = doc.createElement('tr');
|
|
101
|
+
for (let i = 0; i < width; i++) {
|
|
102
|
+
const ref = cellAt(template, i) ?? cellAt(row, i);
|
|
103
|
+
if (ref) newRow.appendChild(makeCell(ref, tag));
|
|
104
|
+
}
|
|
105
|
+
if (!newRow.cells.length) return null;
|
|
106
|
+
|
|
107
|
+
section.insertBefore(newRow, before);
|
|
108
|
+
return newRow;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** 列を挿入する。表の全行(見出し含む)に1セルずつ足す。戻り値は挿入できたか */
|
|
112
|
+
export function insertColumn(cell: HTMLTableCellElement, where: 'left' | 'right'): boolean {
|
|
113
|
+
const table = tableOf(cell);
|
|
114
|
+
if (!table || !table.rows.length) return false;
|
|
115
|
+
|
|
116
|
+
const index = cell.cellIndex;
|
|
117
|
+
for (const row of Array.from(table.rows)) {
|
|
118
|
+
const ref = cellAt(row, index);
|
|
119
|
+
if (!ref) continue;
|
|
120
|
+
const tag = cellTagFor(sectionOf(row));
|
|
121
|
+
row.insertBefore(makeCell(ref, tag), where === 'left' ? ref : ref.nextSibling);
|
|
122
|
+
}
|
|
123
|
+
return true;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/** 行を削除する。最後の1行は消さない(空の表を作らない)。戻り値は削除できたか */
|
|
127
|
+
export function deleteRow(cell: HTMLTableCellElement): boolean {
|
|
128
|
+
const table = tableOf(cell);
|
|
129
|
+
const row = cell.parentElement as HTMLTableRowElement | null;
|
|
130
|
+
if (!table || row?.tagName !== 'TR') return false;
|
|
131
|
+
if (table.rows.length <= 1) return false;
|
|
132
|
+
|
|
133
|
+
const section = sectionOf(row);
|
|
134
|
+
row.remove();
|
|
135
|
+
// 空になった thead / tbody は畳む(保存後のHTMLに空タグを残さない)
|
|
136
|
+
if (section && !section.rows.length) section.remove();
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/** 列を削除する。最後の1列は消さない。戻り値は削除できたか */
|
|
141
|
+
export function deleteColumn(cell: HTMLTableCellElement): boolean {
|
|
142
|
+
const table = tableOf(cell);
|
|
143
|
+
if (!table || columnCount(table) <= 1) return false;
|
|
144
|
+
|
|
145
|
+
const index = cell.cellIndex;
|
|
146
|
+
for (const row of Array.from(table.rows)) {
|
|
147
|
+
if (row.cells.length <= 1) continue;
|
|
148
|
+
cellAt(row, index)?.remove();
|
|
149
|
+
}
|
|
150
|
+
return true;
|
|
151
|
+
}
|