diff --git a/strudel-components/README.md b/strudel-components/README.md index 0d6babed..00fe1fe5 100644 --- a/strudel-components/README.md +++ b/strudel-components/README.md @@ -1,30 +1,48 @@ -# React + TypeScript + Vite +# STRUDEL Components -This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. +STRUDEL Components are a set of react components that support people developing UI applications for the scientific community. They are built on top of [Material UI components](https://mui.com/) and aim to provide an extra layer of implementation to promote positive user experiences and usability standards. -Currently, two official plugins are available: +Key Features: +- Specialized data grid for displaying scientific data +- Chemical formula rendering component +- Filters component for managing complex filter states -- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh -- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh +[Check out the documentation on the STRUDEL Kit site.](https://strudel.science/strudel-kit/docs/components/overview) -## Expanding the ESLint configuration +They also provide the building blocks for the STRUDEL Task Flow templates. [Learn how to get started with the full templates](https://strudel.science/strudel-kit/docs/). -If you are developing a production application, we recommend updating the configuration to enable type aware lint rules: +## Install -- Configure the top-level `parserOptions` property like this: +``` +npm install @strudel-science/components +``` + +## Usage + +### [Examples](https://github.com/strudel-science/strudel-kit/tree/main/strudel-components/src/examples) + +### Import + +```js +import { SciDataGrid } from '@strudel-science/components'; +``` + +```js +import { Filters, FilterGroup, FilterField } from '@strudel-science/components'; +``` + +```js +import { LabelValueTable } from '@strudel-science/components'; +``` ```js -export default { - // other rules... - parserOptions: { - ecmaVersion: 'latest', - sourceType: 'module', - project: ['./tsconfig.json', './tsconfig.node.json'], - tsconfigRootDir: __dirname, - }, -} +import { Formula } from '@strudel-science/components'; ``` -- Replace `plugin:@typescript-eslint/recommended` to `plugin:@typescript-eslint/recommended-type-checked` or `plugin:@typescript-eslint/strict-type-checked` -- Optionally add `plugin:@typescript-eslint/stylistic-type-checked` -- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and add `plugin:react/recommended` & `plugin:react/jsx-runtime` to the `extends` list +```js +import { CheckboxList } from '@strudel-science/components'; +``` + +```js +import { PageHeader } from '@strudel-science/components'; +``` \ No newline at end of file diff --git a/strudel-components/lib/components/CheckboxList.tsx b/strudel-components/lib/components/CheckboxList.tsx index 10b4ccfc..dd58986e 100644 --- a/strudel-components/lib/components/CheckboxList.tsx +++ b/strudel-components/lib/components/CheckboxList.tsx @@ -1,7 +1,7 @@ import { Checkbox, FormControlLabel, FormGroup, FormGroupProps } from '@mui/material'; import React, { useEffect, useState } from 'react'; -type CheckboxOptionValue = string | number; +export type CheckboxOptionValue = string | number; export interface CheckboxOption { label: string; @@ -9,7 +9,7 @@ export interface CheckboxOption { } interface CheckboxListProps extends Omit { - values: string[] | number[] | null; + values: CheckboxOptionValue[] | null; options: CheckboxOption[]; onChange?: (values: CheckboxOptionValue[] | null) => any; } diff --git a/strudel-components/lib/main.tsx b/strudel-components/lib/main.tsx index 5ea6e0c1..d3a643e5 100644 --- a/strudel-components/lib/main.tsx +++ b/strudel-components/lib/main.tsx @@ -5,3 +5,9 @@ export { FilterField } from './components/FilterField' export { FilterGroup } from './components/FilterGroup' export { FilterContext } from './components/FilterContext' export { SciDataGrid } from './components/SciDataGrid' +export type { SciDataGridColDef } from './components/SciDataGrid' +export { Formula } from './components/Formula' +export { PageHeader } from './components/PageHeader' +export { CheckboxList } from './components/CheckboxList' +export type { CheckboxOptionValue, CheckboxOption } from './components/CheckboxList' + diff --git a/strudel-components/package-lock.json b/strudel-components/package-lock.json index a06aded0..7e1d6789 100644 --- a/strudel-components/package-lock.json +++ b/strudel-components/package-lock.json @@ -1,15 +1,12 @@ { - "name": "strudel-components", - "version": "0.0.0", + "name": "@strudel-science/components", + "version": "0.0.1", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "strudel-components", - "version": "0.0.0", - "dependencies": { - "@mui/x-data-grid": "^7.11.0" - }, + "name": "@strudel-science/components", + "version": "0.0.1", "devDependencies": { "@react-docgen/cli": "^2.0.3", "@types/node": "^20.12.7", @@ -31,6 +28,7 @@ "@emotion/styled": "^11.11.5", "@mui/icons-material": "^5.15.15", "@mui/material": "^5.15.15", + "@mui/x-data-grid": "^7.11.0", "@mui/x-date-pickers": "^7.11.0", "dayjs": "^1.11.12", "react": "^18.0.0", @@ -355,6 +353,7 @@ "version": "7.24.8", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.8.tgz", "integrity": "sha512-5F7SDGs1T72ZczbRwbGO9lQi0NLjQxzl6i4lJxLxfW9U5UluCSyEJeniWvnhl3/euNiqQVbo8zruhsDfid0esA==", + "peer": true, "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -451,6 +450,7 @@ "version": "11.11.0", "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz", "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==", + "peer": true, "dependencies": { "@emotion/memoize": "^0.8.1", "@emotion/sheet": "^1.2.2", @@ -477,7 +477,8 @@ "node_modules/@emotion/memoize": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", - "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==", + "peer": true }, "node_modules/@emotion/react": { "version": "11.11.4", @@ -519,7 +520,8 @@ "node_modules/@emotion/sheet": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", - "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==" + "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==", + "peer": true }, "node_modules/@emotion/styled": { "version": "11.11.5", @@ -562,12 +564,14 @@ "node_modules/@emotion/utils": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz", - "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==" + "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==", + "peer": true }, "node_modules/@emotion/weak-memoize": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", - "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" + "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==", + "peer": true }, "node_modules/@esbuild/aix-ppc64": { "version": "0.20.2", @@ -1431,6 +1435,7 @@ "version": "5.16.4", "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.16.4.tgz", "integrity": "sha512-ZsAm8cq31SJ37SVWLRlu02v9SRthxnfQofaiv14L5Bht51B0dz6yQEoVU/V8UduZDCCIrWkBHuReVfKhE/UuXA==", + "peer": true, "dependencies": { "@babel/runtime": "^7.23.9", "@mui/utils": "^5.16.4", @@ -1457,6 +1462,7 @@ "version": "5.16.4", "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.16.4.tgz", "integrity": "sha512-0+mnkf+UiAmTVB8PZFqOhqf729Yh0Cxq29/5cA3VAyDVTRIUUQ8FXQhiAhUIbijFmM72rY80ahFPXIm4WDbzcA==", + "peer": true, "dependencies": { "@babel/runtime": "^7.23.9", "@emotion/cache": "^11.11.0", @@ -1488,6 +1494,7 @@ "version": "5.16.4", "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.16.4.tgz", "integrity": "sha512-ET1Ujl2/8hbsD611/mqUuNArMCGv/fIWO/f8B3ZqF5iyPHM2aS74vhTNyjytncc4i6dYwGxNk+tLa7GwjNS0/w==", + "peer": true, "dependencies": { "@babel/runtime": "^7.23.9", "@mui/private-theming": "^5.16.4", @@ -1527,6 +1534,7 @@ "version": "7.2.15", "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.15.tgz", "integrity": "sha512-nbo7yPhtKJkdf9kcVOF8JZHPZTmqXjJ/tI0bdWgHg5tp9AnIN4Y7f7wm9T+0SyGYJk76+GYZ8Q5XaTYAsUHN0Q==", + "peer": true, "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0" }, @@ -1540,6 +1548,7 @@ "version": "5.16.4", "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.16.4.tgz", "integrity": "sha512-nlppYwq10TBIFqp7qxY0SvbACOXeOjeVL3pOcDsK0FT8XjrEXh9/+lkg8AEIzD16z7YfiJDQjaJG2OLkE7BxNg==", + "peer": true, "dependencies": { "@babel/runtime": "^7.23.9", "@types/prop-types": "^15.7.12", @@ -1568,6 +1577,7 @@ "version": "7.11.0", "resolved": "https://registry.npmjs.org/@mui/x-data-grid/-/x-data-grid-7.11.0.tgz", "integrity": "sha512-dXaIw3Noxc4d6xenS7J+zMPORG9ptkTW7B81P6QFovILSEuI/qebQhijy/IkqRvcCsuZYLL3nA89bp+EDI503Q==", + "peer": true, "dependencies": { "@babel/runtime": "^7.24.8", "@mui/system": "^5.16.2", @@ -1660,6 +1670,7 @@ "version": "7.11.0", "resolved": "https://registry.npmjs.org/@mui/x-internals/-/x-internals-7.11.0.tgz", "integrity": "sha512-GqCYylKiB4cLH9tK4JweJlT2JvPjnpXjS3TEIqtHB4BcSsezhdRrMGzHOO5zCJqkasqTirJh2t6X16Qw1llr4Q==", + "peer": true, "dependencies": { "@babel/runtime": "^7.24.8", "@mui/utils": "^5.16.2" @@ -2730,6 +2741,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "peer": true, "engines": { "node": ">=6" } @@ -3836,6 +3848,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "peer": true, "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, @@ -3956,6 +3969,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -4149,6 +4163,7 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "peer": true, "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -4158,7 +4173,8 @@ "node_modules/prop-types/node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "peer": true }, "node_modules/punycode": { "version": "2.3.1", @@ -4238,7 +4254,8 @@ "node_modules/react-is": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "peer": true }, "node_modules/react-refresh": { "version": "0.14.0", @@ -4268,12 +4285,14 @@ "node_modules/regenerator-runtime": { "version": "0.14.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "peer": true }, "node_modules/reselect": { "version": "4.1.8", "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.8.tgz", - "integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==" + "integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==", + "peer": true }, "node_modules/resolve": { "version": "1.22.8", @@ -4528,7 +4547,8 @@ "node_modules/stylis": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", - "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==", + "peer": true }, "node_modules/supports-color": { "version": "5.5.0", diff --git a/strudel-components/package.json b/strudel-components/package.json index bd1946f8..6e41ad7e 100644 --- a/strudel-components/package.json +++ b/strudel-components/package.json @@ -1,8 +1,12 @@ { - "name": "strudel-components", + "name": "@strudel-science/components", "private": true, - "version": "0.0.0", + "version": "0.0.1", "type": "module", + "repository": { + "type": "git", + "url": "https://github.com/strudel-science/strudel-kit/tree/main" + }, "scripts": { "start": "vite", "dev": "vite", diff --git a/strudel-components/src/examples/CheckboxList/CheckboxListEx.tsx b/strudel-components/src/examples/CheckboxList/CheckboxListEx.tsx new file mode 100644 index 00000000..491b30bc --- /dev/null +++ b/strudel-components/src/examples/CheckboxList/CheckboxListEx.tsx @@ -0,0 +1,28 @@ +import { useState } from "react"; +import { CheckboxList } from "../../../lib/main" +import { CheckboxOptionValue } from "../../../lib/components/CheckboxList"; + +export const CheckboxListEx: React.FC = () => { + const [values, setValues] = useState(null); + + const handleChange = (values: CheckboxOptionValue[] | null) => { + setValues(values); + } + + return ( + + ) +} \ No newline at end of file diff --git a/strudel-components/src/examples/Formula/FormulaEx.tsx b/strudel-components/src/examples/Formula/FormulaEx.tsx new file mode 100644 index 00000000..152ee311 --- /dev/null +++ b/strudel-components/src/examples/Formula/FormulaEx.tsx @@ -0,0 +1,7 @@ +import { Formula } from "../../../lib/main" + +export const FormulaEx: React.FC = () => { + return ( + + ) +} \ No newline at end of file diff --git a/strudel-components/src/examples/LabelValueTable/LabelValueTableEx.tsx b/strudel-components/src/examples/LabelValueTable/LabelValueTableEx.tsx new file mode 100644 index 00000000..081d8fd2 --- /dev/null +++ b/strudel-components/src/examples/LabelValueTable/LabelValueTableEx.tsx @@ -0,0 +1,22 @@ +import { LabelValueTable } from "../../../lib/main" + +export const LabelValueTableEx: React.FC = () => { + return ( + + ) +} \ No newline at end of file diff --git a/strudel-components/src/examples/LabelValueTable/index.tsx b/strudel-components/src/examples/LabelValueTable/index.tsx deleted file mode 100644 index e69de29b..00000000 diff --git a/strudel-components/src/examples/SciDataGrid/SciDataGridEx.tsx b/strudel-components/src/examples/SciDataGrid/SciDataGridEx.tsx index adb1a7d7..984d25d2 100644 --- a/strudel-components/src/examples/SciDataGrid/SciDataGridEx.tsx +++ b/strudel-components/src/examples/SciDataGrid/SciDataGridEx.tsx @@ -1,15 +1,12 @@ -import { DataGrid } from "@mui/x-data-grid"; import { SciDataGrid, SciDataGridColDef } from "../../../lib/components/SciDataGrid"; export const SciDataGridEx = () => { return ( - <> - row['Name']} - /> - + row['Name']} + /> ) }