Skip to content

Commit b1ea3f6

Browse files
committed
feat(heuristic-table): new 100% native table plugin
1 parent 7cb126a commit b1ea3f6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+2567
-16
lines changed

.github/workflows/heuristic-table.yml

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# This workflow will do a clean install of node dependencies, run JS and Typescript tests.
2+
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
3+
4+
name: heuristic-table
5+
6+
on: [push, pull_request]
7+
8+
jobs:
9+
test:
10+
name: Testing
11+
runs-on: ubuntu-latest
12+
13+
strategy:
14+
matrix:
15+
node-version: [14.x]
16+
17+
steps:
18+
- uses: actions/checkout@v2
19+
- name: Use Node.js ${{ matrix.node-version }}
20+
uses: actions/setup-node@v1
21+
with:
22+
node-version: ${{ matrix.node-version }}
23+
- run: yarn install --immutable
24+
- run: yarn build:core
25+
name: Build core
26+
- run: yarn workspace @native-html/heuristic-table-plugin test:ts
27+
name: Typescript Tests
28+
- run: yarn workspace @native-html/heuristic-table-plugin test:lint
29+
name: Linting Tests
30+
- run: yarn workspace @native-html/heuristic-table-plugin test:jest --coverage
31+
name: Behavior Tests
32+
- run: yarn workspace @native-html/heuristic-table-plugin build
33+
name: Build
34+
- uses: codecov/codecov-action@v1
35+
with:
36+
flags: heuristic-table-plugin
37+
fail_ci_if_error: true

codecov.yml

+7
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ coverage:
1414
target: auto
1515
flags:
1616
- iframe-plugin
17+
heuristic-table-plugin:
18+
target: auto
19+
flags:
20+
- heuristic-table-plugin
1721
plugins-core:
1822
target: auto
1923
flags:
@@ -23,6 +27,9 @@ flags:
2327
table-plugin:
2428
paths:
2529
- packages/table-plugin/
30+
heuristic-table-plugin:
31+
paths:
32+
- packages/heuristic-table-plugin/
2633
iframe-plugin:
2734
paths:
2835
- packages/iframe-plugin/

example/App.js

+35
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
import SimpleExample from './SimpleExample';
2323
import CustomExample from './CustomExample';
2424
import YoutubeExample from './YoutubeExample';
25+
import HeuristicTableExample from './HeuristicTableExample';
2526

2627
const Stack = createStackNavigator();
2728

@@ -127,6 +128,24 @@ function YoutubeExampleScreen({ availableWidth, scalesPageToFit }) {
127128
);
128129
}
129130

131+
function HeuristicTableScreen({ availableWidth, onLinkPress }) {
132+
const [instance, setInstance] = useState(0);
133+
return (
134+
<ScrollView
135+
contentContainerStyle={styles.contentStyle}
136+
style={styles.scrollViewStyle}>
137+
<Button title="reload" onPress={() => setInstance((i) => i + 1)} />
138+
<View style={styles.example}>
139+
<HeuristicTableExample
140+
availableWidth={availableWidth}
141+
onLinkPress={onLinkPress}
142+
instance={instance}
143+
/>
144+
</View>
145+
</ScrollView>
146+
);
147+
}
148+
130149
function HomeScreen() {
131150
const navigation = useNavigation();
132151
return (
@@ -156,6 +175,12 @@ function HomeScreen() {
156175
onPress={() => navigation.navigate('YoutubeExampleScaleOff')}
157176
/>
158177
</View>
178+
<View style={styles.button}>
179+
<Button
180+
title="heuristic table example (alpha)"
181+
onPress={() => navigation.navigate('HeuristicTable')}
182+
/>
183+
</View>
159184
</View>
160185
);
161186
}
@@ -232,6 +257,16 @@ export default function App() {
232257
/>
233258
)}
234259
</Stack.Screen>
260+
<Stack.Screen
261+
name="HeuristicTable"
262+
options={{ title: 'Heuristic Table' }}>
263+
{() => (
264+
<HeuristicTableScreen
265+
onLinkPress={onLinkPress}
266+
availableWidth={availableWidth}
267+
/>
268+
)}
269+
</Stack.Screen>
235270
</Stack.Navigator>
236271
</NavigationContainer>
237272
<Portal>

example/HeuristicTableExample.js

+240
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
import React from 'react';
2+
import RenderHTML from 'react-native-render-html';
3+
import tableRenderers from '@native-html/heuristic-table-plugin';
4+
5+
const table1 = `
6+
7+
The heuristic table is a pure native table component which evaluates content of each cell (<code>TNode</code>) to
8+
compute the best width possible for the corresponding column. It doesn't follow strictly the table layout CSS standard,
9+
but it should be a good enough approximation for a majority of use cases.
10+
11+
<h2>Standard table</h2>
12+
13+
<table>
14+
<tr>
15+
<th>Index</th>
16+
<th>Company</th>
17+
<th>Contact</th>
18+
<th>Country</th>
19+
</tr>
20+
<tr>
21+
<td>1</td>
22+
<td>Alfreds Futterkiste website</td>
23+
<td>Maria Anders</td>
24+
<td><a class="a" href="https://en.wikipedia.org/wiki/germany">Germany</a></td>
25+
</tr>
26+
<tr>
27+
<td>2</td>
28+
<td>Centro comercial Moctezuma</td>
29+
<td>Francisco Chang</td>
30+
<td><a href="https://en.wikipedia.org/wiki/mexico">Mexico</a></td>
31+
</tr>
32+
<tr>
33+
<td>3</td>
34+
<td>Ernst Handel</td>
35+
<td>Roland Mendel</td>
36+
<td><a href="https://en.wikipedia.org/wiki/austria">Austria</a></td>
37+
</tr>
38+
<tr>
39+
<td>4</td>
40+
<td>Island Trading</td>
41+
<td>Helen Bennett</td>
42+
<td><a href="https://en.wikipedia.org/wiki/united_kingdom">UK</td>
43+
</tr>
44+
<tr>
45+
<td>5</td>
46+
<td>Laughing Bacchus Winecellars</td>
47+
<td>Yoshi Tannamuri</td>
48+
<td><a href="https://en.wikipedia.org/wiki/canada">Canada</a></td>
49+
</tr>
50+
<tr>
51+
<td>6</td>
52+
<td>Magazzini Alimentari Riuniti</td>
53+
<td>Giovanni Rovelli</td>
54+
<td><a href="https://en.wikipedia.org/wiki/italy">Italy</a></td>
55+
</tr>
56+
<tr>
57+
<td>7</td>
58+
<td>Alfreds Futterkiste website</td>
59+
<td>Maria Anders</td>
60+
<td><a href="https://en.wikipedia.org/wiki/germany">Germany</a></td>
61+
</tr>
62+
<tr>
63+
<td>8</td>
64+
<td>Centro comercial Moctezuma</td>
65+
<td>Francisco Chang</td>
66+
<td><a href="https://en.wikipedia.org/wiki/mexico">Mexico</a></td>
67+
</tr>
68+
<tr>
69+
<td>9</td>
70+
<td>Ernst Handel</td>
71+
<td>Roland Mendel</td>
72+
<td><a href="https://en.wikipedia.org/wiki/austria">Austria</a></td>
73+
</tr>
74+
<tr>
75+
<td>10</td>
76+
<td>Island Trading</td>
77+
<td>Helen Bennett</td>
78+
<td><a href="https://en.wikipedia.org/wiki/united_kingdom">UK</td>
79+
</tr>
80+
<tr>
81+
<td>11</td>
82+
<td>Laughing Bacchus Winecellars</td>
83+
<td>Yoshi Tannamuri</td>
84+
<td><a href="https://en.wikipedia.org/wiki/canada">Canada</a></td>
85+
</tr>
86+
<tr>
87+
<td>12</td>
88+
<td>Magazzini Alimentari Riuniti</td>
89+
<td>Giovanni Rovelli</td>
90+
<td><a href="https://en.wikipedia.org/wiki/italy">Italy</a></td>
91+
</tr>
92+
<tr>
93+
<td>13</td>
94+
<td>Alfreds Futterkiste website</td>
95+
<td>Maria Anders</td>
96+
<td><a href="https://en.wikipedia.org/wiki/germany">Germany</a></td>
97+
</tr>
98+
<tr>
99+
<td>14</td>
100+
<td>Centro comercial Moctezuma</td>
101+
<td>Francisco Chang</td>
102+
<td><a href="https://en.wikipedia.org/wiki/mexico">Mexico</a></td>
103+
</tr>
104+
</table>
105+
106+
<h2>Table with colspan cell</h2>
107+
108+
<table>
109+
<tr>
110+
<th>Month</th>
111+
<th>Savings</th>
112+
<th>Savings for holiday!</th>
113+
</tr>
114+
<tr>
115+
<td colspan="2">January</td>
116+
<td>$100</td>
117+
</tr>
118+
</table>
119+
120+
<h2>Table with rowspan cells (left)</h2>
121+
122+
<table>
123+
<tr>
124+
<th>Month</th>
125+
<th>Fortnight</th>
126+
<th>Savings</th>
127+
</tr>
128+
<tr>
129+
<td rowspan="2">January</td>
130+
<td>first</td>
131+
<td >$50</td>
132+
</tr>
133+
<tr>
134+
<td >second</td>
135+
<td>$80</td>
136+
</tr>
137+
</table>
138+
139+
<h2>Table with rowspan cell (right)</h2>
140+
141+
<table>
142+
<tr>
143+
<th>Month</th>
144+
<th>Savings</th>
145+
<th>Savings for holiday!</th>
146+
</tr>
147+
<tr>
148+
<td>January</td>
149+
<td>$100</td>
150+
<td rowspan="2">$50</td>
151+
</tr>
152+
<tr>
153+
<td>February</td>
154+
<td>$80</td>
155+
</tr>
156+
</table>
157+
158+
<h2>Table with rowspan cell (left and right)</h2>
159+
160+
<table>
161+
<tr>
162+
<th>Month</th>
163+
<th>Savings</th>
164+
<th>Savings for holiday!</th>
165+
</tr>
166+
<tr>
167+
<td rowspan="2">January</td>
168+
<td>$100</td>
169+
<td rowspan="2">$50</td>
170+
</tr>
171+
<tr>
172+
<td>$80</td>
173+
</tr>
174+
</table>
175+
176+
<p>
177+
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
178+
</p>
179+
`;
180+
181+
const htmlConfig = {
182+
renderers: tableRenderers,
183+
renderersProps: {
184+
table: {
185+
getStyleForCell(cell) {
186+
return cell.tnode.tagName === 'td'
187+
? {
188+
backgroundColor:
189+
cell.y % 2 > 0
190+
? 'rgba(65, 91, 118, .05)'
191+
: 'rgba(65, 91, 118, .30)'
192+
}
193+
: null;
194+
}
195+
}
196+
},
197+
tagsStyles: {
198+
a: {
199+
color: '#419edc',
200+
textDecorationColor: '#419edc'
201+
},
202+
table: {
203+
borderColor: '#dfdfdf',
204+
borderWidth: 0.5
205+
},
206+
th: {
207+
textAlign: 'center',
208+
backgroundColor: '#243445',
209+
color: '#fefefe',
210+
padding: 5,
211+
borderColor: '#2f455b',
212+
borderWidth: 0.5
213+
},
214+
td: {
215+
textAlign: 'center',
216+
padding: 5,
217+
borderColor: '#dfdfdf',
218+
borderWidth: 0.5
219+
}
220+
},
221+
defaultWebViewProps: {}
222+
};
223+
224+
export default function HeuristicTable({
225+
instance,
226+
onLinkPress,
227+
availableWidth
228+
}) {
229+
return (
230+
<RenderHTML
231+
key={`custom-${instance}`}
232+
source={{ html: table1 }}
233+
onLinkPress={onLinkPress}
234+
contentWidth={availableWidth}
235+
{...htmlConfig}
236+
debug={false}
237+
triggerTREInvalidationPropNames={['tagsStyles']}
238+
/>
239+
);
240+
}

example/package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
"eject": "expo eject"
1010
},
1111
"dependencies": {
12+
"@native-html/heuristic-table-plugin": "workspace:*",
13+
"@native-html/iframe-plugin": "workspace:*",
1214
"@native-html/table-plugin": "workspace:*",
1315
"@react-native-community/masked-view": "0.1.10",
1416
"@react-navigation/native": "^5.9.2",
@@ -22,7 +24,7 @@
2224
"react-native-gesture-handler": "~1.8.0",
2325
"react-native-paper": "^4.7.1",
2426
"react-native-reanimated": "~1.13.2",
25-
"react-native-render-html": "6.0.0-alpha.17",
27+
"react-native-render-html": "6.0.0-alpha.18",
2628
"react-native-safe-area-context": "3.1.9",
2729
"react-native-screens": "~2.15.2",
2830
"react-native-web": "~0.13.18",

0 commit comments

Comments
 (0)