Skip to content

Commit 423aaeb

Browse files
committed
fix(admin): address PR review feedback for table support
- Replace hard-coded colors with Kumo design tokens - Move TipTap table extensions to catalog dependencies - Use existing convertPTMarks for table cell mark conversion - Fix markDefs handling in both PT↔PM conversion directions - Add unit tests for table conversion (7 tests)
1 parent 4c42de0 commit 423aaeb

5 files changed

Lines changed: 426 additions & 43 deletions

File tree

packages/admin/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@
4343
"@tiptap/extension-placeholder": "catalog:",
4444
"@tiptap/extension-text-align": "catalog:",
4545
"@tiptap/extension-typography": "catalog:",
46+
"@tiptap/extension-table": "catalog:",
47+
"@tiptap/extension-table-cell": "catalog:",
48+
"@tiptap/extension-table-header": "catalog:",
49+
"@tiptap/extension-table-row": "catalog:",
4650
"@tiptap/extension-underline": "catalog:",
4751
"@tiptap/pm": "catalog:",
4852
"@tiptap/react": "catalog:",
@@ -61,10 +65,6 @@
6165
"@tailwindcss/cli": "^4.1.10",
6266
"@tailwindcss/typography": "^0.5.19",
6367
"@testing-library/react": "^16.3.0",
64-
"@tiptap/extension-table": "^3.22.1",
65-
"@tiptap/extension-table-cell": "^3.22.1",
66-
"@tiptap/extension-table-header": "^3.22.1",
67-
"@tiptap/extension-table-row": "^3.22.1",
6868
"@tiptap/suggestion": "catalog:",
6969
"@types/react": "catalog:",
7070
"@types/react-dom": "catalog:",

packages/admin/src/components/PortableTextEditor.tsx

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,7 @@ function convertPMNode(node: {
299299
}>;
300300
}>;
301301

302+
const tableMarkDefs: PortableTextMarkDef[] = [];
302303
const rows = tableContent
303304
.filter((row) => row.type === "tableRow")
304305
.map((row, rowIndex) => {
@@ -309,16 +310,15 @@ function convertPMNode(node: {
309310
content?: unknown[];
310311
}>;
311312

312-
// Extract text from paragraphs inside the cell
313313
const contentSpans: PortableTextSpan[] = [];
314314
for (const para of cellContent) {
315315
if (para.type === "paragraph") {
316-
const { children } = convertInlineContent(para.content || []);
316+
const { children, markDefs } = convertInlineContent(para.content || []);
317317
contentSpans.push(...children);
318+
tableMarkDefs.push(...markDefs);
318319
}
319320
}
320321

321-
// Ensure at least one span
322322
if (contentSpans.length === 0) {
323323
contentSpans.push({
324324
_type: "span",
@@ -347,6 +347,7 @@ function convertPMNode(node: {
347347
_key: tableKey,
348348
rows,
349349
hasHeaderRow: rows[0]?.cells.some((c) => c.isHeader) ?? false,
350+
markDefs: tableMarkDefs.length > 0 ? tableMarkDefs : undefined,
350351
};
351352
}
352353

@@ -626,36 +627,30 @@ function convertPTBlock(block: PortableTextBlock): unknown {
626627
_key: string;
627628
content: PortableTextSpan[];
628629
isHeader?: boolean;
630+
markDefs?: PortableTextMarkDef[];
629631
}>;
630632
}>;
631633
hasHeaderRow?: boolean;
634+
markDefs?: PortableTextMarkDef[];
632635
};
633636

637+
const tableMarkDefs = tableBlock.markDefs || [];
638+
const tableMarkDefsMap = new Map(tableMarkDefs.map((md) => [md._key, md]));
639+
634640
const rows = (tableBlock.rows || []).map((row, rowIndex) => {
635641
const cells = row.cells.map((cell) => {
636642
const cellType =
637643
cell.isHeader || (tableBlock.hasHeaderRow && rowIndex === 0)
638644
? "tableHeader"
639645
: "tableCell";
640646

641-
// Map PortableText marks to ProseMirror marks
642-
const markNameMap: Record<string, string> = {
643-
strong: "bold",
644-
em: "italic",
645-
underline: "underline",
646-
"strike-through": "strike",
647-
code: "code",
648-
};
649-
const pmContent = cell.content.map((span) => ({
650-
type: "text",
651-
text: span.text || "",
652-
marks:
653-
span.marks
654-
?.map((mark) => ({
655-
type: markNameMap[mark] || mark,
656-
}))
657-
.filter((m) => m.type) || [],
658-
}));
647+
const cellMarkDefs = cell.markDefs || [];
648+
const markDefsMap = new Map([
649+
...tableMarkDefsMap,
650+
...cellMarkDefs.map((md) => [md._key, md] as const),
651+
]);
652+
653+
const pmContent = convertPTSpans(cell.content, [...markDefsMap.values()]);
659654

660655
return {
661656
type: cellType,

packages/admin/src/styles.css

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -213,20 +213,20 @@ body {
213213

214214
.ProseMirror td,
215215
.ProseMirror th {
216-
border: 1px solid #d1d5db;
216+
border: 1px solid var(--color-kumo-line);
217217
padding: 0.5rem 0.75rem;
218218
vertical-align: top;
219219
position: relative;
220220
min-width: 80px;
221221
}
222222

223223
.ProseMirror th {
224-
background-color: #f3f4f6;
224+
background-color: var(--color-kumo-tint);
225225
font-weight: 600;
226226
}
227227

228228
.ProseMirror .selectedCell {
229-
background-color: #dbeafe;
229+
background-color: var(--color-kumo-info-tint);
230230
}
231231

232232
.ProseMirror .column-resize-handle {
@@ -235,28 +235,14 @@ body {
235235
top: 0;
236236
bottom: -2px;
237237
width: 4px;
238-
background-color: #3b82f6;
238+
background-color: var(--color-kumo-brand);
239239
pointer-events: none;
240240
}
241241

242242
.ProseMirror.resize-cursor {
243243
cursor: col-resize;
244244
}
245245

246-
/* Dark mode table styles */
247-
.dark .ProseMirror td,
248-
.dark .ProseMirror th {
249-
border-color: #4b5563;
250-
}
251-
252-
.dark .ProseMirror th {
253-
background-color: #374151;
254-
}
255-
256-
.dark .ProseMirror .selectedCell {
257-
background-color: #1e3a5f;
258-
}
259-
260246
/**
261247
* Isolate the admin root's stacking context.
262248
*/

0 commit comments

Comments
 (0)