Skip to content

Commit c2ce368

Browse files
use table column alignments when available (#441)
rdar://100337272
1 parent 32b16c7 commit c2ce368

File tree

3 files changed

+181
-14
lines changed

3 files changed

+181
-14
lines changed

src/components/ContentNode.vue

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,13 @@ const TableHeaderStyle = {
9696
row: 'row',
9797
};
9898
99+
const TableColumnAlignments = {
100+
left: 'left',
101+
right: 'right',
102+
center: 'center',
103+
unset: 'unset',
104+
};
105+
99106
// The point after which a TabNavigator turns to vertical mode.
100107
const TabNavigatorVerticalThreshold = 5;
101108
@@ -115,17 +122,22 @@ function renderNode(createElement, references) {
115122
));
116123
117124
const renderTableCell = (
118-
element, attrs, data, cellIndex, rowIndex, extendedData,
125+
element, attrs, data, cellIndex, rowIndex, extendedData, alignments,
119126
) => {
120127
const { colspan, rowspan } = extendedData[`${rowIndex}_${cellIndex}`] || {};
121128
// if either is `0`, then its spanned over and should not be rendered
122129
if (colspan === 0 || rowspan === 0) return null;
123-
return createElement(element, { attrs: { ...attrs, colspan, rowspan } }, (
130+
const align = alignments[cellIndex] || TableColumnAlignments.unset;
131+
let classes = null;
132+
if (align !== TableColumnAlignments.unset) classes = `${align}-cell`;
133+
return createElement(element, { attrs: { ...attrs, colspan, rowspan }, class: classes }, (
124134
renderChildren(data)
125135
));
126136
};
127137
128-
const renderTableChildren = (rows, headerStyle = TableHeaderStyle.none, extendedData = {}) => {
138+
const renderTableChildren = (
139+
rows, headerStyle = TableHeaderStyle.none, extendedData = {}, alignments = [],
140+
) => {
129141
// build the matrix for the array
130142
switch (headerStyle) {
131143
// thead with first row and th for each first row cell
@@ -135,14 +147,16 @@ function renderNode(createElement, references) {
135147
return [
136148
createElement('thead', {}, [
137149
createElement('tr', {}, firstRow.map((cell, cellIndex) => (
138-
renderTableCell('th', { scope: 'col' }, cell, cellIndex, 0, extendedData)
150+
renderTableCell('th', { scope: 'col' }, cell, cellIndex, 0, extendedData, alignments)
139151
))),
140152
]),
141153
createElement('tbody', {}, otherRows.map(([firstCell, ...otherCells], rowIndex) => (
142154
createElement('tr', {}, [
143-
renderTableCell('th', { scope: 'row' }, firstCell, 0, rowIndex + 1, extendedData),
155+
renderTableCell(
156+
'th', { scope: 'row' }, firstCell, 0, rowIndex + 1, extendedData, alignments,
157+
),
144158
...otherCells.map((cell, cellIndex) => (
145-
renderTableCell('td', {}, cell, cellIndex + 1, rowIndex + 1, extendedData)
159+
renderTableCell('td', {}, cell, cellIndex + 1, rowIndex + 1, extendedData, alignments)
146160
)),
147161
])
148162
))),
@@ -153,9 +167,11 @@ function renderNode(createElement, references) {
153167
return [
154168
createElement('tbody', {}, rows.map(([firstCell, ...otherCells], rowIndex) => (
155169
createElement('tr', {}, [
156-
renderTableCell('th', { scope: 'row' }, firstCell, 0, rowIndex, extendedData),
170+
renderTableCell(
171+
'th', { scope: 'row' }, firstCell, 0, rowIndex, extendedData, alignments,
172+
),
157173
...otherCells.map((cell, cellIndex) => (
158-
renderTableCell('td', {}, cell, cellIndex + 1, rowIndex, extendedData)
174+
renderTableCell('td', {}, cell, cellIndex + 1, rowIndex, extendedData, alignments)
159175
)),
160176
])
161177
))),
@@ -167,12 +183,12 @@ function renderNode(createElement, references) {
167183
return [
168184
createElement('thead', {}, [
169185
createElement('tr', {}, firstRow.map((cell, cellIndex) => renderTableCell(
170-
'th', { scope: 'col' }, cell, cellIndex, 0, extendedData,
186+
'th', { scope: 'col' }, cell, cellIndex, 0, extendedData, alignments,
171187
))),
172188
]),
173189
createElement('tbody', {}, otherRows.map((row, rowIndex) => (
174190
createElement('tr', {}, row.map((cell, cellIndex) => (
175-
renderTableCell('td', {}, cell, cellIndex, rowIndex + 1, extendedData)
191+
renderTableCell('td', {}, cell, cellIndex, rowIndex + 1, extendedData, alignments)
176192
)))
177193
))),
178194
];
@@ -184,7 +200,7 @@ function renderNode(createElement, references) {
184200
rows.map((row, rowIndex) => (
185201
createElement('tr', {}, (
186202
row.map((cell, cellIndex) => (
187-
renderTableCell('td', {}, cell, cellIndex, rowIndex, extendedData)
203+
renderTableCell('td', {}, cell, cellIndex, rowIndex, extendedData, alignments)
188204
))
189205
))
190206
))
@@ -269,7 +285,7 @@ function renderNode(createElement, references) {
269285
spanned: !!node.extendedData,
270286
},
271287
}, (
272-
renderTableChildren(node.rows, node.header, node.extendedData)
288+
renderTableChildren(node.rows, node.header, node.extendedData, node.alignments)
273289
));
274290
case BlockType.termList:
275291
return createElement('dl', {}, node.items.map(({ term, definition }) => [
@@ -417,7 +433,7 @@ function renderNode(createElement, references) {
417433
418434
export default {
419435
name: 'ContentNode',
420-
constants: { TableHeaderStyle },
436+
constants: { TableHeaderStyle, TableColumnAlignments },
421437
render: function render(createElement) {
422438
// Dynamically map each content item and any children to their
423439
// corresponding components, and wrap the whole tree in a <div>

src/components/ContentNode/Table.vue

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,18 @@ table {
6262
border-style: solid;
6363
border-width: var(--table-border-width, 1px 1px);
6464
padding: rem(10px);
65+
66+
&.left-cell {
67+
text-align: left;
68+
}
69+
70+
&.right-cell {
71+
text-align: right;
72+
}
73+
74+
&.center-cell {
75+
text-align: center;
76+
}
6577
}
6678
}
6779
</style>

tests/unit/components/ContentNode.spec.js

Lines changed: 140 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import Column from '@/components/ContentNode/Column.vue';
2929
import TabNavigator from '@/components/ContentNode/TabNavigator.vue';
3030
import TaskList from 'docc-render/components/ContentNode/TaskList.vue';
3131

32-
const { TableHeaderStyle } = ContentNode.constants;
32+
const { TableHeaderStyle, TableColumnAlignments } = ContentNode.constants;
3333

3434
const mountWithContent = (content = [], provide = { references: {} }) => (
3535
shallowMount(ContentNode, {
@@ -1414,6 +1414,145 @@ describe('ContentNode', () => {
14141414
`);
14151415
});
14161416
});
1417+
1418+
describe('and column alignments', () => {
1419+
const alignedRows = [
1420+
[
1421+
[{ type: 'text', text: 'row0col0' }],
1422+
[{ type: 'text', text: 'row0col1' }],
1423+
[{ type: 'text', text: 'row0col2' }],
1424+
[{ type: 'text', text: 'row0col3' }],
1425+
],
1426+
[
1427+
[{ type: 'text', text: 'row1col0' }],
1428+
[{ type: 'text', text: 'row1col1' }],
1429+
[{ type: 'text', text: 'row1col2' }],
1430+
[{ type: 'text', text: 'row1col3' }],
1431+
],
1432+
];
1433+
const alignments = [
1434+
TableColumnAlignments.left,
1435+
TableColumnAlignments.right,
1436+
TableColumnAlignments.center,
1437+
TableColumnAlignments.unset,
1438+
];
1439+
1440+
it('renders header="none" style tables, with column alignments', () => {
1441+
const wrapper = mountWithItem({
1442+
type: 'table',
1443+
header: TableHeaderStyle.none,
1444+
alignments,
1445+
rows: alignedRows,
1446+
});
1447+
const table = wrapper.find('.content').find(Table);
1448+
expect(table.html()).toMatchInlineSnapshot(`
1449+
<table-stub>
1450+
<tbody>
1451+
<tr>
1452+
<td class="left-cell">row0col0</td>
1453+
<td class="right-cell">row0col1</td>
1454+
<td class="center-cell">row0col2</td>
1455+
<td>row0col3</td>
1456+
</tr>
1457+
<tr>
1458+
<td class="left-cell">row1col0</td>
1459+
<td class="right-cell">row1col1</td>
1460+
<td class="center-cell">row1col2</td>
1461+
<td>row1col3</td>
1462+
</tr>
1463+
</tbody>
1464+
</table-stub>
1465+
`);
1466+
});
1467+
1468+
it('renders header="both" style tables, with column alignments', () => {
1469+
const wrapper = mountWithItem({
1470+
type: 'table',
1471+
header: TableHeaderStyle.both,
1472+
alignments,
1473+
rows: alignedRows,
1474+
});
1475+
const table = wrapper.find('.content').find(Table);
1476+
expect(table.html()).toMatchInlineSnapshot(`
1477+
<table-stub>
1478+
<thead>
1479+
<tr>
1480+
<th scope="col" class="left-cell">row0col0</th>
1481+
<th scope="col" class="right-cell">row0col1</th>
1482+
<th scope="col" class="center-cell">row0col2</th>
1483+
<th scope="col">row0col3</th>
1484+
</tr>
1485+
</thead>
1486+
<tbody>
1487+
<tr>
1488+
<th scope="row" class="left-cell">row1col0</th>
1489+
<td class="right-cell">row1col1</td>
1490+
<td class="center-cell">row1col2</td>
1491+
<td>row1col3</td>
1492+
</tr>
1493+
</tbody>
1494+
</table-stub>
1495+
`);
1496+
});
1497+
1498+
it('renders header="row" style tables, with column alignments', () => {
1499+
const wrapper = mountWithItem({
1500+
type: 'table',
1501+
header: TableHeaderStyle.row,
1502+
alignments,
1503+
rows: alignedRows,
1504+
});
1505+
const table = wrapper.find('.content').find(Table);
1506+
expect(table.html()).toMatchInlineSnapshot(`
1507+
<table-stub>
1508+
<thead>
1509+
<tr>
1510+
<th scope="col" class="left-cell">row0col0</th>
1511+
<th scope="col" class="right-cell">row0col1</th>
1512+
<th scope="col" class="center-cell">row0col2</th>
1513+
<th scope="col">row0col3</th>
1514+
</tr>
1515+
</thead>
1516+
<tbody>
1517+
<tr>
1518+
<td class="left-cell">row1col0</td>
1519+
<td class="right-cell">row1col1</td>
1520+
<td class="center-cell">row1col2</td>
1521+
<td>row1col3</td>
1522+
</tr>
1523+
</tbody>
1524+
</table-stub>
1525+
`);
1526+
});
1527+
1528+
it('renders header="column" style tables, with column alignments', () => {
1529+
const wrapper = mountWithItem({
1530+
type: 'table',
1531+
header: TableHeaderStyle.column,
1532+
alignments,
1533+
rows: alignedRows,
1534+
});
1535+
const table = wrapper.find('.content').find(Table);
1536+
expect(table.html()).toMatchInlineSnapshot(`
1537+
<table-stub>
1538+
<tbody>
1539+
<tr>
1540+
<th scope="row" class="left-cell">row0col0</th>
1541+
<td class="right-cell">row0col1</td>
1542+
<td class="center-cell">row0col2</td>
1543+
<td>row0col3</td>
1544+
</tr>
1545+
<tr>
1546+
<th scope="row" class="left-cell">row1col0</th>
1547+
<td class="right-cell">row1col1</td>
1548+
<td class="center-cell">row1col2</td>
1549+
<td>row1col3</td>
1550+
</tr>
1551+
</tbody>
1552+
</table-stub>
1553+
`);
1554+
});
1555+
});
14171556
});
14181557

14191558
describe('with type="termList"', () => {

0 commit comments

Comments
 (0)