Skip to content

Commit c38f84d

Browse files
committed
update table styles
1 parent d4c9070 commit c38f84d

5 files changed

Lines changed: 76 additions & 66 deletions

File tree

src/components/HTMLEngineProvider/HTMLRenderers/TableCellRenderer.tsx

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@ import type {FlexStyle, TextStyle} from 'react-native';
44
import type {CustomRendererProps, TBlock} from 'react-native-render-html';
55
import {TNodeChildrenRenderer} from 'react-native-render-html';
66
import Text from '@components/Text';
7-
import useTheme from '@hooks/useTheme';
87
import useThemeStyles from '@hooks/useThemeStyles';
9-
import variables from '@styles/variables';
108

119
type CellAlignment = {
1210
alignItems: FlexStyle['alignItems'];
@@ -23,28 +21,14 @@ function getCellAlignment(styleAttribute: string | undefined): CellAlignment {
2321
return {alignItems: 'flex-start', textAlign: 'left'};
2422
}
2523

26-
/**
27-
* Renders an HTML <th> or <td>. Cells share the row width equally; header cells use the smaller
28-
* label font and bold weight, while body cells use the normal message font.
29-
*/
3024
function TableCellRenderer({tnode}: CustomRendererProps<TBlock>) {
3125
const styles = useThemeStyles();
32-
const theme = useTheme();
3326
const isHeaderCell = tnode.tagName === 'th';
3427
const {alignItems, textAlign} = getCellAlignment(tnode.attributes.style);
3528

3629
return (
37-
<View style={[styles.flex1, {alignItems, paddingVertical: variables.tableRowPaddingVertical, paddingEnd: 8}]}>
38-
<Text
39-
style={[
40-
isHeaderCell ? styles.textBold : {},
41-
{
42-
color: theme.text,
43-
fontSize: isHeaderCell ? variables.fontSizeLabel : variables.fontSizeNormal,
44-
textAlign,
45-
},
46-
]}
47-
>
30+
<View style={[styles.htmlTableCell, {alignItems}]}>
31+
<Text style={[isHeaderCell ? styles.htmlTableHeaderCellText : styles.htmlTableCellText, {textAlign}]}>
4832
<TNodeChildrenRenderer tnode={tnode} />
4933
</Text>
5034
</View>

src/components/HTMLEngineProvider/HTMLRenderers/TableRenderer.tsx

Lines changed: 22 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,36 @@
11
import React from 'react';
2-
import {View} from 'react-native';
2+
import {ScrollView, View} from 'react-native';
33
import type {CustomRendererProps, TBlock} from 'react-native-render-html';
44
import {TNodeRenderer} from 'react-native-render-html';
5-
import useTheme from '@hooks/useTheme';
6-
import variables from '@styles/variables';
5+
import useThemeStyles from '@hooks/useThemeStyles';
76

8-
/**
9-
* Renders an HTML <table> as a styled, highlighted container. The library has no built-in
10-
* table layout, so children (<thead>/<tbody>) are rendered as stacked blocks and the row/cell
11-
* layout is handled by the dedicated row and cell renderers.
12-
*/
137
function TableRenderer({tnode}: CustomRendererProps<TBlock>) {
14-
const theme = useTheme();
8+
const styles = useThemeStyles();
159

1610
// Skip whitespace-only text nodes that sit between block elements in the source HTML.
1711
const sections = tnode.children.filter((child) => !!child.tagName);
1812

1913
return (
20-
<View
21-
style={{
22-
alignSelf: 'stretch',
23-
marginVertical: 8,
24-
borderRadius: variables.componentBorderRadiusNormal,
25-
backgroundColor: theme.highlightBG,
26-
overflow: 'hidden',
27-
}}
14+
<ScrollView
15+
horizontal
16+
showsHorizontalScrollIndicator={false}
17+
style={styles.w100}
18+
contentContainerStyle={styles.htmlTableScrollContainerContent}
2819
>
29-
{sections.map((child, index) => {
30-
const key = `${child.tagName ?? 'node'}-${index}`;
31-
return (
32-
<TNodeRenderer
33-
key={key}
34-
tnode={child}
35-
renderIndex={index}
36-
renderLength={sections.length}
37-
/>
38-
);
39-
})}
40-
</View>
20+
<View style={styles.htmlTable}>
21+
{sections.map((child, index) => {
22+
const key = `${child.tagName ?? 'node'}-${index}`;
23+
return (
24+
<TNodeRenderer
25+
key={key}
26+
tnode={child}
27+
renderIndex={index}
28+
renderLength={sections.length}
29+
/>
30+
);
31+
})}
32+
</View>
33+
</ScrollView>
4134
);
4235
}
4336

src/components/HTMLEngineProvider/HTMLRenderers/TableRowRenderer.tsx

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,19 @@ import React from 'react';
22
import {View} from 'react-native';
33
import type {CustomRendererProps, TBlock} from 'react-native-render-html';
44
import {TNodeRenderer} from 'react-native-render-html';
5-
import useTheme from '@hooks/useTheme';
65
import useThemeStyles from '@hooks/useThemeStyles';
7-
import variables from '@styles/variables';
86

9-
/**
10-
* Renders an HTML <tr> as a flex row. Each row has a minimum height, horizontal padding and a
11-
* bottom border to separate it from the next row, matching how our other tables are displayed.
12-
*/
137
function TableRowRenderer({tnode}: CustomRendererProps<TBlock>) {
148
const styles = useThemeStyles();
15-
const theme = useTheme();
9+
10+
// Header rows (inside <thead>) use header padding; body rows use the compact min-height.
11+
const isHeaderRow = tnode.parent?.tagName === 'thead';
1612

1713
// Skip whitespace-only text nodes that sit between cells in the source HTML.
1814
const cells = tnode.children.filter((child) => !!child.tagName);
1915

2016
return (
21-
<View
22-
style={[
23-
styles.flexRow,
24-
styles.alignItemsCenter,
25-
{
26-
minHeight: 40,
27-
paddingHorizontal: variables.tableRowPaddingHorizontal,
28-
borderBottomWidth: 1,
29-
borderColor: theme.border,
30-
},
31-
]}
32-
>
17+
<View style={isHeaderRow ? styles.htmlTableHeaderRow : styles.htmlTableRow}>
3318
{cells.map((child, index) => {
3419
const key = `${child.tagName ?? 'node'}-${index}`;
3520
return (

src/styles/index.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2656,6 +2656,52 @@ const staticStyles = (theme: ThemeColors) =>
26562656
minHeight: variables.tableHeaderContentHeight,
26572657
},
26582658

2659+
htmlTableScrollContainerContent: {
2660+
flexGrow: 1,
2661+
},
2662+
2663+
htmlTable: {
2664+
minWidth: '100%',
2665+
marginVertical: 8,
2666+
borderRadius: variables.componentBorderRadius,
2667+
backgroundColor: theme.highlightBG,
2668+
overflow: 'hidden',
2669+
},
2670+
2671+
htmlTableHeaderRow: {
2672+
flexDirection: 'row',
2673+
alignItems: 'center',
2674+
paddingHorizontal: variables.tableRowPaddingHorizontal,
2675+
paddingVertical: variables.tableRowPaddingVertical,
2676+
borderBottomWidth: 1,
2677+
borderColor: theme.border,
2678+
},
2679+
2680+
htmlTableRow: {
2681+
flexDirection: 'row',
2682+
alignItems: 'center',
2683+
minHeight: variables.htmlTableRowMinHeight,
2684+
paddingHorizontal: variables.tableRowPaddingHorizontal,
2685+
borderBottomWidth: 1,
2686+
borderColor: theme.border,
2687+
},
2688+
2689+
htmlTableCell: {
2690+
flex: 1,
2691+
minWidth: variables.htmlTableColumnMinWidth,
2692+
paddingEnd: 8,
2693+
},
2694+
2695+
htmlTableCellText: {
2696+
color: theme.text,
2697+
fontSize: variables.fontSizeNormal,
2698+
},
2699+
2700+
htmlTableHeaderCellText: {
2701+
color: theme.textSupporting,
2702+
fontSize: variables.fontSizeLabel,
2703+
},
2704+
26592705
borderBottom: {
26602706
borderBottomWidth: 1,
26612707
borderColor: theme.border,

src/styles/variables.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ export default {
131131
tableRowHeightCompact: 60,
132132
tableRowPaddingVertical: 8,
133133
tableRowPaddingHorizontal: 12,
134+
htmlTableRowMinHeight: 40,
135+
htmlTableColumnMinWidth: 80,
134136
tableGroupRowPaddingVertical: 4,
135137
tableGroupRowHeight: 36,
136138
tableCheckboxColumnWidth: 20,

0 commit comments

Comments
 (0)