Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"framework":"react","displayName":"Getting Started ▸ Integration with Redux · Standard example · React (TS)","tier":1,"engine":"sandpack","sandpackTemplate":"react-ts","sandpackEnvironment":"parcel","container":null,"htWrappers":["@handsontable/react-wrapper"],"entry":"/src/main.tsx","htmlEntry":"/index.html","devCommand":null,"buildCommand":"vite build","outputDir":"dist","outputGlob":null,"staticExport":false,"spaMode":false,"port":null,"installCommand":"pnpm install","htCoreRange":"18.1.2","fileCount":5,"assets":[],"skipped":[],"files":{"/package.json":"{\n \"name\": \"handsontable-react-example\",\n \"version\": \"1.0.0\",\n \"private\": true,\n \"packageManager\": \"pnpm@10.34.5\",\n \"dependencies\": {\n \"handsontable\": \"18.1.2\",\n \"@handsontable/react-wrapper\": \"18.1.2\",\n \"react\": \"18.x\",\n \"react-dom\": \"18.x\",\n \"vite\": \"^5.4.0\",\n \"@vitejs/plugin-react\": \"^4.0.0\",\n \"redux\": \"5.0.1\",\n \"react-redux\": \"9.3.0\"\n },\n \"scripts\": {\n \"start\": \"vite\",\n \"build\": \"vite build\"\n }\n}","/vite.config.js":"import { defineConfig } from \"vite\";\nimport react from \"@vitejs/plugin-react\";\n\nexport default defineConfig({ plugins: [react()] });","/index.html":"<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>Handsontable React Example</title>\n <style>body { padding: 1rem; font-family: system-ui, -apple-system, sans-serif; }</style>\n</head>\n<body>\n <div id=\"example1\"></div>\n <script type=\"module\" src=\"/src/main.tsx\"></script>\n</body>\n</html>","/src/main.tsx":"import React from \"react\";\nimport { createRoot } from \"react-dom/client\";\nimport App from \"./App\";\nconst root = createRoot(document.getElementById(\"example1\"));\nroot.render(React.createElement(App));","/src/App.tsx":"import { useRef, MouseEvent, JSXElementConstructor, Key, ReactElement, ReactNode, ReactPortal } from 'react';\nimport { createStore } from 'redux';\nimport { Provider, useSelector, useDispatch } from 'react-redux';\nimport { HotTable } from '@handsontable/react-wrapper';\nimport { registerAllModules } from 'handsontable/registry';\nimport Handsontable from 'handsontable/base';\n\n// register Handsontable's modules\nregisterAllModules();\n\nconst ExampleComponentContent = () => {\n const hotSettings = useSelector((state: RootState) => state);\n const dispatch = useDispatch();\n const hotTableComponentRef = useRef(null);\n\n const hotData = hotSettings.data;\n const isHotData = Array.isArray(hotData);\n\n const onBeforeHotChange = (changes: (Handsontable.CellChange | null)[]) => {\n dispatch({\n type: 'updateData',\n dataChanges: changes,\n });\n\n return false;\n };\n\n const toggleReadOnly = (event: MouseEvent) => {\n dispatch({\n type: 'updateReadOnly',\n readOnly: (event.target as HTMLInputElement).checked,\n });\n };\n\n return (\n <div className=\"dump-example-container\">\n <div id=\"example-container\">\n <div id=\"example-preview\">\n <div className=\"example-controls-container\">\n <div className=\"controls\">\n <label>\n <input onClick={toggleReadOnly} type=\"checkbox\" />\n Toggle <code>readOnly</code> for the entire table\n </label>\n </div>\n </div>\n\n <HotTable\n ref={hotTableComponentRef}\n beforeChange={onBeforeHotChange}\n autoWrapRow={true}\n autoWrapCol={true}\n {...hotSettings}\n />\n </div>\n <h3>Redux store dump</h3>\n <pre id=\"redux-preview\" className=\"table-container\">\n {isHotData && (\n <div>\n <strong>data:</strong>\n <table style={{ border: '1px solid #d6d6d6' }}>\n <tbody>\n {hotData.map((row, i) => (\n <tr key={i}>\n {row.map(\n (\n cell:\n | string\n | number\n | boolean\n | ReactElement<any, string | JSXElementConstructor<any>>\n | Iterable<ReactNode>\n | ReactPortal\n | null\n | undefined,\n i: Key | null | undefined\n ) => (\n <td key={i}>{cell}</td>\n )\n )}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n\n <table>\n <tbody>\n {Object.entries(hotSettings).map(\n ([name, value]) =>\n name !== 'data' && (\n <tr key={`${name}${value}`}>\n <td>\n <strong>{name}:</strong>\n </td>\n <td>{value.toString()}</td>\n </tr>\n )\n )}\n </tbody>\n </table>\n </pre>\n </div>\n </div>\n );\n};\n\nconst initialReduxStoreState = {\n data: [\n ['A1', 'B1', 'C1'],\n ['A2', 'B2', 'C2'],\n ['A3', 'B3', 'C3'],\n ['A4', 'B4', 'C4'],\n ['A5', 'B5', 'C5'],\n ],\n colHeaders: true,\n rowHeaders: true,\n readOnly: false,\n height: 'auto',\n licenseKey: 'non-commercial-and-evaluation',\n};\n\nconst updatesReducer = (\n state = initialReduxStoreState,\n action: { type: any; dataChanges: [any, any, any, any][]; readOnly: any }\n) => {\n switch (action.type) {\n case 'updateData':\n const newData = state.data.map((row) => [...row]);\n\n action.dataChanges.forEach(([row, column, oldValue, newValue]) => {\n newData[row][column] = newValue;\n });\n\n return {\n ...state,\n data: newData,\n };\n\n case 'updateReadOnly':\n return {\n ...state,\n readOnly: action.readOnly,\n };\n\n default:\n return state;\n }\n};\n\nexport type RootState = ReturnType<typeof updatesReducer>;\n\nconst reduxStore = createStore(updatesReducer);\n\nconst ExampleComponent = () => (\n <Provider store={reduxStore}>\n <ExampleComponentContent />\n </Provider>\n);\n\nexport default ExampleComponent;"},"docsPath":"guides/getting-started/react-redux/react/example1.tsx","breadcrumb":["Getting Started","Integration with Redux"],"guide":"guides/getting-started/react-redux/react-redux.md","guideTitle":"Integration with Redux","exampleId":"example1","exampleTitle":"Standard example","docPermalink":"/redux","lang":"React (TS)"}
{"framework":"react","displayName":"Getting Started ▸ Integration with Redux · Standard example · React (TS)","tier":1,"engine":"sandpack","sandpackTemplate":"react-ts","sandpackEnvironment":"parcel","container":null,"htWrappers":["@handsontable/react-wrapper"],"entry":"/src/main.tsx","htmlEntry":"/index.html","devCommand":null,"buildCommand":"vite build","outputDir":"dist","outputGlob":null,"staticExport":false,"spaMode":false,"port":null,"installCommand":"pnpm install","htCoreRange":"18.1.2","fileCount":5,"assets":[],"skipped":[],"files":{"/package.json":"{\n \"name\": \"handsontable-react-example\",\n \"version\": \"1.0.0\",\n \"private\": true,\n \"packageManager\": \"pnpm@10.34.5\",\n \"dependencies\": {\n \"handsontable\": \"18.1.2\",\n \"@handsontable/react-wrapper\": \"18.1.2\",\n \"react\": \"18.x\",\n \"react-dom\": \"18.x\",\n \"vite\": \"^5.4.0\",\n \"@vitejs/plugin-react\": \"^4.0.0\",\n \"redux\": \"5.0.1\",\n \"react-redux\": \"9.3.1\"\n },\n \"scripts\": {\n \"start\": \"vite\",\n \"build\": \"vite build\"\n }\n}","/vite.config.js":"import { defineConfig } from \"vite\";\nimport react from \"@vitejs/plugin-react\";\n\nexport default defineConfig({ plugins: [react()] });","/index.html":"<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>Handsontable React Example</title>\n <style>body { padding: 1rem; font-family: system-ui, -apple-system, sans-serif; }</style>\n</head>\n<body>\n <div id=\"example1\"></div>\n <script type=\"module\" src=\"/src/main.tsx\"></script>\n</body>\n</html>","/src/main.tsx":"import React from \"react\";\nimport { createRoot } from \"react-dom/client\";\nimport App from \"./App\";\nconst root = createRoot(document.getElementById(\"example1\"));\nroot.render(React.createElement(App));","/src/App.tsx":"import { useRef, MouseEvent, JSXElementConstructor, Key, ReactElement, ReactNode, ReactPortal } from 'react';\nimport { createStore } from 'redux';\nimport { Provider, useSelector, useDispatch } from 'react-redux';\nimport { HotTable } from '@handsontable/react-wrapper';\nimport { registerAllModules } from 'handsontable/registry';\nimport Handsontable from 'handsontable/base';\n\n// register Handsontable's modules\nregisterAllModules();\n\nconst ExampleComponentContent = () => {\n const hotSettings = useSelector((state: RootState) => state);\n const dispatch = useDispatch();\n const hotTableComponentRef = useRef(null);\n\n const hotData = hotSettings.data;\n const isHotData = Array.isArray(hotData);\n\n const onBeforeHotChange = (changes: (Handsontable.CellChange | null)[]) => {\n dispatch({\n type: 'updateData',\n dataChanges: changes,\n });\n\n return false;\n };\n\n const toggleReadOnly = (event: MouseEvent) => {\n dispatch({\n type: 'updateReadOnly',\n readOnly: (event.target as HTMLInputElement).checked,\n });\n };\n\n return (\n <div className=\"dump-example-container\">\n <div id=\"example-container\">\n <div id=\"example-preview\">\n <div className=\"example-controls-container\">\n <div className=\"controls\">\n <label>\n <input onClick={toggleReadOnly} type=\"checkbox\" />\n Toggle <code>readOnly</code> for the entire table\n </label>\n </div>\n </div>\n\n <HotTable\n ref={hotTableComponentRef}\n beforeChange={onBeforeHotChange}\n autoWrapRow={true}\n autoWrapCol={true}\n {...hotSettings}\n />\n </div>\n <h3>Redux store dump</h3>\n <pre id=\"redux-preview\" className=\"table-container\">\n {isHotData && (\n <div>\n <strong>data:</strong>\n <table style={{ border: '1px solid #d6d6d6' }}>\n <tbody>\n {hotData.map((row, i) => (\n <tr key={i}>\n {row.map(\n (\n cell:\n | string\n | number\n | boolean\n | ReactElement<any, string | JSXElementConstructor<any>>\n | Iterable<ReactNode>\n | ReactPortal\n | null\n | undefined,\n i: Key | null | undefined\n ) => (\n <td key={i}>{cell}</td>\n )\n )}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n\n <table>\n <tbody>\n {Object.entries(hotSettings).map(\n ([name, value]) =>\n name !== 'data' && (\n <tr key={`${name}${value}`}>\n <td>\n <strong>{name}:</strong>\n </td>\n <td>{value.toString()}</td>\n </tr>\n )\n )}\n </tbody>\n </table>\n </pre>\n </div>\n </div>\n );\n};\n\nconst initialReduxStoreState = {\n data: [\n ['A1', 'B1', 'C1'],\n ['A2', 'B2', 'C2'],\n ['A3', 'B3', 'C3'],\n ['A4', 'B4', 'C4'],\n ['A5', 'B5', 'C5'],\n ],\n colHeaders: true,\n rowHeaders: true,\n readOnly: false,\n height: 'auto',\n licenseKey: 'non-commercial-and-evaluation',\n};\n\nconst updatesReducer = (\n state = initialReduxStoreState,\n action: { type: any; dataChanges: [any, any, any, any][]; readOnly: any }\n) => {\n switch (action.type) {\n case 'updateData':\n const newData = state.data.map((row) => [...row]);\n\n action.dataChanges.forEach(([row, column, oldValue, newValue]) => {\n newData[row][column] = newValue;\n });\n\n return {\n ...state,\n data: newData,\n };\n\n case 'updateReadOnly':\n return {\n ...state,\n readOnly: action.readOnly,\n };\n\n default:\n return state;\n }\n};\n\nexport type RootState = ReturnType<typeof updatesReducer>;\n\nconst reduxStore = createStore(updatesReducer);\n\nconst ExampleComponent = () => (\n <Provider store={reduxStore}>\n <ExampleComponentContent />\n </Provider>\n);\n\nexport default ExampleComponent;"},"docsPath":"guides/getting-started/react-redux/react/example1.tsx","breadcrumb":["Getting Started","Integration with Redux"],"guide":"guides/getting-started/react-redux/react-redux.md","guideTitle":"Integration with Redux","exampleId":"example1","exampleTitle":"Standard example","docPermalink":"/redux","lang":"React (TS)"}
Loading