Skip to content

chore(docs): update versioned docs examples - #372

Merged
demtario merged 1 commit into
masterfrom
chore/docs-example-buckets
Sep 24, 2026
Merged

demtario merged 1 commit into
masterfrom
chore/docs-example-buckets

Conversation

@github-actions

@github-actions github-actions Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

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-fns parseISO / isValid instead of isDate(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 ambiguous Date constructor 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.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.

Fix All in Cursor

❌ 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"}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)
Fix in Cursor Fix in Web

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"}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit b611b04. Configure here.

@demtario
demtario merged commit 5a4a83d into master Sep 24, 2026
1 check passed
@demtario
demtario deleted the chore/docs-example-buckets branch September 24, 2026 06:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant