add SheetJS integration example and fix table component styling

- Clean up ExampleFive component by removing unused elements
- Improve cell layout and alignment in various table components
- Improve cell layout and alignment in various table components
This commit is contained in:
Asad Karimov 2025-03-10 00:51:36 -04:00
parent 6bc0ecd739
commit 214467ac82
11 changed files with 25244 additions and 67 deletions

BIN
example/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

@ -15,7 +15,8 @@
"react": "18.3.1",
"react-dom": "18.3.1",
"react-native": "0.76.7",
"react-native-web": "~0.19.13"
"react-native-web": "~0.19.13",
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz"
},
"devDependencies": {
"@babel/core": "^7.20.0",

@ -5,6 +5,7 @@ import { ExampleThree } from './ExampleThree';
import { StickyTableExample } from './StickyColumnExample';
import { ExampleFour } from './ExampleFour';
import { ExampleFive } from './ExampleFive';
import SheetJSExample from './SheetJSExample';
export default function App() {
return (
@ -42,6 +43,15 @@ export default function App() {
<Text style={styles.subheading}>Example Five</Text>
<ExampleFive />
</View>
<View style={styles.section}>
<Text style={styles.subheading}>Example Five</Text>
<ExampleFive />
</View>
<View style={styles.section}>
<Text style={styles.subheading}>SheetJS Example</Text>
<SheetJSExample />
</View>
</ScrollView>
);
}

@ -1,25 +1,8 @@
import React, { useState } from 'react';
import { StyleSheet, View, Text, TouchableOpacity, Alert } from 'react-native';
import { Table, TableWrapper, Row, Col, Rows } from 'react-native-tabeller';
import { StyleSheet, View } from 'react-native';
import { Table, TableWrapper, Col, Rows } from 'react-native-tabeller';
export const ExampleFive: React.FC = () => {
const alertIndex = (value: string): void => {
Alert.alert(`This is column ${value}`);
};
const elementButton = (value: string): React.ReactElement => (
<TouchableOpacity onPress={() => alertIndex(value)}>
<View style={styles.btn}>
<Text style={styles.btnText}>button</Text>
</View>
</TouchableOpacity>
);
const [tableHead] = useState<any[]>([
'',
elementButton('1'),
elementButton('2'),
elementButton('3'),
]);
const [sideHead] = useState<string[]>(['H1', 'H2']);
const [rowTitles] = useState<string[]>([
'Title',
@ -40,12 +23,7 @@ export const ExampleFive: React.FC = () => {
<View style={styles.container}>
<Table borderStyle={{ borderWidth: 1, borderColor: '#C1C0B9' }}>
{/* table header row with buttons */}
<Row
data={tableHead}
style={styles.header}
textStyle={styles.headerText}
flexArr={[1, 1, 1, 1]}
/>
<TableWrapper style={styles.wrapper}>
{/* left column with H1, H2 */}
<Col
@ -84,8 +62,10 @@ const styles = StyleSheet.create({
backgroundColor: '#fff',
},
header: {
height: 40,
height: 50,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
headerText: {
textAlign: 'center',
@ -122,15 +102,20 @@ const styles = StyleSheet.create({
},
btn: {
width: 58,
height: 18,
height: 30,
backgroundColor: '#c8e1ff',
borderRadius: 2,
alignSelf: 'center',
justifyContent: 'center',
alignItems: 'center',
},
btnText: {
textAlign: 'center',
fontSize: 12,
},
centered: {
justifyContent: 'center',
alignItems: 'center',
},
});
export default ExampleFive;

@ -0,0 +1,98 @@
/* sheetjs (C) SheetJS -- https://sheetjs.com */
import { useState, useCallback } from 'react';
import { StyleSheet, Text, Button, Alert, ScrollView, Image } from 'react-native';
import { Table, Row, Rows, TableWrapper } from 'react-native-tabeller';
import { read, utils, WorkSheet } from 'xlsx';
const make_width = (ws: WorkSheet): number[] => {
const aoa = utils.sheet_to_json(ws, { header: 1 }),
res: number[] = [];
aoa.forEach((r) => {
r.forEach((c, C) => {
res[C] = Math.max(res[C] || 60, String(c).length * 10);
});
});
for (let C = 0; C < res.length; ++C) if (!res[C]) res[C] = 60;
return res;
};
function SheetJSExample(): JSX.Element {
const [data, setData] = useState<any[]>([
'SheetJS'.split(''),
[5, 4, 3, 3, 7, 9, 5],
[8, 6, 7, 5, 3, 0, 9],
]);
const [widths, setWidths] = useState<number[]>(
Array.from({ length: 7 }, () => 20)
);
const importFile = useCallback(async () => {
try {
const ab = await (
await fetch('https://docs.sheetjs.com/pres.numbers')
).arrayBuffer();
const wb = read(ab);
/* convert first worksheet to AOA */
const wsname = wb.SheetNames[0];
const ws = wb.Sheets[wsname];
const data = utils.sheet_to_json(ws, { header: 1 });
/* update state */
setData(data);
setWidths(make_width(ws));
} catch (err) {
Alert.alert('importFile Error', 'Error ' + ((err as any).message || err));
}
}, []);
return (
<ScrollView contentContainerStyle={styles.container}>
<Text style={styles.welcome}> </Text>
<Button
onPress={importFile}
title="Import data from a spreadsheet"
color="#841584"
/>
<Text style={styles.bolded}>Current Data</Text>
<ScrollView style={styles.table} horizontal={true}>
<Table style={styles.table}>
<TableWrapper>
<Row
data={data[0]}
style={styles.thead}
textStyle={styles.text}
widthArr={widths.map((x) => x * 1.2)}
/>
</TableWrapper>
<ScrollView>
<TableWrapper>
<Rows
data={data.slice(1)}
style={styles.tr}
textStyle={styles.text}
widthArr={widths.map((x) => x * 1.2)}
/>
</TableWrapper>
</ScrollView>
</Table>
</ScrollView>
</ScrollView>
);
}
const styles = StyleSheet.create({
container: { backgroundColor: '#F5FCFF' },
welcome: { fontSize: 20, textAlign: 'center', margin: 10 },
bolded: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
fontWeight: 'bold',
},
thead: { height: 40, backgroundColor: '#f1f8ff' },
tr: { height: 30 },
text: { marginLeft: 5 },
table: { width: '100%' },
image: { height: 16, width: 16 },
});
export default SheetJSExample;

25095
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

@ -60,22 +60,12 @@ export const Cell: FC<PropsWithChildren<CellProps>> = ({
onPress={onPress ? () => onPress(data) : undefined}
disabled={!onPress}
>
<View style={[styles.touchableContainer, style]}>{textDom}</View>
{textDom}
</TouchableWithoutFeedback>
</View>
);
};
const styles = StyleSheet.create({
cell: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
touchableContainer: {
flex: 1,
width: '100%',
justifyContent: 'center',
alignItems: 'center',
},
cell: { flex: 1 },
});

@ -30,7 +30,6 @@ export const StickyTable: React.FC<StickyTableProps> = ({
<View
key={`sticky-${rowIndex}`}
style={[
styles.cell,
cellStyle,
isHeader && headerStyle,
borderStyle && {
@ -74,7 +73,6 @@ export const StickyTable: React.FC<StickyTableProps> = ({
<View
key={`cell-${rowIndex}-${cellIndex}`}
style={[
styles.cell,
cellStyle,
isHeader && headerStyle,
{ width: colWidth },
@ -111,7 +109,6 @@ const styles = StyleSheet.create({
},
stickyColumn: {
zIndex: 1,
backgroundColor: 'white',
elevation: 3,
},
scrollView: {
@ -120,10 +117,4 @@ const styles = StyleSheet.create({
row: {
flexDirection: 'row',
},
cell: {
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'white',
overflow: 'hidden',
},
});

@ -32,7 +32,6 @@ export const Table: FC<TableProps> = ({ style, borderStyle, children }) => {
return (
<View
style={StyleSheet.flatten([
styles.table,
style,
{
borderLeftWidth,
@ -73,9 +72,6 @@ export const TableWrapper: FC<TableWrapperProps> = ({
};
const styles = StyleSheet.create({
table: {
overflow: 'hidden',
},
wrapper: {
flex: 1,
},

@ -4501,7 +4501,7 @@ __metadata:
languageName: node
linkType: hard
"call-bound@npm:^1.0.2, call-bound@npm:^1.0.3":
"call-bound@npm:^1.0.2, call-bound@npm:^1.0.3, call-bound@npm:^1.0.4":
version: 1.0.4
resolution: "call-bound@npm:1.0.4"
dependencies:
@ -4588,9 +4588,9 @@ __metadata:
linkType: hard
"caniuse-lite@npm:^1.0.30001688":
version: 1.0.30001702
resolution: "caniuse-lite@npm:1.0.30001702"
checksum: ba8e88f0ef09a16f36de805c9491c3047986ab6bb1e0dc66f03067dce5e197be1c98cfaed21867bad851985f775b8d4fa50e7e37537c116a5fe1ae623dfd400c
version: 1.0.30001703
resolution: "caniuse-lite@npm:1.0.30001703"
checksum: f3c19e357df7f5ff480a8a24a61213d1442bf3df9e2f9563a47f4c95e9c08ea7d3c8faa965bc84dcc57c569542584c965b30d552d9b35e421f352c974980de17
languageName: node
linkType: hard
@ -4700,9 +4700,9 @@ __metadata:
linkType: hard
"ci-info@npm:^4.1.0":
version: 4.1.0
resolution: "ci-info@npm:4.1.0"
checksum: dcf286abdc1bb1c4218b91e4a617b49781b282282089b7188e1417397ea00c6b967848e2360fb9a6b10021bf18a627f20ef698f47c2c9c875aeffd1d2ea51d1e
version: 4.2.0
resolution: "ci-info@npm:4.2.0"
checksum: 0e3726721526f54c5b17cf44ab2ed69b842c756bcb4d2b26ce279e595a80a856aec9fb38a2986a2baca3de73d15895f3a01d2771c4aad93c898aae7e3ca0ceb1
languageName: node
linkType: hard
@ -6908,7 +6908,7 @@ __metadata:
languageName: node
linkType: hard
"for-each@npm:^0.3.3":
"for-each@npm:^0.3.3, for-each@npm:^0.3.5":
version: 0.3.5
resolution: "for-each@npm:0.3.5"
dependencies:
@ -11796,6 +11796,7 @@ __metadata:
react-native: 0.76.7
react-native-builder-bob: ^0.37.0
react-native-web: ~0.19.13
xlsx: "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz"
languageName: unknown
linkType: soft
@ -14311,16 +14312,17 @@ __metadata:
linkType: hard
"which-typed-array@npm:^1.1.16, which-typed-array@npm:^1.1.18":
version: 1.1.18
resolution: "which-typed-array@npm:1.1.18"
version: 1.1.19
resolution: "which-typed-array@npm:1.1.19"
dependencies:
available-typed-arrays: ^1.0.7
call-bind: ^1.0.8
call-bound: ^1.0.3
for-each: ^0.3.3
call-bound: ^1.0.4
for-each: ^0.3.5
get-proto: ^1.0.1
gopd: ^1.2.0
has-tostringtag: ^1.0.2
checksum: d2feea7f51af66b3a240397aa41c796585033e1069f18e5b6d4cd3878538a1e7780596fd3ea9bf347c43d9e98e13be09b37d9ea3887cef29b11bc291fd47bb52
checksum: 162d2a07f68ea323f88ed9419861487ce5d02cb876f2cf9dd1e428d04a63133f93a54f89308f337b27cabd312ee3d027cae4a79002b2f0a85b79b9ef4c190670
languageName: node
linkType: hard
@ -14531,6 +14533,15 @@ __metadata:
languageName: node
linkType: hard
"xlsx@https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz":
version: 0.20.3
resolution: "xlsx@https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz"
bin:
xlsx: ./bin/xlsx.njs
checksum: c08ac699e6d31222404871240aa2c2804cb8bae59f0bea08d3293e99756cf0d3122fd34739189edaae1d9b0b493bbb8eb95d021950ee7b5cba9d55ecd6fcb4e4
languageName: node
linkType: hard
"xml2js@npm:0.6.0":
version: 0.6.0
resolution: "xml2js@npm:0.6.0"