From 2ffa9bee87b1a1d63477a57bae11aab63c2481d0 Mon Sep 17 00:00:00 2001 From: clarasb Date: Tue, 28 Jan 2025 11:26:11 +0100 Subject: [PATCH 01/15] add multiple to select component --- chartlets.js/packages/lib/src/plugins/mui/Select.tsx | 3 +++ chartlets.py/chartlets/components/select.py | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/chartlets.js/packages/lib/src/plugins/mui/Select.tsx b/chartlets.js/packages/lib/src/plugins/mui/Select.tsx index 1cae59fd..4094d9f3 100644 --- a/chartlets.js/packages/lib/src/plugins/mui/Select.tsx +++ b/chartlets.js/packages/lib/src/plugins/mui/Select.tsx @@ -16,6 +16,7 @@ export type SelectOption = interface SelectState extends ComponentState { options?: SelectOption[]; + multiple?: boolean } interface SelectProps extends ComponentProps, SelectState {} @@ -30,6 +31,7 @@ export function Select({ style, tooltip, label, + multiple, onChange, }: SelectProps) { const handleChange = (event: SelectChangeEvent) => { @@ -56,6 +58,7 @@ export function Select({ name={name} value={`${value}`} disabled={disabled} + multiple={multiple} onChange={handleChange} > {Array.isArray(options) && diff --git a/chartlets.py/chartlets/components/select.py b/chartlets.py/chartlets/components/select.py index c5e0be7c..89854fad 100644 --- a/chartlets.py/chartlets/components/select.py +++ b/chartlets.py/chartlets/components/select.py @@ -13,6 +13,11 @@ class Select(Component): """Select components are used for collecting user provided information from a list of options.""" + multiple: bool | None = None + """Allows for multiple selection in Select Menu. If `true` value + must be an array. + """ + options: list[SelectOption] = field(default_factory=list) """The options given as a list of number or text values or a list of (value, label) pairs. From e1677bf8d84d65036d53f0295b61bc189fb9d971 Mon Sep 17 00:00:00 2001 From: clarasb Date: Tue, 28 Jan 2025 12:51:52 +0100 Subject: [PATCH 02/15] update changes.md and formatting --- chartlets.js/CHANGES.md | 5 + .../packages/lib/src/plugins/mui/Select.tsx | 129 +++++++++--------- chartlets.py/CHANGES.md | 4 + 3 files changed, 73 insertions(+), 65 deletions(-) diff --git a/chartlets.js/CHANGES.md b/chartlets.js/CHANGES.md index 5e0d1532..dc4d603d 100644 --- a/chartlets.js/CHANGES.md +++ b/chartlets.js/CHANGES.md @@ -1,3 +1,8 @@ +## Version 0.1.4 (in development) + +* Add `multiple` property for `Select` component to enable the + of multiple elements. + ## Version 0.1.0 (in development) * Reorganised Chartlets project to better separate demo from library code. diff --git a/chartlets.js/packages/lib/src/plugins/mui/Select.tsx b/chartlets.js/packages/lib/src/plugins/mui/Select.tsx index 4094d9f3..77532dee 100644 --- a/chartlets.js/packages/lib/src/plugins/mui/Select.tsx +++ b/chartlets.js/packages/lib/src/plugins/mui/Select.tsx @@ -8,81 +8,80 @@ import { isString } from "@/utils/isString"; import { Tooltip } from "./Tooltip"; export type SelectOption = - | string - | number - | [string, string] - | [number, string] - | { value: string | number; label?: string }; + | string + | number + | [string, string] + | [number, string] + | { value: string | number; label?: string }; interface SelectState extends ComponentState { - options?: SelectOption[]; - multiple?: boolean + options?: SelectOption[]; + multiple?: boolean; } interface SelectProps extends ComponentProps, SelectState {} export function Select({ - type, - id, - name, - value, - options, - disabled, - style, - tooltip, - label, - multiple, - onChange, + type, + id, + name, + value, + options, + disabled, + style, + tooltip, + label, + multiple, + onChange, }: SelectProps) { - const handleChange = (event: SelectChangeEvent) => { - if (id) { - let newValue: string | number = event.target.value; - if (typeof value == "number") { - newValue = Number.parseInt(newValue); - } - onChange({ - componentType: type, - id: id, - property: "value", - value: newValue, - }); - } - }; - return ( - - - {label && {label}} - - {Array.isArray(options) && - options.map(normalizeSelectOption).map(([value, text], index) => ( - - {text} - - ))} - - - - ); + const handleChange = (event: SelectChangeEvent) => { + if (id) { + let newValue: string | number = event.target.value; + if (typeof value == "number") { + newValue = Number.parseInt(newValue); + } + onChange({ + componentType: type, + id: id, + property: "value", + value: newValue, + }); + } + }; + return ( + + + {label && {label}} + + {Array.isArray(options) && + options.map(normalizeSelectOption).map(([value, text], index) => ( + + {text} + + ))} + + + + ); } function normalizeSelectOption( - option: SelectOption, + option: SelectOption ): [string | number, string] { - if (isString(option)) { - return [option, option]; - } else if (typeof option === "number") { - return [option, option.toString()]; - } else if (Array.isArray(option)) { - return option; - } else { - return [option.value, option.label || `${option.value}`]; - } + if (isString(option)) { + return [option, option]; + } else if (typeof option === "number") { + return [option, option.toString()]; + } else if (Array.isArray(option)) { + return option; + } else { + return [option.value, option.label || `${option.value}`]; + } } diff --git a/chartlets.py/CHANGES.md b/chartlets.py/CHANGES.md index c82683d7..721853bf 100644 --- a/chartlets.py/CHANGES.md +++ b/chartlets.py/CHANGES.md @@ -1,4 +1,8 @@ +## Version 0.1.4 (in development) +* Add `multiple` property for `Select` component to enable the + of multiple elements. + ## Version 0.1.0 (from 2025/01/14) * Reorganised Chartlets project to better separate demo from library code. From da67e206c122e6db63f7b10dc5cc35602f85e366 Mon Sep 17 00:00:00 2001 From: clarasb Date: Mon, 10 Feb 2025 10:59:39 +0100 Subject: [PATCH 03/15] update --- chartlets.js/packages/lib/src/plugins/mui/Select.tsx | 3 +++ chartlets.py/chartlets/component.py | 2 +- chartlets.py/demo/my_extension/my_panel_2.py | 3 ++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/chartlets.js/packages/lib/src/plugins/mui/Select.tsx b/chartlets.js/packages/lib/src/plugins/mui/Select.tsx index 77532dee..6fce3755 100644 --- a/chartlets.js/packages/lib/src/plugins/mui/Select.tsx +++ b/chartlets.js/packages/lib/src/plugins/mui/Select.tsx @@ -1,3 +1,4 @@ +import * as React from "react"; import MuiFormControl from "@mui/material/FormControl"; import MuiInputLabel from "@mui/material/InputLabel"; import MuiMenuItem from "@mui/material/MenuItem"; @@ -34,6 +35,8 @@ export function Select({ multiple, onChange, }: SelectProps) { + const [personName, setPersonName] = React.useState([]); + const handleChange = (event: SelectChangeEvent) => { if (id) { let newValue: string | number = event.target.value; diff --git a/chartlets.py/chartlets/component.py b/chartlets.py/chartlets/component.py index 32be433d..08dbf1d1 100644 --- a/chartlets.py/chartlets/component.py +++ b/chartlets.py/chartlets/component.py @@ -19,7 +19,7 @@ class Component(ABC): name: str | None = None """HTML `name` attribute. Optional.""" - value: bool | int | float | str | None = None + value: bool | int | float | str | list[bool | int | float | str] | None = None """HTML `value` attribute. Required for specific components.""" style: dict[str, Any] | None = None diff --git a/chartlets.py/demo/my_extension/my_panel_2.py b/chartlets.py/demo/my_extension/my_panel_2.py index 8ce2f2dd..5a13b54d 100644 --- a/chartlets.py/demo/my_extension/my_panel_2.py +++ b/chartlets.py/demo/my_extension/my_panel_2.py @@ -24,10 +24,11 @@ def render_panel( ) select = Select( id="selected_variable_name", - value=var_name, + value=[var_name], label="Variable", options=[(v, v) for v in variable_names], style={"flexGrow": 0, "minWidth": 120}, + multiple=True, tooltip="Select the variable of the test dataset to be used", ) control_group = Box( From f8c9f6ef725804d466b16c05ded83f3c35092eee Mon Sep 17 00:00:00 2001 From: clarasb Date: Mon, 17 Feb 2025 17:19:47 +0100 Subject: [PATCH 04/15] add demo panel E --- chartlets.py/demo/my_extension/my_panel_5.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 chartlets.py/demo/my_extension/my_panel_5.py diff --git a/chartlets.py/demo/my_extension/my_panel_5.py b/chartlets.py/demo/my_extension/my_panel_5.py new file mode 100644 index 00000000..e69de29b From fc343b0e9aeca4e4b41726443e5f62efb538ff03 Mon Sep 17 00:00:00 2001 From: clarasb Date: Mon, 17 Feb 2025 17:20:13 +0100 Subject: [PATCH 05/15] add demo panel E --- chartlets.js/package-lock.json | 117 ++++++++---------- .../packages/lib/src/plugins/mui/Select.tsx | 31 ++--- chartlets.py/demo/my_extension/__init__.py | 2 + chartlets.py/demo/my_extension/my_panel_2.py | 3 +- chartlets.py/demo/my_extension/my_panel_5.py | 99 +++++++++++++++ 5 files changed, 170 insertions(+), 82 deletions(-) diff --git a/chartlets.js/package-lock.json b/chartlets.js/package-lock.json index f8d5105e..30a0b905 100644 --- a/chartlets.js/package-lock.json +++ b/chartlets.js/package-lock.json @@ -2020,12 +2020,11 @@ } }, "node_modules/@swc/core": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.10.1.tgz", - "integrity": "sha512-rQ4dS6GAdmtzKiCRt3LFVxl37FaY1cgL9kSUTnhQ2xc3fmHOd7jdJK/V4pSZMG1ruGTd0bsi34O2R0Olg9Zo/w==", + "version": "1.10.16", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.10.16.tgz", + "integrity": "sha512-nOINg/OUcZazCW7B55QV2/UB8QAqz9FYe4+z229+4RYboBTZ102K7ebOEjY5sKn59JgAkhjZTz+5BKmXpDFopw==", "dev": true, "hasInstallScript": true, - "license": "Apache-2.0", "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.17" @@ -2038,16 +2037,16 @@ "url": "https://opencollective.com/swc" }, "optionalDependencies": { - "@swc/core-darwin-arm64": "1.10.1", - "@swc/core-darwin-x64": "1.10.1", - "@swc/core-linux-arm-gnueabihf": "1.10.1", - "@swc/core-linux-arm64-gnu": "1.10.1", - "@swc/core-linux-arm64-musl": "1.10.1", - "@swc/core-linux-x64-gnu": "1.10.1", - "@swc/core-linux-x64-musl": "1.10.1", - "@swc/core-win32-arm64-msvc": "1.10.1", - "@swc/core-win32-ia32-msvc": "1.10.1", - "@swc/core-win32-x64-msvc": "1.10.1" + "@swc/core-darwin-arm64": "1.10.16", + "@swc/core-darwin-x64": "1.10.16", + "@swc/core-linux-arm-gnueabihf": "1.10.16", + "@swc/core-linux-arm64-gnu": "1.10.16", + "@swc/core-linux-arm64-musl": "1.10.16", + "@swc/core-linux-x64-gnu": "1.10.16", + "@swc/core-linux-x64-musl": "1.10.16", + "@swc/core-win32-arm64-msvc": "1.10.16", + "@swc/core-win32-ia32-msvc": "1.10.16", + "@swc/core-win32-x64-msvc": "1.10.16" }, "peerDependencies": { "@swc/helpers": "*" @@ -2059,14 +2058,13 @@ } }, "node_modules/@swc/core-darwin-arm64": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.10.1.tgz", - "integrity": "sha512-NyELPp8EsVZtxH/mEqvzSyWpfPJ1lugpTQcSlMduZLj1EASLO4sC8wt8hmL1aizRlsbjCX+r0PyL+l0xQ64/6Q==", + "version": "1.10.16", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.10.16.tgz", + "integrity": "sha512-iikIxwqCQ4Bvz79vJ4ELh26efPf1u5D9TFdmXSJUBs7C3mmMHvk5zyWD9A9cTowXiW6WHs2gE58U1R9HOTTIcg==", "cpu": [ "arm64" ], "dev": true, - "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "darwin" @@ -2076,14 +2074,13 @@ } }, "node_modules/@swc/core-darwin-x64": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.10.1.tgz", - "integrity": "sha512-L4BNt1fdQ5ZZhAk5qoDfUnXRabDOXKnXBxMDJ+PWLSxOGBbWE6aJTnu4zbGjJvtot0KM46m2LPAPY8ttknqaZA==", + "version": "1.10.16", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.10.16.tgz", + "integrity": "sha512-R2Eb9aktWd62vPfW9H/c/OaQ0e94iURibBo4uzUUcgxNNmB4+wb6piKbHxGdr/5bEsT+vJ1lwZFSRzfb45E7DA==", "cpu": [ "x64" ], "dev": true, - "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "darwin" @@ -2093,14 +2090,13 @@ } }, "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.10.1.tgz", - "integrity": "sha512-Y1u9OqCHgvVp2tYQAJ7hcU9qO5brDMIrA5R31rwWQIAKDkJKtv3IlTHF0hrbWk1wPR0ZdngkQSJZple7G+Grvw==", + "version": "1.10.16", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.10.16.tgz", + "integrity": "sha512-mkqN3HBAMnuiSGZ/k2utScuH8rAPshvNj0T1LjBWon+X9DkMNHSA+aMLdWsy0yZKF1zjOPc4L3Uq2l2wzhUlzA==", "cpu": [ "arm" ], "dev": true, - "license": "Apache-2.0", "optional": true, "os": [ "linux" @@ -2110,14 +2106,13 @@ } }, "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.10.1.tgz", - "integrity": "sha512-tNQHO/UKdtnqjc7o04iRXng1wTUXPgVd8Y6LI4qIbHVoVPwksZydISjMcilKNLKIwOoUQAkxyJ16SlOAeADzhQ==", + "version": "1.10.16", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.10.16.tgz", + "integrity": "sha512-PH/+q/L5nVZJ91CU07CL6Q9Whs6iR6nneMZMAgtVF9Ix8ST0cWVItdUhs6D38kFklCFhaOrpHhS01HlMJ72vWw==", "cpu": [ "arm64" ], "dev": true, - "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "linux" @@ -2127,14 +2122,13 @@ } }, "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.10.1.tgz", - "integrity": "sha512-x0L2Pd9weQ6n8dI1z1Isq00VHFvpBClwQJvrt3NHzmR+1wCT/gcYl1tp9P5xHh3ldM8Cn4UjWCw+7PaUgg8FcQ==", + "version": "1.10.16", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.10.16.tgz", + "integrity": "sha512-1169+C9XbydKKc6Ec1XZxTGKtHjZHDIFn0r+Nqp/QSVwkORrOY1Vz2Hdu7tn/lWMg36ZkGePS+LnnyV67s/7yg==", "cpu": [ "arm64" ], "dev": true, - "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "linux" @@ -2144,14 +2138,13 @@ } }, "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.10.1.tgz", - "integrity": "sha512-yyYEwQcObV3AUsC79rSzN9z6kiWxKAVJ6Ntwq2N9YoZqSPYph+4/Am5fM1xEQYf/kb99csj0FgOelomJSobxQA==", + "version": "1.10.16", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.10.16.tgz", + "integrity": "sha512-n2rV0XwkjoHn4MDJmpYp5RBrnyi94/6GsJVpbn6f+/eqSrZn3mh3dT7pdZc9zCN1Qp9eDHo+uI6e/wgvbL22uA==", "cpu": [ "x64" ], "dev": true, - "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "linux" @@ -2161,14 +2154,13 @@ } }, "node_modules/@swc/core-linux-x64-musl": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.10.1.tgz", - "integrity": "sha512-tcaS43Ydd7Fk7sW5ROpaf2Kq1zR+sI5K0RM+0qYLYYurvsJruj3GhBCaiN3gkzd8m/8wkqNqtVklWaQYSDsyqA==", + "version": "1.10.16", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.10.16.tgz", + "integrity": "sha512-EevCpwreBrkPrJjQVIbiM81lK42ukNNSlBmrSRxxbx2V9VGmOd5qxX0cJBn0TRRSLIPi62BuMS76F9iYjqsjgg==", "cpu": [ "x64" ], "dev": true, - "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "linux" @@ -2178,14 +2170,13 @@ } }, "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.10.1.tgz", - "integrity": "sha512-D3Qo1voA7AkbOzQ2UGuKNHfYGKL6eejN8VWOoQYtGHHQi1p5KK/Q7V1ku55oxXBsj79Ny5FRMqiRJpVGad7bjQ==", + "version": "1.10.16", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.10.16.tgz", + "integrity": "sha512-BvE7RWAnKJeELVQWLok6env5I4GUVBTZSvaSN/VPgxnTjF+4PsTeQptYx0xCYhp5QCv68wWYsBnZKuPDS+SBsw==", "cpu": [ "arm64" ], "dev": true, - "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "win32" @@ -2195,14 +2186,13 @@ } }, "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.10.1.tgz", - "integrity": "sha512-WalYdFoU3454Og+sDKHM1MrjvxUGwA2oralknXkXL8S0I/8RkWZOB++p3pLaGbTvOO++T+6znFbQdR8KRaa7DA==", + "version": "1.10.16", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.10.16.tgz", + "integrity": "sha512-7Jf/7AeCgbLR/JsQgMJuacHIq4Jeie3knf6+mXxn8aCvRypsOTIEu0eh7j24SolOboxK1ijqJ86GyN1VA2Rebg==", "cpu": [ "ia32" ], "dev": true, - "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "win32" @@ -2212,14 +2202,13 @@ } }, "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.10.1.tgz", - "integrity": "sha512-JWobfQDbTnoqaIwPKQ3DVSywihVXlQMbDuwik/dDWlj33A8oEHcjPOGs4OqcA3RHv24i+lfCQpM3Mn4FAMfacA==", + "version": "1.10.16", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.10.16.tgz", + "integrity": "sha512-p0blVm0R8bjaTtmW+FoPmLxLSQdRNbqhuWcR/8g80OzMSkka9mk5/J3kn/5JRVWh+MaR9LHRHZc1Q1L8zan13g==", "cpu": [ "x64" ], "dev": true, - "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "win32" @@ -2232,15 +2221,13 @@ "version": "0.1.3", "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", - "dev": true, - "license": "Apache-2.0" + "dev": true }, "node_modules/@swc/types": { "version": "0.1.17", "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.17.tgz", "integrity": "sha512-V5gRru+aD8YVyCOMAjMpWR1Ui577DD5KSJsHP8RAxopAH22jFz6GZd/qxqjO6MJHQhcsjvjOFXyDhyLQUnMveQ==", "dev": true, - "license": "Apache-2.0", "dependencies": { "@swc/counter": "^0.1.3" } @@ -2616,13 +2603,12 @@ "license": "ISC" }, "node_modules/@vitejs/plugin-react-swc": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.7.2.tgz", - "integrity": "sha512-y0byko2b2tSVVf5Gpng1eEhX1OvPC7x8yns1Fx8jDzlJp4LS6CMkCPfLw47cjyoMrshQDoQw4qcgjsU9VvlCew==", + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.8.0.tgz", + "integrity": "sha512-T4sHPvS+DIqDP51ifPqa9XIRAz/kIvIi8oXcnOZZgHmMotgmmdxe/DD5tMFlt5nuIRzT0/QuiwmKlH0503Aapw==", "dev": true, - "license": "MIT", "dependencies": { - "@swc/core": "^1.7.26" + "@swc/core": "^1.10.15" }, "peerDependencies": { "vite": "^4 || ^5 || ^6" @@ -7575,11 +7561,10 @@ } }, "node_modules/vite": { - "version": "5.4.11", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.11.tgz", - "integrity": "sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==", + "version": "5.4.14", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.14.tgz", + "integrity": "sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==", "dev": true, - "license": "MIT", "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", diff --git a/chartlets.js/packages/lib/src/plugins/mui/Select.tsx b/chartlets.js/packages/lib/src/plugins/mui/Select.tsx index 6fce3755..fd47efde 100644 --- a/chartlets.js/packages/lib/src/plugins/mui/Select.tsx +++ b/chartlets.js/packages/lib/src/plugins/mui/Select.tsx @@ -1,4 +1,3 @@ -import * as React from "react"; import MuiFormControl from "@mui/material/FormControl"; import MuiInputLabel from "@mui/material/InputLabel"; import MuiMenuItem from "@mui/material/MenuItem"; @@ -32,17 +31,19 @@ export function Select({ style, tooltip, label, - multiple, + multiple = false, onChange, }: SelectProps) { - const [personName, setPersonName] = React.useState([]); - - const handleChange = (event: SelectChangeEvent) => { + const handleChange = (event: SelectChangeEvent) => { if (id) { - let newValue: string | number = event.target.value; - if (typeof value == "number") { - newValue = Number.parseInt(newValue); + let newValue: string | number | (string | number)[] = multiple + ? (event.target.value as (string | number)[]) + : (event.target.value as string | number); + + if (!multiple && typeof value === "number") { + newValue = Number.parseInt(newValue as string); } + onChange({ componentType: type, id: id, @@ -59,16 +60,18 @@ export function Select({ labelId={`${id}-label`} id={id} name={name} - value={`${value}`} + value={value} disabled={disabled} multiple={multiple} onChange={handleChange}> {Array.isArray(options) && - options.map(normalizeSelectOption).map(([value, text], index) => ( - - {text} - - ))} + options + .map(normalizeSelectOption) + .map(([optionValue, optionLabel], index) => ( + + {optionLabel} + + ))} diff --git a/chartlets.py/demo/my_extension/__init__.py b/chartlets.py/demo/my_extension/__init__.py index 0f969eeb..e1d4538d 100644 --- a/chartlets.py/demo/my_extension/__init__.py +++ b/chartlets.py/demo/my_extension/__init__.py @@ -3,9 +3,11 @@ from .my_panel_2 import panel as my_panel_2 from .my_panel_3 import panel as my_panel_3 from .my_panel_4 import panel as my_panel_4 +from .my_panel_5 import panel as my_panel_5 ext = Extension(__name__) ext.add(my_panel_1) ext.add(my_panel_2) ext.add(my_panel_3) ext.add(my_panel_4) +ext.add(my_panel_5) diff --git a/chartlets.py/demo/my_extension/my_panel_2.py b/chartlets.py/demo/my_extension/my_panel_2.py index 5a13b54d..8ce2f2dd 100644 --- a/chartlets.py/demo/my_extension/my_panel_2.py +++ b/chartlets.py/demo/my_extension/my_panel_2.py @@ -24,11 +24,10 @@ def render_panel( ) select = Select( id="selected_variable_name", - value=[var_name], + value=var_name, label="Variable", options=[(v, v) for v in variable_names], style={"flexGrow": 0, "minWidth": 120}, - multiple=True, tooltip="Select the variable of the test dataset to be used", ) control_group = Box( diff --git a/chartlets.py/demo/my_extension/my_panel_5.py b/chartlets.py/demo/my_extension/my_panel_5.py index e69de29b..7364413c 100644 --- a/chartlets.py/demo/my_extension/my_panel_5.py +++ b/chartlets.py/demo/my_extension/my_panel_5.py @@ -0,0 +1,99 @@ +import altair as alt +import pandas as pd +from chartlets import Component, Input, State, Output +from chartlets.components import VegaChart, Box, Select, Typography + +from server.context import Context +from server.panel import Panel + + +panel = Panel(__name__, title="Panel E") + + +@panel.layout(State("@app", "selectedDatasetId")) +def render_panel( + ctx: Context, + selected_dataset_id: str = "", +) -> Component: + dataset = ctx.datasets.get(selected_dataset_id) + variable_names, selected_var_names = get_variable_names(dataset) + print(selected_var_names) + print(type(selected_var_names)) + + select = Select( + id="selected_variable_name", + # value=[selected_var_names], + value=[selected_var_names], + label="Variable", + options=[(v, v) for v in variable_names], + style={"flexGrow": 0, "minWidth": 120}, + multiple=True, + tooltip="Select the variables of the test dataset", + ) + control_group = Box( + style={ + "display": "flex", + "flexDirection": "row", + "padding": 4, + "justifyContent": "center", + "gap": 4, + }, + children=[select], + ) + + text = update_info_text(ctx, selected_dataset_id) + info_text = Typography(id="info_text", children=text) + + return Box( + style={ + "display": "flex", + "flexDirection": "column", + "width": "100%", + "height": "100%", + }, + children=[info_text, control_group], + ) + + +def get_variable_names( + dataset: pd.DataFrame, + prev_var_name: str | None = None, +) -> tuple[list[str], list[str]]: + """Get the variable names and the selected variable name + for the given dataset and previously selected variable name. + """ + + if dataset is not None: + var_names = [v for v in dataset.keys() if v != "x"] + else: + var_names = [] + + if prev_var_name and prev_var_name in var_names: + var_name = prev_var_name + elif var_names: + var_name = var_names[0] + else: + var_name = "" + + return var_names, var_name + + +@panel.callback( + Input("@app", "selectedDatasetId"), + Input("selected_variable_name", "value"), + Output("info_text", "children"), +) +def update_info_text( + ctx: Context, + dataset_id: str = "", + selected_var_names: list[str] | None = None, +) -> list[str]: + print(selected_var_names) + print(type(selected_var_names)) + + if selected_var_names is not None: + # text = ", ".join(selected_var_names) + text = ", ".join(map(str, selected_var_names)) + return [f"The dataset is {dataset_id} and the selected variables are: {text}"] + else: + return [f"The dataset is {dataset_id} and no variables are selected."] From 7244c03b6ebf6d51e8be14ae817c9d6a16d0de5f Mon Sep 17 00:00:00 2001 From: clarasb Date: Mon, 17 Feb 2025 17:40:29 +0100 Subject: [PATCH 06/15] update demo panel E --- chartlets.py/demo/my_extension/my_panel_5.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/chartlets.py/demo/my_extension/my_panel_5.py b/chartlets.py/demo/my_extension/my_panel_5.py index 7364413c..af52633a 100644 --- a/chartlets.py/demo/my_extension/my_panel_5.py +++ b/chartlets.py/demo/my_extension/my_panel_5.py @@ -17,13 +17,10 @@ def render_panel( ) -> Component: dataset = ctx.datasets.get(selected_dataset_id) variable_names, selected_var_names = get_variable_names(dataset) - print(selected_var_names) - print(type(selected_var_names)) select = Select( id="selected_variable_name", - # value=[selected_var_names], - value=[selected_var_names], + value=[], label="Variable", options=[(v, v) for v in variable_names], style={"flexGrow": 0, "minWidth": 120}, @@ -88,11 +85,8 @@ def update_info_text( dataset_id: str = "", selected_var_names: list[str] | None = None, ) -> list[str]: - print(selected_var_names) - print(type(selected_var_names)) if selected_var_names is not None: - # text = ", ".join(selected_var_names) text = ", ".join(map(str, selected_var_names)) return [f"The dataset is {dataset_id} and the selected variables are: {text}"] else: From 2281406b59059149e9b03116d52676aa008b6872 Mon Sep 17 00:00:00 2001 From: clarasb Date: Mon, 24 Feb 2025 15:48:38 +0100 Subject: [PATCH 07/15] update Changes --- chartlets.js/CHANGES.md | 100 +++++++++++++-------------- chartlets.js/package-lock.json | 121 ++++++++++++++++++--------------- chartlets.py/CHANGES.md | 65 +++++++++--------- 3 files changed, 151 insertions(+), 135 deletions(-) diff --git a/chartlets.js/CHANGES.md b/chartlets.js/CHANGES.md index 1a55757f..c07176de 100644 --- a/chartlets.js/CHANGES.md +++ b/chartlets.js/CHANGES.md @@ -1,58 +1,57 @@ ## Version 0.1.4 (in development) -- Add `multiple` property for `Select` component to enable the +* In `chartlets.js` we no longer emit warnings and errors in common + situations to avoid too much spam in the browser console. + +* Add `multiple` property for `Select` component to enable the of multiple elements. ## Version 0.1.3 (from 2025/01/28) -- **Chore:** Version bump to align CI process with GitHub release flow. - No functional changes. This release ensures proper triggering of the CI +* **Chore:** Version bump to align CI process with GitHub release flow. + No functional changes. This release ensures proper triggering of the CI pipeline for publishing and NPM. ## Version 0.1.0 (from 2025/01/14) -- Reorganised Chartlets project to better separate demo from library code. +* Reorganised Chartlets project to better separate demo from library code. Using monorepo layout for `chartlets.js` with workspaces `lib` and `demo` that host the packages for `chartlets` and `chartlets-demo`. -- Other code reorganisations: - - - moved `component/Registry` into `store` - - renamed module `component` into `components` +* Other code reorganisations: + - moved `component/Registry` into `store` + - renamed module `component` into `components` - no longer exposing `Registry` type -- Chartlets now allows for plugins that can provide individual component +* Chartlets now allows for plugins that can provide individual component implementations. - The Vega-based chart and MUI components are now optional and have been + The Vega-based chart and MUI components are now optional and have been moved into respective plugin modules `chartlets/plugins/vega` and `chartlets/plugins/mui`. - To activate them, use the new `plugins: PluginLike[]` option + To activate them, use the new `plugins: PluginLike[]` option of `FrameworkOptions`: - ```TypeScript import { configureFramework } from "chartlets"; import mui from "chartlets/plugins/mui"; import vega from "chartlets/plugins/vega"; - - configureFramework({ plugins: [mui(), vega()], ... }); + + configureFramework({ plugins: [mui(), vega()], ... }); ``` -- Renamed `Plot` component into `VegaChart`. +* Renamed `Plot` component into `VegaChart`. -- The new `VegaChart` component respects a `theme` property. If not given, +* The new `VegaChart` component respects a `theme` property. If not given, it will respect the current theme mode `"dark"` otherwise fallback to the - Vega default theme. + Vega default theme. -- The demo application now allows for switching the theme mode between +* The demo application now allows for switching the theme mode between dark, light, and system mode. -- Changed the yet unused descriptor type `CbFunction` for callback functions. - +* Changed the yet unused descriptor type `CbFunction` for callback functions. - using `schema` instead of `type` property for callback arguments - using `return` object with `schema` property for callback return values -- New (MUI) components - +* New (MUI) components - `Divider` - `LinearProgress` - `RadioGroup` and `Radio` @@ -60,95 +59,96 @@ - `Tabs` - `Slider` -- Supporting `tooltip` property for interactive MUI components. +* Supporting `tooltip` property for interactive MUI components. ## Version 0.0.29 (from 2024/11/26) -- Resolved warnings that appeared when using Vega charts. +* Resolved warnings that appeared when using Vega charts. ## Version 0.0.28 (from 2024/11/26) -- Updated docs. +* Updated docs. ## Version 0.0.27 (from 2024/11/25) -- Added component `IconButton` and enhanced other components' attributes. +* Added component `IconButton` and enhanced other components' attributes. ## Version 0.0.26 (from 2024/11/23) -- Channels such as `Input`, `State`, `Output` no longer have a `link` property. +* Channels such as `Input`, `State`, `Output` no longer have a `link` property. Instead, we use a special `id` format, namely `"@app"` and `@container` to address states other than components. (#52) ## Version 0.0.25 (from 2024/11/23) -- `Registry.register()` now requires the `type` +* `Registry.register()` now requires the `type` to be passed as 1st argument because `component.name` will be a mangled name in most cases. ## Version 0.0.24 (from 2024/11/23) -- Exporting required `HostStore` type. +* Exporting required `HostStore` type. ## Version 0.0.23 (from 2024/11/23) -- Introduced new interface `HostState` that applications may implement +* Introduced new interface `HostState` that applications may implement to provide computed properties, i.e., a derived state. (#43) -- Replacing entire components if a related component `StateChange` +* Replacing entire components if a related component `StateChange` has an empty `property`. (#38) -- Added handy hooks `useContributions` and `useComponentChangeHandlers`. +* Added handy hooks `useContributions` and `useComponentChangeHandlers`. + ## Version 0.0.22 (from 2024/11/19) -- Improved robustness while rendering the in `Select` component +* Improved robustness while rendering the in `Select` component wrt `options` property. -- `Button` component now sets a `clicked: boolean` property instead +* `Button` component now sets a `clicked: boolean` property instead of `n_clicks: int`. ## Version 0.0.21 (from 2024/11/19) -- `Component` children can now also be text nodes (of type `string`). +* `Component` children can now also be text nodes (of type `string`). -- `Typography` component has children instead of `text`. +* `Typography` component has children instead of `text`. -- A component's `children` property can now be changed, even from a +* A component's `children` property can now be changed, even from a scalar. -- Renamed `Dropdown` component into `Select` +* Renamed `Dropdown` component into `Select` (to refer to MUI component with same name). -- `Select` component has more flexible options. +* `Select` component has more flexible options. ## Version 0.0.20 (from 2024/11/19) -- Using `FrameworkOptions.getDerivedHostState` also in +* Using `FrameworkOptions.getDerivedHostState` also in `handleHostStoreChange()`. -- Actions `handleComponentChange()` and `handleHostStoreChange()` +* Actions `handleComponentChange()` and `handleHostStoreChange()` now exit immediately, if no extensions are configured yet. -- Module `utils.objPath`: Renamed `toObjPath` into `normalizeObjPath`, +* Module `utils.objPath`: Renamed `toObjPath` into `normalizeObjPath`, added `formatObjPath`. ## Version 0.0.19 (from 2024/11/18) -- Fixed TypeScript typing issues with `configureFramework()` and +* Fixed TypeScript typing issues with `configureFramework()` and `FrameworkOptions`. - + ## Version 0.0.18 (from 2024/11/18) -- Fixed TypeScript typing issues with `configureFramework()` and - `FrameworkOptions`. +* Fixed TypeScript typing issues with `configureFramework()` and + `FrameworkOptions`. ## Version 0.0.17 (from 2024/11/18) -- Enhanced interface `FrameworkOptions` by property `getDerivedHostState`, +* Enhanced interface `FrameworkOptions` by property `getDerivedHostState`, which is a user-supplied function that can compute derived - host state property. - + host state property. + ## Version 0.0.16 (from 2024/11/12) -Initial, still experimental version. +Initial, still experimental version. \ No newline at end of file diff --git a/chartlets.js/package-lock.json b/chartlets.js/package-lock.json index 30a0b905..322a16a1 100644 --- a/chartlets.js/package-lock.json +++ b/chartlets.js/package-lock.json @@ -2020,11 +2020,12 @@ } }, "node_modules/@swc/core": { - "version": "1.10.16", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.10.16.tgz", - "integrity": "sha512-nOINg/OUcZazCW7B55QV2/UB8QAqz9FYe4+z229+4RYboBTZ102K7ebOEjY5sKn59JgAkhjZTz+5BKmXpDFopw==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.10.1.tgz", + "integrity": "sha512-rQ4dS6GAdmtzKiCRt3LFVxl37FaY1cgL9kSUTnhQ2xc3fmHOd7jdJK/V4pSZMG1ruGTd0bsi34O2R0Olg9Zo/w==", "dev": true, "hasInstallScript": true, + "license": "Apache-2.0", "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.17" @@ -2037,16 +2038,16 @@ "url": "https://opencollective.com/swc" }, "optionalDependencies": { - "@swc/core-darwin-arm64": "1.10.16", - "@swc/core-darwin-x64": "1.10.16", - "@swc/core-linux-arm-gnueabihf": "1.10.16", - "@swc/core-linux-arm64-gnu": "1.10.16", - "@swc/core-linux-arm64-musl": "1.10.16", - "@swc/core-linux-x64-gnu": "1.10.16", - "@swc/core-linux-x64-musl": "1.10.16", - "@swc/core-win32-arm64-msvc": "1.10.16", - "@swc/core-win32-ia32-msvc": "1.10.16", - "@swc/core-win32-x64-msvc": "1.10.16" + "@swc/core-darwin-arm64": "1.10.1", + "@swc/core-darwin-x64": "1.10.1", + "@swc/core-linux-arm-gnueabihf": "1.10.1", + "@swc/core-linux-arm64-gnu": "1.10.1", + "@swc/core-linux-arm64-musl": "1.10.1", + "@swc/core-linux-x64-gnu": "1.10.1", + "@swc/core-linux-x64-musl": "1.10.1", + "@swc/core-win32-arm64-msvc": "1.10.1", + "@swc/core-win32-ia32-msvc": "1.10.1", + "@swc/core-win32-x64-msvc": "1.10.1" }, "peerDependencies": { "@swc/helpers": "*" @@ -2058,13 +2059,14 @@ } }, "node_modules/@swc/core-darwin-arm64": { - "version": "1.10.16", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.10.16.tgz", - "integrity": "sha512-iikIxwqCQ4Bvz79vJ4ELh26efPf1u5D9TFdmXSJUBs7C3mmMHvk5zyWD9A9cTowXiW6WHs2gE58U1R9HOTTIcg==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.10.1.tgz", + "integrity": "sha512-NyELPp8EsVZtxH/mEqvzSyWpfPJ1lugpTQcSlMduZLj1EASLO4sC8wt8hmL1aizRlsbjCX+r0PyL+l0xQ64/6Q==", "cpu": [ "arm64" ], "dev": true, + "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "darwin" @@ -2074,13 +2076,14 @@ } }, "node_modules/@swc/core-darwin-x64": { - "version": "1.10.16", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.10.16.tgz", - "integrity": "sha512-R2Eb9aktWd62vPfW9H/c/OaQ0e94iURibBo4uzUUcgxNNmB4+wb6piKbHxGdr/5bEsT+vJ1lwZFSRzfb45E7DA==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.10.1.tgz", + "integrity": "sha512-L4BNt1fdQ5ZZhAk5qoDfUnXRabDOXKnXBxMDJ+PWLSxOGBbWE6aJTnu4zbGjJvtot0KM46m2LPAPY8ttknqaZA==", "cpu": [ "x64" ], "dev": true, + "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "darwin" @@ -2090,13 +2093,14 @@ } }, "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.10.16", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.10.16.tgz", - "integrity": "sha512-mkqN3HBAMnuiSGZ/k2utScuH8rAPshvNj0T1LjBWon+X9DkMNHSA+aMLdWsy0yZKF1zjOPc4L3Uq2l2wzhUlzA==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.10.1.tgz", + "integrity": "sha512-Y1u9OqCHgvVp2tYQAJ7hcU9qO5brDMIrA5R31rwWQIAKDkJKtv3IlTHF0hrbWk1wPR0ZdngkQSJZple7G+Grvw==", "cpu": [ "arm" ], "dev": true, + "license": "Apache-2.0", "optional": true, "os": [ "linux" @@ -2106,13 +2110,14 @@ } }, "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.10.16", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.10.16.tgz", - "integrity": "sha512-PH/+q/L5nVZJ91CU07CL6Q9Whs6iR6nneMZMAgtVF9Ix8ST0cWVItdUhs6D38kFklCFhaOrpHhS01HlMJ72vWw==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.10.1.tgz", + "integrity": "sha512-tNQHO/UKdtnqjc7o04iRXng1wTUXPgVd8Y6LI4qIbHVoVPwksZydISjMcilKNLKIwOoUQAkxyJ16SlOAeADzhQ==", "cpu": [ "arm64" ], "dev": true, + "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "linux" @@ -2122,13 +2127,14 @@ } }, "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.10.16", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.10.16.tgz", - "integrity": "sha512-1169+C9XbydKKc6Ec1XZxTGKtHjZHDIFn0r+Nqp/QSVwkORrOY1Vz2Hdu7tn/lWMg36ZkGePS+LnnyV67s/7yg==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.10.1.tgz", + "integrity": "sha512-x0L2Pd9weQ6n8dI1z1Isq00VHFvpBClwQJvrt3NHzmR+1wCT/gcYl1tp9P5xHh3ldM8Cn4UjWCw+7PaUgg8FcQ==", "cpu": [ "arm64" ], "dev": true, + "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "linux" @@ -2138,13 +2144,14 @@ } }, "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.10.16", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.10.16.tgz", - "integrity": "sha512-n2rV0XwkjoHn4MDJmpYp5RBrnyi94/6GsJVpbn6f+/eqSrZn3mh3dT7pdZc9zCN1Qp9eDHo+uI6e/wgvbL22uA==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.10.1.tgz", + "integrity": "sha512-yyYEwQcObV3AUsC79rSzN9z6kiWxKAVJ6Ntwq2N9YoZqSPYph+4/Am5fM1xEQYf/kb99csj0FgOelomJSobxQA==", "cpu": [ "x64" ], "dev": true, + "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "linux" @@ -2154,13 +2161,14 @@ } }, "node_modules/@swc/core-linux-x64-musl": { - "version": "1.10.16", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.10.16.tgz", - "integrity": "sha512-EevCpwreBrkPrJjQVIbiM81lK42ukNNSlBmrSRxxbx2V9VGmOd5qxX0cJBn0TRRSLIPi62BuMS76F9iYjqsjgg==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.10.1.tgz", + "integrity": "sha512-tcaS43Ydd7Fk7sW5ROpaf2Kq1zR+sI5K0RM+0qYLYYurvsJruj3GhBCaiN3gkzd8m/8wkqNqtVklWaQYSDsyqA==", "cpu": [ "x64" ], "dev": true, + "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "linux" @@ -2170,13 +2178,14 @@ } }, "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.10.16", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.10.16.tgz", - "integrity": "sha512-BvE7RWAnKJeELVQWLok6env5I4GUVBTZSvaSN/VPgxnTjF+4PsTeQptYx0xCYhp5QCv68wWYsBnZKuPDS+SBsw==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.10.1.tgz", + "integrity": "sha512-D3Qo1voA7AkbOzQ2UGuKNHfYGKL6eejN8VWOoQYtGHHQi1p5KK/Q7V1ku55oxXBsj79Ny5FRMqiRJpVGad7bjQ==", "cpu": [ "arm64" ], "dev": true, + "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "win32" @@ -2186,13 +2195,14 @@ } }, "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.10.16", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.10.16.tgz", - "integrity": "sha512-7Jf/7AeCgbLR/JsQgMJuacHIq4Jeie3knf6+mXxn8aCvRypsOTIEu0eh7j24SolOboxK1ijqJ86GyN1VA2Rebg==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.10.1.tgz", + "integrity": "sha512-WalYdFoU3454Og+sDKHM1MrjvxUGwA2oralknXkXL8S0I/8RkWZOB++p3pLaGbTvOO++T+6znFbQdR8KRaa7DA==", "cpu": [ "ia32" ], "dev": true, + "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "win32" @@ -2202,13 +2212,14 @@ } }, "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.10.16", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.10.16.tgz", - "integrity": "sha512-p0blVm0R8bjaTtmW+FoPmLxLSQdRNbqhuWcR/8g80OzMSkka9mk5/J3kn/5JRVWh+MaR9LHRHZc1Q1L8zan13g==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.10.1.tgz", + "integrity": "sha512-JWobfQDbTnoqaIwPKQ3DVSywihVXlQMbDuwik/dDWlj33A8oEHcjPOGs4OqcA3RHv24i+lfCQpM3Mn4FAMfacA==", "cpu": [ "x64" ], "dev": true, + "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "win32" @@ -2221,13 +2232,15 @@ "version": "0.1.3", "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", - "dev": true + "dev": true, + "license": "Apache-2.0" }, "node_modules/@swc/types": { "version": "0.1.17", "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.17.tgz", "integrity": "sha512-V5gRru+aD8YVyCOMAjMpWR1Ui577DD5KSJsHP8RAxopAH22jFz6GZd/qxqjO6MJHQhcsjvjOFXyDhyLQUnMveQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@swc/counter": "^0.1.3" } @@ -2603,12 +2616,13 @@ "license": "ISC" }, "node_modules/@vitejs/plugin-react-swc": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.8.0.tgz", - "integrity": "sha512-T4sHPvS+DIqDP51ifPqa9XIRAz/kIvIi8oXcnOZZgHmMotgmmdxe/DD5tMFlt5nuIRzT0/QuiwmKlH0503Aapw==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.7.2.tgz", + "integrity": "sha512-y0byko2b2tSVVf5Gpng1eEhX1OvPC7x8yns1Fx8jDzlJp4LS6CMkCPfLw47cjyoMrshQDoQw4qcgjsU9VvlCew==", "dev": true, + "license": "MIT", "dependencies": { - "@swc/core": "^1.10.15" + "@swc/core": "^1.7.26" }, "peerDependencies": { "vite": "^4 || ^5 || ^6" @@ -7561,10 +7575,11 @@ } }, "node_modules/vite": { - "version": "5.4.14", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.14.tgz", - "integrity": "sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==", + "version": "5.4.11", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.11.tgz", + "integrity": "sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==", "dev": true, + "license": "MIT", "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", @@ -8180,7 +8195,7 @@ }, "packages/lib": { "name": "chartlets", - "version": "0.1.3", + "version": "0.1.4-dev.0", "license": "MIT", "dependencies": { "microdiff": "^1.4", @@ -8225,4 +8240,4 @@ } } } -} +} \ No newline at end of file diff --git a/chartlets.py/CHANGES.md b/chartlets.py/CHANGES.md index 820514d8..8eda3edc 100644 --- a/chartlets.py/CHANGES.md +++ b/chartlets.py/CHANGES.md @@ -1,80 +1,81 @@ ## Version 0.1.4 (in development) -- Add `multiple` property for `Select` component to enable the +* Add `multiple` property for `Select` component to enable the of multiple elements. - + ## Version 0.1.3 (from 2025/01/28) -- **Chore:** Version bump to align CI process with GitHub release flow. - No functional changes. This release ensures proper triggering of the CI +* **Chore:** Version bump to align CI process with GitHub release flow. + No functional changes. This release ensures proper triggering of the CI pipeline for publishing to PyPI. ## Version 0.1.0 (from 2025/01/14) -- Reorganised Chartlets project to better separate demo from library code. - Created separate folder `demo` in `chartlets.py` that contains +* Reorganised Chartlets project to better separate demo from library code. + Created separate folder `demo` in `chartlets.py` that contains a demo `server` package and example configuration. Also simplified demo server code: - - Moved `panel` module one level up - - Removed `util` module which was no longer required + - Removed `util` module which was no longer required -- Allow for different chart providers. `VegaChart` can be configured only if +* Allow for different chart providers. `VegaChart` can be configured only if `altair` package is installed. -- Renamed `Plot` into `VegaChart`, which now also respects a `theme` property. - -- Changed schema of the yet unused descriptor for callback functions. + +* Renamed `Plot` into `VegaChart`, which now also respects a `theme` property. +* Changed schema of the yet unused descriptor for callback functions. - using `schema` instead of `type` property for callback arguments - using `return` object with `schema` property for callback return values -- Added `tooltip` property to interactive components. +* Added `tooltip` property to interactive components. -- New components +* New components - `Divider` - `RadioGroup` and `Radio` - `Switch` - `Slider` - `Tabs` and `Tab` + ## Version 0.0.29 (from 2024/11/26) -- Fixed a bug that prevents using annotations of type `dict` or `dict[str, T]`. +* Fixed a bug that prevents using annotations of type `dict` or `dict[str, T]`. in callback functions. -- Introduced a callback function in `my_panel.py` to handle click events. +* Introduced a callback function in `my_panel.py` to handle click events. Demonstrates how to dynamically change the color of a clicked bar. + ## Version 0.0.28 (from 2024/11/26) -- Updated docs. +* Updated docs. -- Added component `IconButton` and enhanced other components' attributes. +* Added component `IconButton` and enhanced other components' attributes. -- Channels such as `Input`, `State`, `Output` no longer have a `link` property. - Instead, we use a special `id` format, namely `"@app"` and `@container` - to address states other than components. - This way, the call syntax `Input(id, property)` is the same for all states, - e.g., `Input("@app", "selectedDatasetId")`, instead of +* Channels such as `Input`, `State`, `Output` no longer have a `link` property. + Instead, we use a special `id` format, namely `"@app"` and `@container` + to address states other than components. + This way, the call syntax `Input(id, property)` is the same for all states, + e.g., `Input("@app", "selectedDatasetId")`, instead of `Input(source="app", property="selectedDatasetId")`. (#52) -- Added progress components `CircularProgress`, `CircularProgressWithLabel`, +* Added progress components `CircularProgress`, `CircularProgressWithLabel`, `LinearProgress`, `LinearProgressWithLabel`. -- Replacing components is now possible by using an +* Replacing components is now possible by using an `Output` with `property` set to an empty string. (#38) -- `Component` children can now also be text nodes (of type `string`). +* `Component` children can now also be text nodes (of type `string`). -- `Typography` component has children instead of `text`. +* `Typography` component has children instead of `text`. -- Renamed `Dropdown` component into `Select` +* Renamed `Dropdown` component into `Select` (to refer to MUI component with same name). -- `Select` component has more flexible options. +* `Select` component has more flexible options. -- Dealing with callbacks parameter and return types +* Dealing with callbacks parameter and return types that are just `list` and not, e.g., `list[str]`. - + ## Version 0.0.16 (from 2024/11/12) -Initial, still experimental version. +Initial, still experimental version. \ No newline at end of file From 1a8215b90f79e9e44d0e6a49f6217f146e221d68 Mon Sep 17 00:00:00 2001 From: clarasb Date: Mon, 24 Feb 2025 15:52:08 +0100 Subject: [PATCH 08/15] update Changes --- chartlets.js/CHANGES.md | 3 ++- chartlets.py/CHANGES.md | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/chartlets.js/CHANGES.md b/chartlets.js/CHANGES.md index c07176de..6d7ddf15 100644 --- a/chartlets.js/CHANGES.md +++ b/chartlets.js/CHANGES.md @@ -151,4 +151,5 @@ ## Version 0.0.16 (from 2024/11/12) -Initial, still experimental version. \ No newline at end of file +Initial, still experimental version. + \ No newline at end of file diff --git a/chartlets.py/CHANGES.md b/chartlets.py/CHANGES.md index 8eda3edc..36725fae 100644 --- a/chartlets.py/CHANGES.md +++ b/chartlets.py/CHANGES.md @@ -78,4 +78,4 @@ ## Version 0.0.16 (from 2024/11/12) -Initial, still experimental version. \ No newline at end of file +Initial, still experimental version. From d5bc83f0d7be7e9bd5f0d03152c4b74482051cbf Mon Sep 17 00:00:00 2001 From: clarasb Date: Mon, 24 Feb 2025 15:56:14 +0100 Subject: [PATCH 09/15] update Changes --- chartlets.js/package-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chartlets.js/package-lock.json b/chartlets.js/package-lock.json index 322a16a1..43954ff3 100644 --- a/chartlets.js/package-lock.json +++ b/chartlets.js/package-lock.json @@ -8195,7 +8195,7 @@ }, "packages/lib": { "name": "chartlets", - "version": "0.1.4-dev.0", + "version": "0.1.3", "license": "MIT", "dependencies": { "microdiff": "^1.4", From b71b36a02676dae295ebf238dcc25af7ca2f780b Mon Sep 17 00:00:00 2001 From: clarasb Date: Mon, 24 Feb 2025 15:58:30 +0100 Subject: [PATCH 10/15] update Changes --- chartlets.js/CHANGES.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/chartlets.js/CHANGES.md b/chartlets.js/CHANGES.md index 6d7ddf15..9fdc445f 100644 --- a/chartlets.js/CHANGES.md +++ b/chartlets.js/CHANGES.md @@ -1,7 +1,4 @@ ## Version 0.1.4 (in development) - -* In `chartlets.js` we no longer emit warnings and errors in common - situations to avoid too much spam in the browser console. * Add `multiple` property for `Select` component to enable the of multiple elements. From 0cd39a45b05eac4c187257833552af35380c3c6c Mon Sep 17 00:00:00 2001 From: Clara Backens <64074334+clarasb@users.noreply.github.com> Date: Mon, 3 Mar 2025 09:34:29 +0100 Subject: [PATCH 11/15] Update chartlets.py/chartlets/components/select.py Co-authored-by: b-yogesh --- chartlets.py/chartlets/components/select.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chartlets.py/chartlets/components/select.py b/chartlets.py/chartlets/components/select.py index 89854fad..5b45d40a 100644 --- a/chartlets.py/chartlets/components/select.py +++ b/chartlets.py/chartlets/components/select.py @@ -14,7 +14,7 @@ class Select(Component): information from a list of options.""" multiple: bool | None = None - """Allows for multiple selection in Select Menu. If `true` value + """Allows for multiple selection in Select Menu. If `true`, value must be an array. """ From 7d74f676bafe745a71311bd36a169be4700a7135 Mon Sep 17 00:00:00 2001 From: clarasb Date: Mon, 3 Mar 2025 11:47:14 +0100 Subject: [PATCH 12/15] update formatting --- chartlets.js/CHANGES.md | 4 +- .../packages/lib/src/plugins/mui/Select.tsx | 136 +++++++++--------- 2 files changed, 70 insertions(+), 70 deletions(-) diff --git a/chartlets.js/CHANGES.md b/chartlets.js/CHANGES.md index 9fdc445f..eb61b9ec 100644 --- a/chartlets.js/CHANGES.md +++ b/chartlets.js/CHANGES.md @@ -1,7 +1,7 @@ ## Version 0.1.4 (in development) -* Add `multiple` property for `Select` component to enable the - of multiple elements. +* Add `multiple` property for `Select` component to enable the selection + of multiple elements. The `default` mode is supported at the moment. ## Version 0.1.3 (from 2025/01/28) diff --git a/chartlets.js/packages/lib/src/plugins/mui/Select.tsx b/chartlets.js/packages/lib/src/plugins/mui/Select.tsx index fd47efde..71b6245c 100644 --- a/chartlets.js/packages/lib/src/plugins/mui/Select.tsx +++ b/chartlets.js/packages/lib/src/plugins/mui/Select.tsx @@ -8,86 +8,86 @@ import { isString } from "@/utils/isString"; import { Tooltip } from "./Tooltip"; export type SelectOption = - | string - | number - | [string, string] - | [number, string] - | { value: string | number; label?: string }; + | string + | number + | [string, string] + | [number, string] + | { value: string | number; label?: string }; interface SelectState extends ComponentState { - options?: SelectOption[]; - multiple?: boolean; + options?: SelectOption[]; + multiple?: boolean; } interface SelectProps extends ComponentProps, SelectState {} export function Select({ - type, - id, - name, - value, - options, - disabled, - style, - tooltip, - label, - multiple = false, - onChange, + type, + id, + name, + value, + options, + disabled, + style, + tooltip, + label, + multiple = false, + onChange, }: SelectProps) { - const handleChange = (event: SelectChangeEvent) => { - if (id) { - let newValue: string | number | (string | number)[] = multiple - ? (event.target.value as (string | number)[]) - : (event.target.value as string | number); + const handleChange = (event: SelectChangeEvent) => { + if (id) { + let newValue: string | number | (string | number)[] = multiple + ? (event.target.value as (string | number)[]) + : (event.target.value as string | number); - if (!multiple && typeof value === "number") { - newValue = Number.parseInt(newValue as string); - } + if (!multiple && typeof value === "number") { + newValue = Number.parseInt(newValue as string); + } - onChange({ - componentType: type, - id: id, - property: "value", - value: newValue, - }); - } - }; - return ( - - - {label && {label}} - - {Array.isArray(options) && - options - .map(normalizeSelectOption) - .map(([optionValue, optionLabel], index) => ( - - {optionLabel} - - ))} - - - - ); + onChange({ + componentType: type, + id: id, + property: "value", + value: newValue, + }); + } + }; + return ( + + + {label && {label}} + + {Array.isArray(options) && + options + .map(normalizeSelectOption) + .map(([optionValue, optionLabel], index) => ( + + {optionLabel} + + ))} + + + + ); } function normalizeSelectOption( - option: SelectOption + option: SelectOption ): [string | number, string] { - if (isString(option)) { - return [option, option]; - } else if (typeof option === "number") { - return [option, option.toString()]; - } else if (Array.isArray(option)) { - return option; - } else { - return [option.value, option.label || `${option.value}`]; - } + if (isString(option)) { + return [option, option]; + } else if (typeof option === "number") { + return [option, option.toString()]; + } else if (Array.isArray(option)) { + return option; + } else { + return [option.value, option.label || `${option.value}`]; + } } From d5c98d57a4ecc04918ab4a3a61578ca4f18f5323 Mon Sep 17 00:00:00 2001 From: clarasb Date: Mon, 3 Mar 2025 16:05:44 +0100 Subject: [PATCH 13/15] add test for select.tsx regarding `multiple` property --- .../lib/src/plugins/mui/Select.test.tsx | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/chartlets.js/packages/lib/src/plugins/mui/Select.test.tsx b/chartlets.js/packages/lib/src/plugins/mui/Select.test.tsx index 258e00cb..59535152 100644 --- a/chartlets.js/packages/lib/src/plugins/mui/Select.test.tsx +++ b/chartlets.js/packages/lib/src/plugins/mui/Select.test.tsx @@ -105,6 +105,47 @@ describe("Select", () => { }); }); + it("should fire 'value' property with an array of multiple values", () => { + const { recordedEvents, onChange } = createChangeHandler(); + render( +