[components,excel][m]: initial version of the <Excel /> component

This commit is contained in:
João Demenech
2023-07-10 17:44:11 -03:00
parent df000b9e8f
commit cbe693825c
4 changed files with 265 additions and 4 deletions

View File

@@ -37,6 +37,7 @@
"ol": "^7.4.0",
"papaparse": "^5.4.1",
"react": "^18.2.0",
"react-data-grid": "^7.0.0-beta.34",
"react-dom": "^18.2.0",
"react-hook-form": "^7.43.9",
"react-leaflet": "^4.2.1",
@@ -44,7 +45,8 @@
"react-vega": "^7.6.0",
"vega": "5.25.0",
"vega-lite": "5.1.0",
"vitest": "^0.31.4"
"vitest": "^0.31.4",
"xlsx": "^0.18.5"
},
"devDependencies": {
"@storybook/addon-essentials": "^7.0.7",

View File

@@ -0,0 +1,53 @@
import { useEffect, useState } from 'react';
import LoadingSpinner from './LoadingSpinner';
import { read, utils } from 'xlsx';
import DataGrid, { Column, textEditor } from 'react-data-grid';
import 'react-data-grid/lib/styles.css';
export type ExcelProps = {
url: string;
};
export function Excel({ url }: ExcelProps) {
const [isLoading, setIsLoading] = useState<boolean>(false);
const [rows, setRows] = useState<any>();
const [cols, setCols] = useState<any>();
useEffect(() => {
setIsLoading(true);
fetch(url)
.then((res) => res.arrayBuffer())
.then((f) => {
const wb = read(f);
const ws = wb.Sheets[wb.SheetNames[0]];
const rows = utils.sheet_to_json(ws, { header: 1 });
const range = utils.decode_range(ws['!ref'] || 'A1');
const columns = Array.from({ length: range.e.c + 1 }, (_, i) => ({
key: String(i),
name: utils.encode_col(i),
editor: textEditor,
}));
setRows(rows);
setCols(columns);
setIsLoading(false);
});
}, []);
return isLoading ? (
<div className="w-full flex items-center justify-center w-[600px] h-[300px]">
<LoadingSpinner />
</div>
) : (
<>
{cols && rows && (
<DataGrid columns={cols} rows={rows} onRowsChange={setRows} />
)}
</>
);
}

View File

@@ -0,0 +1,27 @@
import type { Meta, StoryObj } from '@storybook/react';
import { Excel, ExcelProps } from '../src/components/Excel';
// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction
const meta: Meta = {
title: 'Components/Excel',
component: Excel,
tags: ['autodocs'],
argTypes: {
url: {
description:
'Data to be displayed.\n\n E.g.: [["1990", 1], ["1991", 2]] \n\nOR\n\n "https://url.to/data.csv"',
},
},
};
export default meta;
type Story = StoryObj<ExcelProps>;
export const FromURL: Story = {
name: 'Excel spreadsheet from URL',
args: {
url: 'https://sheetjs.com/pres.xlsx',
},
};