chore(docs): update versioned docs examples - #372
Conversation
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit b611b04. Configure here.
| @@ -1 +1 @@ | |||
| {"framework":"javascript","displayName":"Recipes ▸ Cell Types ▸ Flatpickr · Standard example · JavaScript","tier":1,"engine":"sandpack","sandpackTemplate":"vanilla","sandpackEnvironment":"parcel","container":null,"htWrappers":[],"entry":"/src/main.js","htmlEntry":"/index.html","devCommand":null,"buildCommand":"vite build","outputDir":"dist","outputGlob":null,"staticExport":false,"spaMode":false,"port":null,"installCommand":"pnpm install","htCoreRange":"18.1.1","fileCount":5,"assets":[],"skipped":[],"files":{"/package.json":"{\n \"name\": \"handsontable-example\",\n \"version\": \"1.0.0\",\n \"private\": true,\n \"packageManager\": \"pnpm@10.34.5\",\n \"dependencies\": {\n \"handsontable\": \"18.1.1\",\n \"vite\": \"^5.4.0\",\n \"date-fns\": \"4.4.0\",\n \"flatpickr\": \"4.6.13\"\n },\n \"scripts\": {\n \"start\": \"vite\",\n \"build\": \"vite build\"\n }\n}","/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 Example</title>\n <style>body { padding: 1rem; font-family: sans-serif; }</style>\n</head>\n<body>\n <div id=\"example1\"></div>\n <script type=\"module\" src=\"/src/main.js\"></script>\n</body>\n</html>","/index.js":"import Handsontable from 'handsontable/base';\nimport { registerAllModules } from 'handsontable/registry';\nimport { format, isDate } from 'date-fns';\nimport flatpickr from 'flatpickr';\nimport 'flatpickr/dist/flatpickr.css';\nimport { editorFactory } from 'handsontable/editors';\nimport { rendererFactory } from 'handsontable/renderers';\n\nregisterAllModules();\nconst DATE_FORMAT_US = 'MM/dd/yyyy';\nconst DATE_FORMAT_EU = 'dd/MM/yyyy';\n\n/* start:skip-in-preview */\nconst data = [\n {\n product: 'Dashboard Pro',\n category: 'Analytics',\n version: '3.2.0',\n releaseDate: '2025-03-15',\n status: 'Released',\n downloads: 12450,\n },\n {\n product: 'Form Builder',\n category: 'Tools',\n version: '2.1.0',\n releaseDate: '2025-04-22',\n status: 'Released',\n downloads: 8320,\n },\n {\n product: 'Chart Engine',\n category: 'Analytics',\n version: '4.0.0',\n releaseDate: '2025-06-10',\n status: 'Beta',\n downloads: 3100,\n },\n {\n product: 'Auth Module',\n category: 'Security',\n version: '1.5.2',\n releaseDate: '2025-07-01',\n status: 'Released',\n downloads: 15600,\n },\n {\n product: 'File Manager',\n category: 'Storage',\n version: '2.0.0',\n releaseDate: '2025-08-18',\n status: 'Planned',\n downloads: 0,\n },\n {\n product: 'Email Service',\n category: 'Communication',\n version: '3.1.0',\n releaseDate: '2025-09-05',\n status: 'Released',\n downloads: 9870,\n },\n {\n product: 'Search Index',\n category: 'Tools',\n version: '1.2.0',\n releaseDate: '2025-10-12',\n status: 'Beta',\n downloads: 2450,\n },\n {\n product: 'Cache Layer',\n category: 'Infra',\n version: '2.3.1',\n releaseDate: '2025-11-28',\n status: 'Planned',\n downloads: 0,\n },\n];\n/* end:skip-in-preview */\n// Get the DOM element with the ID 'example1' where the Handsontable will be rendered\nconst container = document.querySelector('#example1');\nconst cellDefinition = {\n validator: (value, callback) => {\n callback(isDate(new Date(value)));\n },\n renderer: rendererFactory(({ td, value, cellProperties }) => {\n td.innerText = value ? format(new Date(value), cellProperties.renderFormat) : '';\n }),\n editor: editorFactory({\n init(editor) {\n editor.input = editor.hot.rootDocument.createElement('INPUT');\n editor.input.classList.add('flatpickr-editor');\n \n editor.flatpickr = flatpickr(editor.input, {\n dateFormat: 'Y-m-d',\n disableMobile: true,\n onClose: () => {\n editor.finishEditing();\n },\n });\n\n editor.preventCloseElement = editor.flatpickr.calendarContainer;\n\n /**\n * Prepare dark theme stylesheet for dynamic loading.\n */\n editor._darkThemeLink = editor.hot.rootDocument.createElement('LINK');\n editor._darkThemeLink.rel = 'stylesheet';\n editor._darkThemeLink.href = 'https://cdn.jsdelivr.net/npm/flatpickr/dist/themes/dark.css';\n },\n afterClose(editor) {\n editor.flatpickr.close();\n },\n afterOpen(editor) {\n const isDark = editor.hot.rootDocument.documentElement.getAttribute('data-theme') === 'dark';\n\n const head = editor.hot.rootDocument.head;\n\n if (isDark && !editor._darkThemeLink.parentNode) {\n head.appendChild(editor._darkThemeLink);\n } else if (!isDark && editor._darkThemeLink.parentNode) {\n head.removeChild(editor._darkThemeLink);\n }\n\n editor.flatpickr.open();\n },\n beforeOpen(editor, { cellProperties }) {\n for (const key in cellProperties.flatpickrSettings) {\n editor.flatpickr.set(key, cellProperties.flatpickrSettings[key]);\n }\n },\n getValue(editor) {\n return editor.input.value;\n },\n setValue(editor, value) {\n editor.input.value = value;\n editor.flatpickr.setDate(value ? new Date(value) : new Date());\n },\n }),\n};\n\n// Define configuration options for the Handsontable\nconst hotOptions = {\n data,\n colHeaders: ['Product', 'Version', 'Release (EU)', 'Release (US)', 'Status'],\n autoRowSize: true,\n rowHeaders: true,\n height: 'auto',\n width: '100%',\n autoWrapRow: true,\n headerClassName: 'htLeft',\n columns: [\n { data: 'product', type: 'text', width: 200 },\n { data: 'version', type: 'text', width: 80 },\n {\n data: 'releaseDate',\n width: 130,\n allowInvalid: false,\n ...cellDefinition,\n renderFormat: DATE_FORMAT_EU,\n flatpickrSettings: {\n locale: {\n firstDayOfWeek: 1,\n },\n },\n },\n {\n data: 'releaseDate',\n width: 130,\n allowInvalid: false,\n ...cellDefinition,\n renderFormat: DATE_FORMAT_US,\n flatpickrSettings: {\n locale: {\n firstDayOfWeek: 0,\n },\n },\n },\n { data: 'status', type: 'text', width: 130 },\n ],\n licenseKey: 'non-commercial-and-evaluation',\n};\n\n// Initialize the Handsontable instance with the specified configuration options\n// eslint-disable-next-line no-unused-vars\nconst hot = new Handsontable(container, hotOptions);","/src/main.js":"import \"../styles.css\";\nimport \"../index.js\";","/styles.css":".flatpickr-editor {\n width: 100%;\n height: 100%;\n box-sizing: border-box !important;\n border: none;\n border-radius: 0;\n outline: none;\n box-shadow: inset 0 0 0 var(--ht-cell-editor-border-width, 2px)\n var(--ht-cell-editor-border-color, #1a42e8),\n 0 0 var(--ht-cell-editor-shadow-blur-radius, 0) 0\n var(--ht-cell-editor-shadow-color, transparent) !important;\n background-color: var(--ht-cell-editor-background-color, #ffffff) !important;\n padding: var(--ht-cell-vertical-padding, 4px)\n var(--ht-cell-horizontal-padding, 8px) !important;\n border: none !important;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n.flatpickr-editor:focus-visible {\n border: none !important;\n}\n\n.flatpickr-editor.active {\n box-shadow: none;\n background-color: transparent;\n border-radius: 0 !important;\n border-radius: none;\n}"},"docsPath":"recipes/cell-types/flatpickr/javascript/example1.js","breadcrumb":["Recipes","Cell Types","Flatpickr"],"guide":"recipes/cell-types/flatpickr/flatpickr.md","guideTitle":"Flatpickr","exampleId":"example1","exampleTitle":"Standard example","docPermalink":"/recipes/cell-types/flatpickr","lang":"JavaScript"} | |||
| {"framework":"javascript","displayName":"Recipes ▸ Cell Types ▸ Flatpickr · Standard example · JavaScript","tier":1,"engine":"sandpack","sandpackTemplate":"vanilla","sandpackEnvironment":"parcel","container":null,"htWrappers":[],"entry":"/src/main.js","htmlEntry":"/index.html","devCommand":null,"buildCommand":"vite build","outputDir":"dist","outputGlob":null,"staticExport":false,"spaMode":false,"port":null,"installCommand":"pnpm install","htCoreRange":"18.1.1","fileCount":5,"assets":[],"skipped":[],"files":{"/package.json":"{\n \"name\": \"handsontable-example\",\n \"version\": \"1.0.0\",\n \"private\": true,\n \"packageManager\": \"pnpm@10.34.5\",\n \"dependencies\": {\n \"handsontable\": \"18.1.1\",\n \"vite\": \"^5.4.0\",\n \"date-fns\": \"4.4.0\",\n \"flatpickr\": \"4.6.13\"\n },\n \"scripts\": {\n \"start\": \"vite\",\n \"build\": \"vite build\"\n }\n}","/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 Example</title>\n <style>body { padding: 1rem; font-family: sans-serif; }</style>\n</head>\n<body>\n <div id=\"example1\"></div>\n <script type=\"module\" src=\"/src/main.js\"></script>\n</body>\n</html>","/index.js":"import Handsontable from 'handsontable/base';\nimport { registerAllModules } from 'handsontable/registry';\nimport { format, isValid, parseISO } from 'date-fns';\nimport flatpickr from 'flatpickr';\nimport 'flatpickr/dist/flatpickr.css';\nimport { editorFactory } from 'handsontable/editors';\nimport { rendererFactory } from 'handsontable/renderers';\n\nregisterAllModules();\nconst DATE_FORMAT_US = 'MM/dd/yyyy';\nconst DATE_FORMAT_EU = 'dd/MM/yyyy';\n\n/* start:skip-in-preview */\nconst data = [\n {\n product: 'Dashboard Pro',\n category: 'Analytics',\n version: '3.2.0',\n releaseDate: '2025-03-15',\n status: 'Released',\n downloads: 12450,\n },\n {\n product: 'Form Builder',\n category: 'Tools',\n version: '2.1.0',\n releaseDate: '2025-04-22',\n status: 'Released',\n downloads: 8320,\n },\n {\n product: 'Chart Engine',\n category: 'Analytics',\n version: '4.0.0',\n releaseDate: '2025-06-10',\n status: 'Beta',\n downloads: 3100,\n },\n {\n product: 'Auth Module',\n category: 'Security',\n version: '1.5.2',\n releaseDate: '2025-07-01',\n status: 'Released',\n downloads: 15600,\n },\n {\n product: 'File Manager',\n category: 'Storage',\n version: '2.0.0',\n releaseDate: '2025-08-18',\n status: 'Planned',\n downloads: 0,\n },\n {\n product: 'Email Service',\n category: 'Communication',\n version: '3.1.0',\n releaseDate: '2025-09-05',\n status: 'Released',\n downloads: 9870,\n },\n {\n product: 'Search Index',\n category: 'Tools',\n version: '1.2.0',\n releaseDate: '2025-10-12',\n status: 'Beta',\n downloads: 2450,\n },\n {\n product: 'Cache Layer',\n category: 'Infra',\n version: '2.3.1',\n releaseDate: '2025-11-28',\n status: 'Planned',\n downloads: 0,\n },\n];\n/* end:skip-in-preview */\n// Get the DOM element with the ID 'example1' where the Handsontable will be rendered\nconst container = document.querySelector('#example1');\nconst cellDefinition = {\n validator: (value, callback) => {\n callback(!value || isValid(parseISO(value)));\n },\n renderer: rendererFactory(({ td, value, cellProperties }) => {\n const date = parseISO(value);\n\n td.innerText = value && isValid(date) ? format(date, cellProperties.renderFormat) : value || '';\n }),\n editor: editorFactory({\n init(editor) {\n editor.input = editor.hot.rootDocument.createElement('INPUT');\n editor.input.classList.add('flatpickr-editor');\n \n editor.flatpickr = flatpickr(editor.input, {\n dateFormat: 'Y-m-d',\n disableMobile: true,\n onClose: () => {\n editor.finishEditing();\n },\n });\n\n editor.preventCloseElement = editor.flatpickr.calendarContainer;\n\n /**\n * Prepare dark theme stylesheet for dynamic loading.\n */\n editor._darkThemeLink = editor.hot.rootDocument.createElement('LINK');\n editor._darkThemeLink.rel = 'stylesheet';\n editor._darkThemeLink.href = 'https://cdn.jsdelivr.net/npm/flatpickr/dist/themes/dark.css';\n },\n afterClose(editor) {\n editor.flatpickr.close();\n },\n afterOpen(editor) {\n const isDark = editor.hot.rootDocument.documentElement.getAttribute('data-theme') === 'dark';\n\n const head = editor.hot.rootDocument.head;\n\n if (isDark && !editor._darkThemeLink.parentNode) {\n head.appendChild(editor._darkThemeLink);\n } else if (!isDark && editor._darkThemeLink.parentNode) {\n head.removeChild(editor._darkThemeLink);\n }\n\n editor.flatpickr.open();\n },\n beforeOpen(editor, { cellProperties }) {\n for (const key in cellProperties.flatpickrSettings) {\n editor.flatpickr.set(key, cellProperties.flatpickrSettings[key]);\n }\n },\n getValue(editor) {\n return editor.input.value;\n },\n setValue(editor, value) {\n editor.input.value = value;\n editor.flatpickr.setDate(value ? new Date(value) : new Date());\n },\n }),\n};\n\n// Define configuration options for the Handsontable\nconst hotOptions = {\n data,\n colHeaders: ['Product', 'Version', 'Release (EU)', 'Release (US)', 'Status'],\n autoRowSize: true,\n rowHeaders: true,\n height: 'auto',\n width: '100%',\n autoWrapRow: true,\n headerClassName: 'htLeft',\n columns: [\n { data: 'product', type: 'text', width: 200 },\n { data: 'version', type: 'text', width: 80 },\n {\n data: 'releaseDate',\n width: 130,\n allowInvalid: false,\n ...cellDefinition,\n renderFormat: DATE_FORMAT_EU,\n flatpickrSettings: {\n locale: {\n firstDayOfWeek: 1,\n },\n },\n },\n {\n data: 'releaseDate',\n width: 130,\n allowInvalid: false,\n ...cellDefinition,\n renderFormat: DATE_FORMAT_US,\n flatpickrSettings: {\n locale: {\n firstDayOfWeek: 0,\n },\n },\n },\n { data: 'status', type: 'text', width: 130 },\n ],\n licenseKey: 'non-commercial-and-evaluation',\n};\n\n// Initialize the Handsontable instance with the specified configuration options\n// eslint-disable-next-line no-unused-vars\nconst hot = new Handsontable(container, hotOptions);","/src/main.js":"import \"../styles.css\";\nimport \"../index.js\";","/styles.css":".flatpickr-editor {\n width: 100%;\n height: 100%;\n box-sizing: border-box !important;\n border: none;\n border-radius: 0;\n outline: none;\n box-shadow: inset 0 0 0 var(--ht-cell-editor-border-width, 2px)\n var(--ht-cell-editor-border-color, #1a42e8),\n 0 0 var(--ht-cell-editor-shadow-blur-radius, 0) 0\n var(--ht-cell-editor-shadow-color, transparent) !important;\n background-color: var(--ht-cell-editor-background-color, #ffffff) !important;\n padding: var(--ht-cell-vertical-padding, 4px)\n var(--ht-cell-horizontal-padding, 8px) !important;\n border: none !important;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n.flatpickr-editor:focus-visible {\n border: none !important;\n}\n\n.flatpickr-editor.active {\n box-shadow: none;\n background-color: transparent;\n border-radius: 0 !important;\n border-radius: none;\n}"},"docsPath":"recipes/cell-types/flatpickr/javascript/example1.js","breadcrumb":["Recipes","Cell Types","Flatpickr"],"guide":"recipes/cell-types/flatpickr/flatpickr.md","guideTitle":"Flatpickr","exampleId":"example1","exampleTitle":"Standard example","docPermalink":"/recipes/cell-types/flatpickr","lang":"JavaScript"} | |||
There was a problem hiding this comment.
Renderer crashes on empty dates
Medium Severity
The new renderer calls parseISO before checking value. In date-fns 4.4.0, parseISO throws on null or undefined, so an empty date cell crashes rendering. The validator already skips falsy values, and the sibling Angular recipe guards first.
Additional Locations (2)
Reviewed by Cursor Bugbot for commit b611b04. Configure here.
| @@ -1 +1 @@ | |||
| {"framework":"javascript","displayName":"Recipes ▸ Cell Types ▸ Flatpickr · Standard example · JavaScript","tier":1,"engine":"sandpack","sandpackTemplate":"vanilla","sandpackEnvironment":"parcel","container":null,"htWrappers":[],"entry":"/src/main.js","htmlEntry":"/index.html","devCommand":null,"buildCommand":"vite build","outputDir":"dist","outputGlob":null,"staticExport":false,"spaMode":false,"port":null,"installCommand":"pnpm install","htCoreRange":"18.1.1","fileCount":5,"assets":[],"skipped":[],"files":{"/package.json":"{\n \"name\": \"handsontable-example\",\n \"version\": \"1.0.0\",\n \"private\": true,\n \"packageManager\": \"pnpm@10.34.5\",\n \"dependencies\": {\n \"handsontable\": \"18.1.1\",\n \"vite\": \"^5.4.0\",\n \"date-fns\": \"4.4.0\",\n \"flatpickr\": \"4.6.13\"\n },\n \"scripts\": {\n \"start\": \"vite\",\n \"build\": \"vite build\"\n }\n}","/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 Example</title>\n <style>body { padding: 1rem; font-family: sans-serif; }</style>\n</head>\n<body>\n <div id=\"example1\"></div>\n <script type=\"module\" src=\"/src/main.js\"></script>\n</body>\n</html>","/index.js":"import Handsontable from 'handsontable/base';\nimport { registerAllModules } from 'handsontable/registry';\nimport { format, isDate } from 'date-fns';\nimport flatpickr from 'flatpickr';\nimport 'flatpickr/dist/flatpickr.css';\nimport { editorFactory } from 'handsontable/editors';\nimport { rendererFactory } from 'handsontable/renderers';\n\nregisterAllModules();\nconst DATE_FORMAT_US = 'MM/dd/yyyy';\nconst DATE_FORMAT_EU = 'dd/MM/yyyy';\n\n/* start:skip-in-preview */\nconst data = [\n {\n product: 'Dashboard Pro',\n category: 'Analytics',\n version: '3.2.0',\n releaseDate: '2025-03-15',\n status: 'Released',\n downloads: 12450,\n },\n {\n product: 'Form Builder',\n category: 'Tools',\n version: '2.1.0',\n releaseDate: '2025-04-22',\n status: 'Released',\n downloads: 8320,\n },\n {\n product: 'Chart Engine',\n category: 'Analytics',\n version: '4.0.0',\n releaseDate: '2025-06-10',\n status: 'Beta',\n downloads: 3100,\n },\n {\n product: 'Auth Module',\n category: 'Security',\n version: '1.5.2',\n releaseDate: '2025-07-01',\n status: 'Released',\n downloads: 15600,\n },\n {\n product: 'File Manager',\n category: 'Storage',\n version: '2.0.0',\n releaseDate: '2025-08-18',\n status: 'Planned',\n downloads: 0,\n },\n {\n product: 'Email Service',\n category: 'Communication',\n version: '3.1.0',\n releaseDate: '2025-09-05',\n status: 'Released',\n downloads: 9870,\n },\n {\n product: 'Search Index',\n category: 'Tools',\n version: '1.2.0',\n releaseDate: '2025-10-12',\n status: 'Beta',\n downloads: 2450,\n },\n {\n product: 'Cache Layer',\n category: 'Infra',\n version: '2.3.1',\n releaseDate: '2025-11-28',\n status: 'Planned',\n downloads: 0,\n },\n];\n/* end:skip-in-preview */\n// Get the DOM element with the ID 'example1' where the Handsontable will be rendered\nconst container = document.querySelector('#example1');\nconst cellDefinition = {\n validator: (value, callback) => {\n callback(isDate(new Date(value)));\n },\n renderer: rendererFactory(({ td, value, cellProperties }) => {\n td.innerText = value ? format(new Date(value), cellProperties.renderFormat) : '';\n }),\n editor: editorFactory({\n init(editor) {\n editor.input = editor.hot.rootDocument.createElement('INPUT');\n editor.input.classList.add('flatpickr-editor');\n \n editor.flatpickr = flatpickr(editor.input, {\n dateFormat: 'Y-m-d',\n disableMobile: true,\n onClose: () => {\n editor.finishEditing();\n },\n });\n\n editor.preventCloseElement = editor.flatpickr.calendarContainer;\n\n /**\n * Prepare dark theme stylesheet for dynamic loading.\n */\n editor._darkThemeLink = editor.hot.rootDocument.createElement('LINK');\n editor._darkThemeLink.rel = 'stylesheet';\n editor._darkThemeLink.href = 'https://cdn.jsdelivr.net/npm/flatpickr/dist/themes/dark.css';\n },\n afterClose(editor) {\n editor.flatpickr.close();\n },\n afterOpen(editor) {\n const isDark = editor.hot.rootDocument.documentElement.getAttribute('data-theme') === 'dark';\n\n const head = editor.hot.rootDocument.head;\n\n if (isDark && !editor._darkThemeLink.parentNode) {\n head.appendChild(editor._darkThemeLink);\n } else if (!isDark && editor._darkThemeLink.parentNode) {\n head.removeChild(editor._darkThemeLink);\n }\n\n editor.flatpickr.open();\n },\n beforeOpen(editor, { cellProperties }) {\n for (const key in cellProperties.flatpickrSettings) {\n editor.flatpickr.set(key, cellProperties.flatpickrSettings[key]);\n }\n },\n getValue(editor) {\n return editor.input.value;\n },\n setValue(editor, value) {\n editor.input.value = value;\n editor.flatpickr.setDate(value ? new Date(value) : new Date());\n },\n }),\n};\n\n// Define configuration options for the Handsontable\nconst hotOptions = {\n data,\n colHeaders: ['Product', 'Version', 'Release (EU)', 'Release (US)', 'Status'],\n autoRowSize: true,\n rowHeaders: true,\n height: 'auto',\n width: '100%',\n autoWrapRow: true,\n headerClassName: 'htLeft',\n columns: [\n { data: 'product', type: 'text', width: 200 },\n { data: 'version', type: 'text', width: 80 },\n {\n data: 'releaseDate',\n width: 130,\n allowInvalid: false,\n ...cellDefinition,\n renderFormat: DATE_FORMAT_EU,\n flatpickrSettings: {\n locale: {\n firstDayOfWeek: 1,\n },\n },\n },\n {\n data: 'releaseDate',\n width: 130,\n allowInvalid: false,\n ...cellDefinition,\n renderFormat: DATE_FORMAT_US,\n flatpickrSettings: {\n locale: {\n firstDayOfWeek: 0,\n },\n },\n },\n { data: 'status', type: 'text', width: 130 },\n ],\n licenseKey: 'non-commercial-and-evaluation',\n};\n\n// Initialize the Handsontable instance with the specified configuration options\n// eslint-disable-next-line no-unused-vars\nconst hot = new Handsontable(container, hotOptions);","/src/main.js":"import \"../styles.css\";\nimport \"../index.js\";","/styles.css":".flatpickr-editor {\n width: 100%;\n height: 100%;\n box-sizing: border-box !important;\n border: none;\n border-radius: 0;\n outline: none;\n box-shadow: inset 0 0 0 var(--ht-cell-editor-border-width, 2px)\n var(--ht-cell-editor-border-color, #1a42e8),\n 0 0 var(--ht-cell-editor-shadow-blur-radius, 0) 0\n var(--ht-cell-editor-shadow-color, transparent) !important;\n background-color: var(--ht-cell-editor-background-color, #ffffff) !important;\n padding: var(--ht-cell-vertical-padding, 4px)\n var(--ht-cell-horizontal-padding, 8px) !important;\n border: none !important;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n.flatpickr-editor:focus-visible {\n border: none !important;\n}\n\n.flatpickr-editor.active {\n box-shadow: none;\n background-color: transparent;\n border-radius: 0 !important;\n border-radius: none;\n}"},"docsPath":"recipes/cell-types/flatpickr/javascript/example1.js","breadcrumb":["Recipes","Cell Types","Flatpickr"],"guide":"recipes/cell-types/flatpickr/flatpickr.md","guideTitle":"Flatpickr","exampleId":"example1","exampleTitle":"Standard example","docPermalink":"/recipes/cell-types/flatpickr","lang":"JavaScript"} | |||
| {"framework":"javascript","displayName":"Recipes ▸ Cell Types ▸ Flatpickr · Standard example · JavaScript","tier":1,"engine":"sandpack","sandpackTemplate":"vanilla","sandpackEnvironment":"parcel","container":null,"htWrappers":[],"entry":"/src/main.js","htmlEntry":"/index.html","devCommand":null,"buildCommand":"vite build","outputDir":"dist","outputGlob":null,"staticExport":false,"spaMode":false,"port":null,"installCommand":"pnpm install","htCoreRange":"18.1.1","fileCount":5,"assets":[],"skipped":[],"files":{"/package.json":"{\n \"name\": \"handsontable-example\",\n \"version\": \"1.0.0\",\n \"private\": true,\n \"packageManager\": \"pnpm@10.34.5\",\n \"dependencies\": {\n \"handsontable\": \"18.1.1\",\n \"vite\": \"^5.4.0\",\n \"date-fns\": \"4.4.0\",\n \"flatpickr\": \"4.6.13\"\n },\n \"scripts\": {\n \"start\": \"vite\",\n \"build\": \"vite build\"\n }\n}","/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 Example</title>\n <style>body { padding: 1rem; font-family: sans-serif; }</style>\n</head>\n<body>\n <div id=\"example1\"></div>\n <script type=\"module\" src=\"/src/main.js\"></script>\n</body>\n</html>","/index.js":"import Handsontable from 'handsontable/base';\nimport { registerAllModules } from 'handsontable/registry';\nimport { format, isValid, parseISO } from 'date-fns';\nimport flatpickr from 'flatpickr';\nimport 'flatpickr/dist/flatpickr.css';\nimport { editorFactory } from 'handsontable/editors';\nimport { rendererFactory } from 'handsontable/renderers';\n\nregisterAllModules();\nconst DATE_FORMAT_US = 'MM/dd/yyyy';\nconst DATE_FORMAT_EU = 'dd/MM/yyyy';\n\n/* start:skip-in-preview */\nconst data = [\n {\n product: 'Dashboard Pro',\n category: 'Analytics',\n version: '3.2.0',\n releaseDate: '2025-03-15',\n status: 'Released',\n downloads: 12450,\n },\n {\n product: 'Form Builder',\n category: 'Tools',\n version: '2.1.0',\n releaseDate: '2025-04-22',\n status: 'Released',\n downloads: 8320,\n },\n {\n product: 'Chart Engine',\n category: 'Analytics',\n version: '4.0.0',\n releaseDate: '2025-06-10',\n status: 'Beta',\n downloads: 3100,\n },\n {\n product: 'Auth Module',\n category: 'Security',\n version: '1.5.2',\n releaseDate: '2025-07-01',\n status: 'Released',\n downloads: 15600,\n },\n {\n product: 'File Manager',\n category: 'Storage',\n version: '2.0.0',\n releaseDate: '2025-08-18',\n status: 'Planned',\n downloads: 0,\n },\n {\n product: 'Email Service',\n category: 'Communication',\n version: '3.1.0',\n releaseDate: '2025-09-05',\n status: 'Released',\n downloads: 9870,\n },\n {\n product: 'Search Index',\n category: 'Tools',\n version: '1.2.0',\n releaseDate: '2025-10-12',\n status: 'Beta',\n downloads: 2450,\n },\n {\n product: 'Cache Layer',\n category: 'Infra',\n version: '2.3.1',\n releaseDate: '2025-11-28',\n status: 'Planned',\n downloads: 0,\n },\n];\n/* end:skip-in-preview */\n// Get the DOM element with the ID 'example1' where the Handsontable will be rendered\nconst container = document.querySelector('#example1');\nconst cellDefinition = {\n validator: (value, callback) => {\n callback(!value || isValid(parseISO(value)));\n },\n renderer: rendererFactory(({ td, value, cellProperties }) => {\n const date = parseISO(value);\n\n td.innerText = value && isValid(date) ? format(date, cellProperties.renderFormat) : value || '';\n }),\n editor: editorFactory({\n init(editor) {\n editor.input = editor.hot.rootDocument.createElement('INPUT');\n editor.input.classList.add('flatpickr-editor');\n \n editor.flatpickr = flatpickr(editor.input, {\n dateFormat: 'Y-m-d',\n disableMobile: true,\n onClose: () => {\n editor.finishEditing();\n },\n });\n\n editor.preventCloseElement = editor.flatpickr.calendarContainer;\n\n /**\n * Prepare dark theme stylesheet for dynamic loading.\n */\n editor._darkThemeLink = editor.hot.rootDocument.createElement('LINK');\n editor._darkThemeLink.rel = 'stylesheet';\n editor._darkThemeLink.href = 'https://cdn.jsdelivr.net/npm/flatpickr/dist/themes/dark.css';\n },\n afterClose(editor) {\n editor.flatpickr.close();\n },\n afterOpen(editor) {\n const isDark = editor.hot.rootDocument.documentElement.getAttribute('data-theme') === 'dark';\n\n const head = editor.hot.rootDocument.head;\n\n if (isDark && !editor._darkThemeLink.parentNode) {\n head.appendChild(editor._darkThemeLink);\n } else if (!isDark && editor._darkThemeLink.parentNode) {\n head.removeChild(editor._darkThemeLink);\n }\n\n editor.flatpickr.open();\n },\n beforeOpen(editor, { cellProperties }) {\n for (const key in cellProperties.flatpickrSettings) {\n editor.flatpickr.set(key, cellProperties.flatpickrSettings[key]);\n }\n },\n getValue(editor) {\n return editor.input.value;\n },\n setValue(editor, value) {\n editor.input.value = value;\n editor.flatpickr.setDate(value ? new Date(value) : new Date());\n },\n }),\n};\n\n// Define configuration options for the Handsontable\nconst hotOptions = {\n data,\n colHeaders: ['Product', 'Version', 'Release (EU)', 'Release (US)', 'Status'],\n autoRowSize: true,\n rowHeaders: true,\n height: 'auto',\n width: '100%',\n autoWrapRow: true,\n headerClassName: 'htLeft',\n columns: [\n { data: 'product', type: 'text', width: 200 },\n { data: 'version', type: 'text', width: 80 },\n {\n data: 'releaseDate',\n width: 130,\n allowInvalid: false,\n ...cellDefinition,\n renderFormat: DATE_FORMAT_EU,\n flatpickrSettings: {\n locale: {\n firstDayOfWeek: 1,\n },\n },\n },\n {\n data: 'releaseDate',\n width: 130,\n allowInvalid: false,\n ...cellDefinition,\n renderFormat: DATE_FORMAT_US,\n flatpickrSettings: {\n locale: {\n firstDayOfWeek: 0,\n },\n },\n },\n { data: 'status', type: 'text', width: 130 },\n ],\n licenseKey: 'non-commercial-and-evaluation',\n};\n\n// Initialize the Handsontable instance with the specified configuration options\n// eslint-disable-next-line no-unused-vars\nconst hot = new Handsontable(container, hotOptions);","/src/main.js":"import \"../styles.css\";\nimport \"../index.js\";","/styles.css":".flatpickr-editor {\n width: 100%;\n height: 100%;\n box-sizing: border-box !important;\n border: none;\n border-radius: 0;\n outline: none;\n box-shadow: inset 0 0 0 var(--ht-cell-editor-border-width, 2px)\n var(--ht-cell-editor-border-color, #1a42e8),\n 0 0 var(--ht-cell-editor-shadow-blur-radius, 0) 0\n var(--ht-cell-editor-shadow-color, transparent) !important;\n background-color: var(--ht-cell-editor-background-color, #ffffff) !important;\n padding: var(--ht-cell-vertical-padding, 4px)\n var(--ht-cell-horizontal-padding, 8px) !important;\n border: none !important;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n.flatpickr-editor:focus-visible {\n border: none !important;\n}\n\n.flatpickr-editor.active {\n box-shadow: none;\n background-color: transparent;\n border-radius: 0 !important;\n border-radius: none;\n}"},"docsPath":"recipes/cell-types/flatpickr/javascript/example1.js","breadcrumb":["Recipes","Cell Types","Flatpickr"],"guide":"recipes/cell-types/flatpickr/flatpickr.md","guideTitle":"Flatpickr","exampleId":"example1","exampleTitle":"Standard example","docPermalink":"/recipes/cell-types/flatpickr","lang":"JavaScript"} | |||
There was a problem hiding this comment.
Editor shifts dates behind UTC
Medium Severity
The renderer and validator now parse YYYY-MM-DD with parseISO (local midnight), but setValue still uses new Date(value) (UTC midnight). In timezones behind UTC, opening the picker shows the previous day and can rewrite the cell.
Additional Locations (2)
Reviewed by Cursor Bugbot for commit b611b04. Configure here.


Generated by the Import versioned docs examples workflow.
The workflow imported the requested Handsontable documentation bucket(s)
with concrete npm dependency versions.
Note
Low Risk
Only regenerated versioned documentation Sandpack JSON for one recipe; no production app or library runtime changes.
Overview
Updates the 18.1 Flatpickr “standard example” Sandpack bundles for JavaScript, TypeScript, and React so date cells use
date-fnsparseISO/isValidinstead ofisDate(new Date(value)).The validator now treats empty values as valid (
!value || isValid(parseISO(value))). The renderer only formats when the ISO string parses cleanly; otherwise it shows the raw cell value (or blank), avoiding ambiguousDateconstructor parsing in the live docs demo.Reviewed by Cursor Bugbot for commit b611b04. Bugbot is set up for automated code reviews on this repo. Configure here.