torch-glare 1.2.8 → 1.3.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/apps/lib/components/TableDnDWrapper.ts +495 -0
- package/apps/lib/components/TextEditor.tsx +53 -1
- package/dist/bin/index.js +5 -0
- package/dist/bin/index.js.map +1 -1
- package/dist/src/commands/mcp.d.ts +2 -0
- package/dist/src/commands/mcp.d.ts.map +1 -0
- package/dist/src/commands/mcp.js +91 -0
- package/dist/src/commands/mcp.js.map +1 -0
- package/dist/src/shared/configureFonts.d.ts +6 -0
- package/dist/src/shared/configureFonts.d.ts.map +1 -0
- package/dist/src/shared/configureFonts.js +106 -0
- package/dist/src/shared/configureFonts.js.map +1 -0
- package/dist/src/shared/configureGlobalCss.d.ts +6 -0
- package/dist/src/shared/configureGlobalCss.d.ts.map +1 -0
- package/dist/src/shared/configureGlobalCss.js +154 -0
- package/dist/src/shared/configureGlobalCss.js.map +1 -0
- package/dist/src/shared/configureTailwind.d.ts +7 -0
- package/dist/src/shared/configureTailwind.d.ts.map +1 -0
- package/dist/src/shared/configureTailwind.js +163 -0
- package/dist/src/shared/configureTailwind.js.map +1 -0
- package/dist/src/shared/detectFramework.d.ts +23 -0
- package/dist/src/shared/detectFramework.d.ts.map +1 -0
- package/dist/src/shared/detectFramework.js +119 -0
- package/dist/src/shared/detectFramework.js.map +1 -0
- package/dist/src/shared/getDependenciesAndInstallNestedComponents.d.ts.map +1 -1
- package/dist/src/shared/getDependenciesAndInstallNestedComponents.js +18 -2
- package/dist/src/shared/getDependenciesAndInstallNestedComponents.js.map +1 -1
- package/dist/src/shared/installBaseUtils.d.ts +5 -0
- package/dist/src/shared/installBaseUtils.d.ts.map +1 -0
- package/dist/src/shared/installBaseUtils.js +79 -0
- package/dist/src/shared/installBaseUtils.js.map +1 -0
- package/dist/src/shared/resolveAliases.d.ts +24 -0
- package/dist/src/shared/resolveAliases.d.ts.map +1 -0
- package/dist/src/shared/resolveAliases.js +98 -0
- package/dist/src/shared/resolveAliases.js.map +1 -0
- package/docs/components/breadcrumb.md +955 -0
- package/docs/components/button-group.md +647 -0
- package/docs/components/text-editor.md +711 -0
- package/docs/components/toggle-button.md +640 -0
- package/docs/tutorials/getting-started.md +123 -431
- package/package.json +1 -1
|
@@ -0,0 +1,495 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TableDnDWrapper
|
|
3
|
+
*
|
|
4
|
+
* Wraps @editorjs/table and adds drag-and-drop reordering for rows
|
|
5
|
+
* and columns by hijacking the existing .tc-toolbox toggler elements.
|
|
6
|
+
*
|
|
7
|
+
* - Click the toggler → opens the original popover menu (unchanged)
|
|
8
|
+
* - Drag the toggler → reorders the row/column (new behavior)
|
|
9
|
+
*
|
|
10
|
+
* No extra UI elements are injected — we reuse what the table plugin
|
|
11
|
+
* already renders.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
15
|
+
type TableClass = any;
|
|
16
|
+
|
|
17
|
+
const DRAG_THRESHOLD = 5; // px before a pointerdown becomes a drag
|
|
18
|
+
|
|
19
|
+
interface DragState {
|
|
20
|
+
active: boolean;
|
|
21
|
+
pending: boolean; // pointerdown happened but haven't passed threshold
|
|
22
|
+
type: "row" | "col" | null;
|
|
23
|
+
index: number;
|
|
24
|
+
dropIndex: number;
|
|
25
|
+
pointerId: number;
|
|
26
|
+
startX: number;
|
|
27
|
+
startY: number;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export default function createTableDnDClass(
|
|
31
|
+
OriginalTable: TableClass,
|
|
32
|
+
): TableClass {
|
|
33
|
+
return class TableDnD extends OriginalTable {
|
|
34
|
+
private _drag: DragState = {
|
|
35
|
+
active: false,
|
|
36
|
+
pending: false,
|
|
37
|
+
type: null,
|
|
38
|
+
index: -1,
|
|
39
|
+
dropIndex: -1,
|
|
40
|
+
pointerId: -1,
|
|
41
|
+
startX: 0,
|
|
42
|
+
startY: 0,
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
private _indicator: HTMLDivElement | null = null;
|
|
46
|
+
private _wrapperRef: HTMLElement | null = null;
|
|
47
|
+
private _onMoveBound = this._onPointerMove.bind(this);
|
|
48
|
+
private _onUpBound = this._onPointerUp.bind(this);
|
|
49
|
+
private _mutationObs: MutationObserver | null = null;
|
|
50
|
+
private _rafId: number | null = null;
|
|
51
|
+
private _attachedTogglers = new WeakSet<HTMLElement>();
|
|
52
|
+
|
|
53
|
+
// ─── Lifecycle ──────────────────────────────────────────────────────
|
|
54
|
+
|
|
55
|
+
render(): HTMLElement {
|
|
56
|
+
const wrapper: HTMLElement = super.render();
|
|
57
|
+
this._wrapperRef = wrapper;
|
|
58
|
+
|
|
59
|
+
if (this.readOnly) return wrapper;
|
|
60
|
+
|
|
61
|
+
this._waitForLayout(wrapper, () => this._setup(wrapper));
|
|
62
|
+
return wrapper;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
destroy(): void {
|
|
66
|
+
this._teardown();
|
|
67
|
+
if (super.destroy) super.destroy();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// ─── Wait for DOM ───────────────────────────────────────────────────
|
|
71
|
+
|
|
72
|
+
private _waitForLayout(el: HTMLElement, cb: () => void): void {
|
|
73
|
+
const check = () => {
|
|
74
|
+
if (el.offsetHeight > 0 && el.querySelector(".tc-row")) {
|
|
75
|
+
cb();
|
|
76
|
+
} else {
|
|
77
|
+
this._rafId = requestAnimationFrame(check);
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
this._rafId = requestAnimationFrame(check);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// ─── Setup ──────────────────────────────────────────────────────────
|
|
84
|
+
|
|
85
|
+
private _setup(wrapper: HTMLElement): void {
|
|
86
|
+
wrapper.classList.add("tc-dnd-wrap");
|
|
87
|
+
|
|
88
|
+
// Drop indicator
|
|
89
|
+
this._indicator = document.createElement("div");
|
|
90
|
+
this._indicator.className = "tc-dnd__indicator";
|
|
91
|
+
wrapper.appendChild(this._indicator);
|
|
92
|
+
|
|
93
|
+
// Attach to existing togglers
|
|
94
|
+
this._attachTogglers(wrapper);
|
|
95
|
+
|
|
96
|
+
// Re-attach when DOM changes (new rows/cols might create new togglers)
|
|
97
|
+
this._mutationObs = new MutationObserver(() => {
|
|
98
|
+
this._attachTogglers(wrapper);
|
|
99
|
+
});
|
|
100
|
+
this._mutationObs.observe(wrapper, { childList: true, subtree: true });
|
|
101
|
+
|
|
102
|
+
// Proximity-based toolbox visibility:
|
|
103
|
+
// Only show row handle near left edge, column handle near top edge
|
|
104
|
+
wrapper.addEventListener("mousemove", (e) =>
|
|
105
|
+
this._onWrapperMouseMove(e),
|
|
106
|
+
);
|
|
107
|
+
wrapper.addEventListener("mouseleave", () => {
|
|
108
|
+
wrapper.classList.remove("tc-dnd--show-row", "tc-dnd--show-col");
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// ─── Attach to .tc-toolbox__toggler elements ────────────────────────
|
|
113
|
+
|
|
114
|
+
private _attachTogglers(wrapper: HTMLElement): void {
|
|
115
|
+
// Row toolbox toggler
|
|
116
|
+
const rowToolbox = wrapper.querySelector<HTMLElement>(
|
|
117
|
+
".tc-toolbox--row .tc-toolbox__toggler",
|
|
118
|
+
);
|
|
119
|
+
if (rowToolbox && !this._attachedTogglers.has(rowToolbox)) {
|
|
120
|
+
this._attachedTogglers.add(rowToolbox);
|
|
121
|
+
rowToolbox.style.cursor = "grab";
|
|
122
|
+
rowToolbox.addEventListener("pointerdown", (e) => {
|
|
123
|
+
this._onTogglerDown("row", wrapper, e);
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Column toolbox toggler
|
|
128
|
+
const colToolbox = wrapper.querySelector<HTMLElement>(
|
|
129
|
+
".tc-toolbox--column .tc-toolbox__toggler",
|
|
130
|
+
);
|
|
131
|
+
if (colToolbox && !this._attachedTogglers.has(colToolbox)) {
|
|
132
|
+
this._attachedTogglers.add(colToolbox);
|
|
133
|
+
colToolbox.style.cursor = "grab";
|
|
134
|
+
colToolbox.addEventListener("pointerdown", (e) => {
|
|
135
|
+
this._onTogglerDown("col", wrapper, e);
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// ─── Proximity-based toolbox visibility ──────────────────────────────
|
|
141
|
+
|
|
142
|
+
private _onWrapperMouseMove(e: MouseEvent): void {
|
|
143
|
+
const tableEl =
|
|
144
|
+
this._wrapperRef?.querySelector<HTMLElement>(".tc-table");
|
|
145
|
+
if (!tableEl || !this._wrapperRef) return;
|
|
146
|
+
|
|
147
|
+
const tableRect = tableEl.getBoundingClientRect();
|
|
148
|
+
const distFromLeft = e.clientX - tableRect.left;
|
|
149
|
+
const distFromTop = e.clientY - tableRect.top;
|
|
150
|
+
|
|
151
|
+
const LEFT_THRESHOLD = 50;
|
|
152
|
+
const TOP_THRESHOLD = 35;
|
|
153
|
+
|
|
154
|
+
const nearLeft = distFromLeft <= LEFT_THRESHOLD && distFromLeft >= -30;
|
|
155
|
+
const nearTop = distFromTop <= TOP_THRESHOLD && distFromTop >= -25;
|
|
156
|
+
|
|
157
|
+
if (nearLeft && nearTop) {
|
|
158
|
+
// Corner: pick the proportionally closer edge
|
|
159
|
+
const leftRatio = Math.abs(distFromLeft) / LEFT_THRESHOLD;
|
|
160
|
+
const topRatio = Math.abs(distFromTop) / TOP_THRESHOLD;
|
|
161
|
+
if (leftRatio < topRatio) {
|
|
162
|
+
this._wrapperRef.classList.add("tc-dnd--show-row");
|
|
163
|
+
this._wrapperRef.classList.remove("tc-dnd--show-col");
|
|
164
|
+
} else {
|
|
165
|
+
this._wrapperRef.classList.add("tc-dnd--show-col");
|
|
166
|
+
this._wrapperRef.classList.remove("tc-dnd--show-row");
|
|
167
|
+
}
|
|
168
|
+
} else if (nearLeft) {
|
|
169
|
+
this._wrapperRef.classList.add("tc-dnd--show-row");
|
|
170
|
+
this._wrapperRef.classList.remove("tc-dnd--show-col");
|
|
171
|
+
} else if (nearTop) {
|
|
172
|
+
this._wrapperRef.classList.add("tc-dnd--show-col");
|
|
173
|
+
this._wrapperRef.classList.remove("tc-dnd--show-row");
|
|
174
|
+
} else {
|
|
175
|
+
this._wrapperRef.classList.remove(
|
|
176
|
+
"tc-dnd--show-row",
|
|
177
|
+
"tc-dnd--show-col",
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// ─── Toggler pointerdown (start pending drag) ───────────────────────
|
|
183
|
+
|
|
184
|
+
private _onTogglerDown(
|
|
185
|
+
type: "row" | "col",
|
|
186
|
+
wrapper: HTMLElement,
|
|
187
|
+
e: PointerEvent,
|
|
188
|
+
): void {
|
|
189
|
+
// Detect which row/col is currently hovered by the table plugin
|
|
190
|
+
const index = this._detectHoveredIndex(type, wrapper);
|
|
191
|
+
if (index < 0) return;
|
|
192
|
+
|
|
193
|
+
this._drag = {
|
|
194
|
+
active: false,
|
|
195
|
+
pending: true,
|
|
196
|
+
type,
|
|
197
|
+
index,
|
|
198
|
+
dropIndex: index,
|
|
199
|
+
pointerId: e.pointerId,
|
|
200
|
+
startX: e.clientX,
|
|
201
|
+
startY: e.clientY,
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
document.addEventListener("pointermove", this._onMoveBound);
|
|
205
|
+
document.addEventListener("pointerup", this._onUpBound);
|
|
206
|
+
document.addEventListener("pointercancel", this._onUpBound);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// ─── Detect hovered row/col index ───────────────────────────────────
|
|
210
|
+
|
|
211
|
+
private _detectHoveredIndex(
|
|
212
|
+
type: "row" | "col",
|
|
213
|
+
wrapper: HTMLElement,
|
|
214
|
+
): number {
|
|
215
|
+
const tableEl = wrapper.querySelector<HTMLElement>(".tc-table");
|
|
216
|
+
if (!tableEl) return -1;
|
|
217
|
+
|
|
218
|
+
if (type === "row") {
|
|
219
|
+
// The row toolbox is positioned at the hovered row.
|
|
220
|
+
// Find which row by comparing toolbox top to row tops.
|
|
221
|
+
const toolbox = wrapper.querySelector<HTMLElement>(".tc-toolbox--row");
|
|
222
|
+
if (!toolbox) return -1;
|
|
223
|
+
const toolboxRect = toolbox.getBoundingClientRect();
|
|
224
|
+
const toolboxMid = toolboxRect.top + toolboxRect.height / 2;
|
|
225
|
+
|
|
226
|
+
const rows = tableEl.querySelectorAll<HTMLElement>(".tc-row");
|
|
227
|
+
for (let i = 0; i < rows.length; i++) {
|
|
228
|
+
const r = rows[i].getBoundingClientRect();
|
|
229
|
+
if (toolboxMid >= r.top && toolboxMid <= r.bottom) return i;
|
|
230
|
+
}
|
|
231
|
+
return -1;
|
|
232
|
+
} else {
|
|
233
|
+
const toolbox = wrapper.querySelector<HTMLElement>(
|
|
234
|
+
".tc-toolbox--column",
|
|
235
|
+
);
|
|
236
|
+
if (!toolbox) return -1;
|
|
237
|
+
const toolboxRect = toolbox.getBoundingClientRect();
|
|
238
|
+
const toolboxMid = toolboxRect.left + toolboxRect.width / 2;
|
|
239
|
+
|
|
240
|
+
const firstRow = tableEl.querySelector<HTMLElement>(".tc-row");
|
|
241
|
+
if (!firstRow) return -1;
|
|
242
|
+
const cells = firstRow.querySelectorAll<HTMLElement>(".tc-cell");
|
|
243
|
+
for (let i = 0; i < cells.length; i++) {
|
|
244
|
+
const r = cells[i].getBoundingClientRect();
|
|
245
|
+
if (toolboxMid >= r.left && toolboxMid <= r.right) return i;
|
|
246
|
+
}
|
|
247
|
+
return -1;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// ─── Pointer Move ───────────────────────────────────────────────────
|
|
252
|
+
|
|
253
|
+
private _onPointerMove(e: PointerEvent): void {
|
|
254
|
+
const d = this._drag;
|
|
255
|
+
if (!d.pending && !d.active) return;
|
|
256
|
+
|
|
257
|
+
// Check threshold to start drag
|
|
258
|
+
if (d.pending && !d.active) {
|
|
259
|
+
const dx = e.clientX - d.startX;
|
|
260
|
+
const dy = e.clientY - d.startY;
|
|
261
|
+
if (Math.abs(dx) + Math.abs(dy) < DRAG_THRESHOLD) return;
|
|
262
|
+
|
|
263
|
+
// Passed threshold → start real drag
|
|
264
|
+
d.pending = false;
|
|
265
|
+
d.active = true;
|
|
266
|
+
|
|
267
|
+
// Close any open popover from the table plugin
|
|
268
|
+
const openPopover =
|
|
269
|
+
this._wrapperRef?.querySelector<HTMLElement>(".tc-popover--opened");
|
|
270
|
+
openPopover?.classList.remove("tc-popover--opened");
|
|
271
|
+
|
|
272
|
+
this._highlight(d.type!, d.index, true);
|
|
273
|
+
document.body.style.cursor = "grabbing";
|
|
274
|
+
document.body.style.userSelect = "none";
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
if (!d.active || !this._wrapperRef) return;
|
|
278
|
+
e.preventDefault();
|
|
279
|
+
|
|
280
|
+
const drop = this._calcDrop(this._wrapperRef, e.clientX, e.clientY);
|
|
281
|
+
if (drop !== d.dropIndex) {
|
|
282
|
+
d.dropIndex = drop;
|
|
283
|
+
this._showIndicator(this._wrapperRef, drop);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// ─── Pointer Up ─────────────────────────────────────────────────────
|
|
288
|
+
|
|
289
|
+
private _onPointerUp(e: PointerEvent): void {
|
|
290
|
+
const d = this._drag;
|
|
291
|
+
const wasDragging = d.active;
|
|
292
|
+
|
|
293
|
+
if (wasDragging) {
|
|
294
|
+
e.preventDefault();
|
|
295
|
+
e.stopPropagation();
|
|
296
|
+
|
|
297
|
+
this._highlight(d.type!, d.index, false);
|
|
298
|
+
if (this._indicator) this._indicator.style.display = "none";
|
|
299
|
+
|
|
300
|
+
document.body.style.cursor = "";
|
|
301
|
+
document.body.style.userSelect = "";
|
|
302
|
+
|
|
303
|
+
if (d.dropIndex !== d.index && d.dropIndex !== -1) {
|
|
304
|
+
if (d.type === "row") this._moveRow(d.index, d.dropIndex);
|
|
305
|
+
else this._moveCol(d.index, d.dropIndex);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// Swallow the click event that the browser fires after pointerup
|
|
309
|
+
// so the popover menu doesn't open after a drag.
|
|
310
|
+
const swallowClick = (ev: Event) => {
|
|
311
|
+
ev.preventDefault();
|
|
312
|
+
ev.stopPropagation();
|
|
313
|
+
ev.stopImmediatePropagation();
|
|
314
|
+
};
|
|
315
|
+
document.addEventListener("click", swallowClick, {
|
|
316
|
+
capture: true,
|
|
317
|
+
once: true,
|
|
318
|
+
});
|
|
319
|
+
// Safety: remove after a short delay in case click never fires
|
|
320
|
+
setTimeout(() => {
|
|
321
|
+
document.removeEventListener("click", swallowClick, {
|
|
322
|
+
capture: true,
|
|
323
|
+
});
|
|
324
|
+
}, 200);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// If pending (no drag threshold met) — let the click go through
|
|
328
|
+
// to the original popover menu handler.
|
|
329
|
+
|
|
330
|
+
// Reset
|
|
331
|
+
d.active = false;
|
|
332
|
+
d.pending = false;
|
|
333
|
+
document.removeEventListener("pointermove", this._onMoveBound);
|
|
334
|
+
document.removeEventListener("pointerup", this._onUpBound);
|
|
335
|
+
document.removeEventListener("pointercancel", this._onUpBound);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// ─── Move Row / Column ──────────────────────────────────────────────
|
|
339
|
+
|
|
340
|
+
private _moveRow(from: number, to: number): void {
|
|
341
|
+
const tableEl =
|
|
342
|
+
this._wrapperRef?.querySelector<HTMLElement>(".tc-table");
|
|
343
|
+
if (!tableEl) return;
|
|
344
|
+
|
|
345
|
+
const rows = Array.from(
|
|
346
|
+
tableEl.querySelectorAll<HTMLElement>(".tc-row"),
|
|
347
|
+
);
|
|
348
|
+
if (from < 0 || from >= rows.length) return;
|
|
349
|
+
|
|
350
|
+
const target = to > from ? to - 1 : to;
|
|
351
|
+
if (target === from) return;
|
|
352
|
+
|
|
353
|
+
const row = rows[from];
|
|
354
|
+
const ref = rows[target];
|
|
355
|
+
if (target > from) {
|
|
356
|
+
ref.parentElement!.insertBefore(row, ref.nextSibling);
|
|
357
|
+
} else {
|
|
358
|
+
ref.parentElement!.insertBefore(row, ref);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
private _moveCol(from: number, to: number): void {
|
|
363
|
+
const tableEl =
|
|
364
|
+
this._wrapperRef?.querySelector<HTMLElement>(".tc-table");
|
|
365
|
+
if (!tableEl) return;
|
|
366
|
+
|
|
367
|
+
const target = to > from ? to - 1 : to;
|
|
368
|
+
if (target === from) return;
|
|
369
|
+
|
|
370
|
+
tableEl.querySelectorAll<HTMLElement>(".tc-row").forEach((row) => {
|
|
371
|
+
const cells = Array.from(
|
|
372
|
+
row.querySelectorAll<HTMLElement>(".tc-cell"),
|
|
373
|
+
);
|
|
374
|
+
if (from >= cells.length) return;
|
|
375
|
+
|
|
376
|
+
const cell = cells[from];
|
|
377
|
+
const ref = cells[target];
|
|
378
|
+
if (target > from) {
|
|
379
|
+
row.insertBefore(cell, ref.nextSibling);
|
|
380
|
+
} else {
|
|
381
|
+
row.insertBefore(cell, ref);
|
|
382
|
+
}
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// ─── Drop Index Calc ────────────────────────────────────────────────
|
|
387
|
+
|
|
388
|
+
private _calcDrop(
|
|
389
|
+
wrapper: HTMLElement,
|
|
390
|
+
cx: number,
|
|
391
|
+
cy: number,
|
|
392
|
+
): number {
|
|
393
|
+
const tableEl = wrapper.querySelector<HTMLElement>(".tc-table");
|
|
394
|
+
if (!tableEl) return this._drag.index;
|
|
395
|
+
|
|
396
|
+
if (this._drag.type === "row") {
|
|
397
|
+
const rows = tableEl.querySelectorAll<HTMLElement>(".tc-row");
|
|
398
|
+
for (let i = 0; i < rows.length; i++) {
|
|
399
|
+
const r = rows[i].getBoundingClientRect();
|
|
400
|
+
if (cy < r.top + r.height / 2) return i;
|
|
401
|
+
}
|
|
402
|
+
return rows.length;
|
|
403
|
+
} else {
|
|
404
|
+
const first = tableEl.querySelector<HTMLElement>(".tc-row");
|
|
405
|
+
if (!first) return this._drag.index;
|
|
406
|
+
const cells = first.querySelectorAll<HTMLElement>(".tc-cell");
|
|
407
|
+
for (let i = 0; i < cells.length; i++) {
|
|
408
|
+
const r = cells[i].getBoundingClientRect();
|
|
409
|
+
if (cx < r.left + r.width / 2) return i;
|
|
410
|
+
}
|
|
411
|
+
return cells.length;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
// ─── Visual Feedback ────────────────────────────────────────────────
|
|
416
|
+
|
|
417
|
+
private _highlight(
|
|
418
|
+
type: "row" | "col",
|
|
419
|
+
idx: number,
|
|
420
|
+
on: boolean,
|
|
421
|
+
): void {
|
|
422
|
+
const tableEl =
|
|
423
|
+
this._wrapperRef?.querySelector<HTMLElement>(".tc-table");
|
|
424
|
+
if (!tableEl) return;
|
|
425
|
+
|
|
426
|
+
if (type === "row") {
|
|
427
|
+
const rows = tableEl.querySelectorAll<HTMLElement>(".tc-row");
|
|
428
|
+
rows[idx]?.classList.toggle("tc-dnd__row--dragging", on);
|
|
429
|
+
} else {
|
|
430
|
+
tableEl.querySelectorAll<HTMLElement>(".tc-row").forEach((row) => {
|
|
431
|
+
const cells = row.querySelectorAll<HTMLElement>(".tc-cell");
|
|
432
|
+
cells[idx]?.classList.toggle("tc-dnd__cell--dragging", on);
|
|
433
|
+
});
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
private _showIndicator(wrapper: HTMLElement, dropIdx: number): void {
|
|
438
|
+
if (!this._indicator) return;
|
|
439
|
+
const tableEl = wrapper.querySelector<HTMLElement>(".tc-table");
|
|
440
|
+
if (!tableEl) return;
|
|
441
|
+
|
|
442
|
+
const { type, index } = this._drag;
|
|
443
|
+
if (dropIdx === index || dropIdx === index + 1) {
|
|
444
|
+
this._indicator.style.display = "none";
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
const wrapRect = wrapper.getBoundingClientRect();
|
|
449
|
+
this._indicator.style.display = "block";
|
|
450
|
+
|
|
451
|
+
if (type === "row") {
|
|
452
|
+
const rows = tableEl.querySelectorAll<HTMLElement>(".tc-row");
|
|
453
|
+
const tableRect = tableEl.getBoundingClientRect();
|
|
454
|
+
let y: number;
|
|
455
|
+
if (dropIdx >= rows.length) {
|
|
456
|
+
y = rows[rows.length - 1].getBoundingClientRect().bottom;
|
|
457
|
+
} else {
|
|
458
|
+
y = rows[dropIdx].getBoundingClientRect().top;
|
|
459
|
+
}
|
|
460
|
+
this._indicator.style.left = `${tableRect.left - wrapRect.left}px`;
|
|
461
|
+
this._indicator.style.top = `${y - wrapRect.top - 2}px`;
|
|
462
|
+
this._indicator.style.width = `${tableRect.width}px`;
|
|
463
|
+
this._indicator.style.height = "4px";
|
|
464
|
+
} else {
|
|
465
|
+
const first = tableEl.querySelector<HTMLElement>(".tc-row");
|
|
466
|
+
if (!first) return;
|
|
467
|
+
const cells = first.querySelectorAll<HTMLElement>(".tc-cell");
|
|
468
|
+
const tableRect = tableEl.getBoundingClientRect();
|
|
469
|
+
let x: number;
|
|
470
|
+
if (dropIdx >= cells.length) {
|
|
471
|
+
x = cells[cells.length - 1].getBoundingClientRect().right;
|
|
472
|
+
} else {
|
|
473
|
+
x = cells[dropIdx].getBoundingClientRect().left;
|
|
474
|
+
}
|
|
475
|
+
this._indicator.style.left = `${x - wrapRect.left - 2}px`;
|
|
476
|
+
this._indicator.style.top = `${tableRect.top - wrapRect.top}px`;
|
|
477
|
+
this._indicator.style.width = "4px";
|
|
478
|
+
this._indicator.style.height = `${tableRect.height}px`;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
// ─── Cleanup ────────────────────────────────────────────────────────
|
|
483
|
+
|
|
484
|
+
private _teardown(): void {
|
|
485
|
+
if (this._rafId) cancelAnimationFrame(this._rafId);
|
|
486
|
+
document.removeEventListener("pointermove", this._onMoveBound);
|
|
487
|
+
document.removeEventListener("pointerup", this._onUpBound);
|
|
488
|
+
document.removeEventListener("pointercancel", this._onUpBound);
|
|
489
|
+
this._mutationObs?.disconnect();
|
|
490
|
+
this._indicator?.remove();
|
|
491
|
+
document.body.style.cursor = "";
|
|
492
|
+
document.body.style.userSelect = "";
|
|
493
|
+
}
|
|
494
|
+
};
|
|
495
|
+
}
|
|
@@ -26,6 +26,7 @@ import CodeTool from "@editorjs/code";
|
|
|
26
26
|
import Delimiter from "@editorjs/delimiter";
|
|
27
27
|
import Embed from "@editorjs/embed";
|
|
28
28
|
import Table from "@editorjs/table";
|
|
29
|
+
import createTableDnDClass from "./TableDnDWrapper";
|
|
29
30
|
import LinkTool from "@editorjs/link";
|
|
30
31
|
import SimpleImage from "@editorjs/simple-image";
|
|
31
32
|
import RawTool from "@editorjs/raw";
|
|
@@ -160,7 +161,7 @@ const getDefaultTools = (): Record<string, any> => ({
|
|
|
160
161
|
},
|
|
161
162
|
},
|
|
162
163
|
table: {
|
|
163
|
-
class: Table,
|
|
164
|
+
class: createTableDnDClass(Table),
|
|
164
165
|
inlineToolbar: true,
|
|
165
166
|
config: { rows: 2, cols: 3 },
|
|
166
167
|
shortcut: "CMD+ALT+T",
|
|
@@ -299,6 +300,57 @@ const AUTO_DIR_STYLES = `
|
|
|
299
300
|
fill: #999;
|
|
300
301
|
}
|
|
301
302
|
|
|
303
|
+
/* ── Table DnD: toggler-based drag-and-drop ── */
|
|
304
|
+
.torch-text-editor .tc-dnd-wrap {
|
|
305
|
+
position: relative;
|
|
306
|
+
}
|
|
307
|
+
.torch-text-editor .tc-dnd-wrap .tc-toolbox__toggler {
|
|
308
|
+
cursor: grab;
|
|
309
|
+
}
|
|
310
|
+
/* Hide both toolboxes by default — show only near the relevant edge */
|
|
311
|
+
.torch-text-editor .tc-dnd-wrap .tc-toolbox--row {
|
|
312
|
+
opacity: 0 !important;
|
|
313
|
+
pointer-events: none !important;
|
|
314
|
+
transition: opacity 120ms ease;
|
|
315
|
+
}
|
|
316
|
+
.torch-text-editor .tc-dnd-wrap .tc-toolbox--column {
|
|
317
|
+
opacity: 0 !important;
|
|
318
|
+
pointer-events: none !important;
|
|
319
|
+
transition: opacity 120ms ease;
|
|
320
|
+
}
|
|
321
|
+
.torch-text-editor .tc-dnd-wrap.tc-dnd--show-row .tc-toolbox--row {
|
|
322
|
+
opacity: 1 !important;
|
|
323
|
+
pointer-events: auto !important;
|
|
324
|
+
}
|
|
325
|
+
.torch-text-editor .tc-dnd-wrap.tc-dnd--show-col .tc-toolbox--column {
|
|
326
|
+
opacity: 1 !important;
|
|
327
|
+
pointer-events: auto !important;
|
|
328
|
+
}
|
|
329
|
+
/* Dragging: purple highlight on row */
|
|
330
|
+
.torch-text-editor .tc-dnd__row--dragging {
|
|
331
|
+
outline: 2px solid #8b5cf6 !important;
|
|
332
|
+
outline-offset: -1px;
|
|
333
|
+
background: rgba(139, 92, 246, 0.06) !important;
|
|
334
|
+
position: relative;
|
|
335
|
+
z-index: 2;
|
|
336
|
+
}
|
|
337
|
+
/* Dragging: purple highlight on column cells */
|
|
338
|
+
.torch-text-editor .tc-dnd__cell--dragging {
|
|
339
|
+
outline: 2px solid #8b5cf6 !important;
|
|
340
|
+
outline-offset: -1px;
|
|
341
|
+
background: rgba(139, 92, 246, 0.06) !important;
|
|
342
|
+
}
|
|
343
|
+
/* Drop indicator line */
|
|
344
|
+
.torch-text-editor .tc-dnd__indicator {
|
|
345
|
+
position: absolute;
|
|
346
|
+
background: #8b5cf6;
|
|
347
|
+
border-radius: 2px;
|
|
348
|
+
display: none;
|
|
349
|
+
pointer-events: none;
|
|
350
|
+
z-index: 10;
|
|
351
|
+
transition: top 60ms ease-out, left 60ms ease-out;
|
|
352
|
+
}
|
|
353
|
+
|
|
302
354
|
/* ── Editor.js core popover: dark mode variable overrides ── */
|
|
303
355
|
[data-theme="dark"] .ce-popover,
|
|
304
356
|
.torch-text-editor[data-theme="dark"] .ce-popover {
|
package/dist/bin/index.js
CHANGED
|
@@ -7,6 +7,7 @@ import { addLayout } from "../src/commands/layout.js";
|
|
|
7
7
|
import { addUtil } from "../src/commands/utils.js";
|
|
8
8
|
import { addProvider } from "../src/commands/provider.js";
|
|
9
9
|
import { updateInstalledComponents } from "../src/commands/update.js";
|
|
10
|
+
import { setupMcp } from "../src/commands/mcp.js";
|
|
10
11
|
const program = new Command();
|
|
11
12
|
program
|
|
12
13
|
.name("torch-glare")
|
|
@@ -40,5 +41,9 @@ program
|
|
|
40
41
|
.command("update")
|
|
41
42
|
.description("Update everything installed")
|
|
42
43
|
.action(() => updateInstalledComponents());
|
|
44
|
+
program
|
|
45
|
+
.command("mcp")
|
|
46
|
+
.description("Set up TORCH Glare MCP server for your AI client")
|
|
47
|
+
.action(() => setupMcp());
|
|
43
48
|
program.parse(process.argv);
|
|
44
49
|
//# sourceMappingURL=index.js.map
|
package/dist/bin/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../cli/bin/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,GAAG,EAAE,MAAM,wBAAwB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../cli/bin/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,GAAG,EAAE,MAAM,wBAAwB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAElD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,aAAa,CAAC;KACnB,WAAW,CAAC,2CAA2C,CAAC;KACxD,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,0CAA0C,CAAC;KACvD,MAAM,CAAC,GAAG,EAAE,CAAC,UAAU,EAAE,CAAC,CAAC;AAE9B,OAAO;KACJ,OAAO,CAAC,iBAAiB,CAAC;KAC1B,WAAW,CAAC,0DAA0D,CAAC;KACvE,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,GAAG,CAAC,SAAS,IAAI,GAAG,SAAS,MAAM,CAAC,CAAC,CAAC;AAE/D,OAAO;KACJ,OAAO,CAAC,aAAa,CAAC;KACtB,WAAW,CAAC,qDAAqD,CAAC;KAClE,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,IAAI,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC;AAEhD,OAAO;KACJ,OAAO,CAAC,iBAAiB,CAAC;KAC1B,WAAW,CAAC,uDAAuD,CAAC;KACpE,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,CAAC,CAAC;AAE5D,OAAO;KACJ,OAAO,CAAC,aAAa,CAAC;KACtB,WAAW,CAAC,sDAAsD,CAAC;KACnE,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,IAAI,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC;AAEnD,OAAO;KACJ,OAAO,CAAC,qBAAqB,CAAC;KAC9B,WAAW,CAAC,yDAAyD,CAAC;KACtE,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,WAAW,CAAC,QAAQ,IAAI,GAAG,QAAQ,EAAE,CAAC,CAAC,CAAC;AAEhE,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,6BAA6B,CAAC;KAC1C,MAAM,CAAC,GAAG,EAAE,CAAC,yBAAyB,EAAE,CAAC,CAAC;AAE7C,OAAO;KACJ,OAAO,CAAC,KAAK,CAAC;KACd,WAAW,CAAC,kDAAkD,CAAC;KAC/D,MAAM,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;AAE5B,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../../cli/src/commands/mcp.ts"],"names":[],"mappings":"AA0DA,wBAAsB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAyD9C"}
|