diff --git a/runner/apps/authoring/public/docs-examples/18.1/recipes__cell-types__color-picker__angular__example1.ts.json b/runner/apps/authoring/public/docs-examples/18.1/recipes__cell-types__color-picker__angular__example1.ts.json index cf1097eef..8071e55ec 100644 --- a/runner/apps/authoring/public/docs-examples/18.1/recipes__cell-types__color-picker__angular__example1.ts.json +++ b/runner/apps/authoring/public/docs-examples/18.1/recipes__cell-types__color-picker__angular__example1.ts.json @@ -1 +1 @@ -{"framework":"angular","displayName":"Recipes ▸ Cell Types ▸ Color picker · Standard example · Angular","tier":2,"engine":"container","sandpackTemplate":null,"sandpackEnvironment":null,"container":"angular","htWrappers":["@handsontable/angular-wrapper"],"entry":"/src/main.ts","htmlEntry":"/src/index.html","devCommand":"pnpm exec ng serve --host 0.0.0.0 --port 3000","buildCommand":"ng build","outputDir":"dist","outputGlob":"dist/*/browser","staticExport":false,"spaMode":false,"port":3000,"installCommand":"pnpm install","htCoreRange":"18.1.0","fileCount":7,"assets":[],"skipped":[],"files":{"/package.json":"{\n \"name\": \"handsontable-angular-example\",\n \"version\": \"1.0.0\",\n \"private\": true,\n \"packageManager\": \"pnpm@10.34.5\",\n \"scripts\": {\n \"ng\": \"ng\",\n \"start\": \"ng serve\",\n \"build\": \"ng build\"\n },\n \"dependencies\": {\n \"handsontable\": \"18.1.0\",\n \"@handsontable/angular-wrapper\": \"18.1.0\",\n \"@angular/animations\": \"22.0.6\",\n \"@angular/common\": \"22.0.6\",\n \"@angular/compiler\": \"22.0.6\",\n \"@angular/core\": \"22.0.6\",\n \"@angular/forms\": \"22.0.6\",\n \"@angular/platform-browser\": \"22.0.6\",\n \"@angular/platform-browser-dynamic\": \"22.0.6\",\n \"@angular/router\": \"22.0.6\",\n \"rxjs\": \"~7.8.2\",\n \"tslib\": \"^2.8.1\",\n \"zone.js\": \"~0.16.2\",\n \"@angular-devkit/build-angular\": \"22.0.6\",\n \"@angular/cli\": \"22.0.6\",\n \"@angular/compiler-cli\": \"22.0.6\",\n \"typescript\": \"~6.0.3\",\n \"@simonwep/pickr\": \"1.10.1\"\n },\n \"devDependencies\": {}\n}","/angular.json":"{\n \"$schema\": \"./node_modules/@angular/cli/lib/config/schema.json\",\n \"version\": 1,\n \"newProjectRoot\": \"projects\",\n \"projects\": {\n \"app\": {\n \"projectType\": \"application\",\n \"root\": \"\",\n \"sourceRoot\": \"src\",\n \"prefix\": \"app\",\n \"architect\": {\n \"build\": {\n \"builder\": \"@angular-devkit/build-angular:application\",\n \"options\": {\n \"outputPath\": \"dist/app\",\n \"index\": \"src/index.html\",\n \"browser\": \"src/main.ts\",\n \"polyfills\": [\n \"zone.js\"\n ],\n \"tsConfig\": \"tsconfig.json\",\n \"assets\": [],\n \"styles\": [],\n \"scripts\": []\n },\n \"configurations\": {\n \"development\": {\n \"optimization\": false,\n \"sourceMap\": true\n }\n },\n \"defaultConfiguration\": \"development\"\n },\n \"serve\": {\n \"builder\": \"@angular-devkit/build-angular:dev-server\",\n \"configurations\": {\n \"development\": {\n \"buildTarget\": \"app:build:development\"\n }\n },\n \"defaultConfiguration\": \"development\"\n }\n }\n }\n }\n}","/tsconfig.json":"{\n \"compilerOptions\": {\n \"outDir\": \"./dist/out-tsc\",\n \"strict\": true,\n \"noImplicitOverride\": true,\n \"noPropertyAccessFromIndexSignature\": true,\n \"noImplicitReturns\": true,\n \"noFallthroughCasesInSwitch\": true,\n \"skipLibCheck\": true,\n \"esModuleInterop\": true,\n \"sourceMap\": true,\n \"declaration\": false,\n \"experimentalDecorators\": true,\n \"moduleResolution\": \"bundler\",\n \"importHelpers\": true,\n \"target\": \"ES2022\",\n \"module\": \"ES2022\",\n \"useDefineForClassFields\": false,\n \"lib\": [\n \"ES2022\",\n \"dom\"\n ]\n },\n \"angularCompilerOptions\": {\n \"enableI18nLegacyMessageIdFormat\": false,\n \"strictInjectionParameters\": true,\n \"strictInputAccessModifiers\": true,\n \"strictTemplates\": true\n }\n}","/src/index.html":"\n\n\n \n Handsontable Angular Example\n \n \n\n\n
\n \n
\n\n","/src/main.ts":"import { bootstrapApplication } from '@angular/platform-browser';\nimport { registerAllModules } from 'handsontable/registry';\nimport { AppComponent } from './app/app.component';\nimport { appConfig } from './app/app.config';\n\nregisterAllModules();\n\nbootstrapApplication(AppComponent, appConfig).catch(err => console.error(err));","/src/app/app.component.ts":"import { Component, ChangeDetectionStrategy, ElementRef, ViewChild } from '@angular/core';\nimport {\n GridSettings,\n HotCellEditorAdvancedComponent,\n HotCellRendererAdvancedComponent,\n HotTableModule\n} from '@handsontable/angular-wrapper';\nimport Pickr from '@simonwep/pickr';\nimport '@simonwep/pickr/dist/themes/nano.min.css';\n\n/* start:skip-in-preview */\nconst inputData = [\n { id: 640329, itemName: 'Lunar Core', itemNo: 'XJ-12', cost: 350000, valueStock: 700000 },\n { id: 863104, itemName: 'Zero Thrusters', itemNo: 'QL-54', cost: 450000, valueStock: 0 },\n { id: 395603, itemName: 'EVA Suits', itemNo: 'PM-67', cost: 150000, valueStock: 7500000 },\n { id: 679083, itemName: 'Solar Panels', itemNo: 'BW-09', cost: 75000, valueStock: 750000 },\n { id: 912663, itemName: 'Comm Array', itemNo: 'ZR-56', cost: 125000, valueStock: 0 },\n { id: 315806, itemName: 'Habitat Dome', itemNo: 'UJ-23', cost: 1000000, valueStock: 3000000 },\n { id: 954632, itemName: 'Oxygen Unit', itemNo: 'FK-87', cost: 600000, valueStock: 9000000 },\n { id: 734944, itemName: 'Processing Rig', itemNo: 'LK-13', cost: 350000, valueStock: 8750000 },\n];\n/* end:skip-in-preview */\n\nconst colorValidator = (value: string): boolean => /^#[0-9A-Fa-f]{6}$/.test(value);\n\n@Component({\n standalone: true,\n selector: 'example1-color-renderer',\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n
\n \n
`,\n styles: `\n :host { height: 100%; width: 100%; }\n .color-picker-cell { display: flex; align-items: center; justify-content: center; }\n .color-picker-swatch { width: 18px; height: 18px; border-radius: 50%; flex-shrink: 0; border: 1px solid rgba(0,0,0,0.15); }\n `,\n})\nexport class ColorRendererComponent extends HotCellRendererAdvancedComponent {}\n\n@Component({\n standalone: true,\n selector: 'example1-color-picker-editor',\n template: `\n
\n \n
\n `,\n styles: `\n :host { width: 100%; height: 100%; }\n .color-picker-editor { width: 100%; height: 100%; border: none; outline: none; box-sizing: border-box !important; cursor: pointer; }\n `,\n})\nexport class ColorPickerEditorComponent extends HotCellEditorAdvancedComponent {\n @ViewChild('colorInput', { static: true }) colorInput!: ElementRef;\n @ViewChild('editorContainer', { static: true }) editorContainer!: ElementRef;\n\n private pickrInstance: Pickr | null = null;\n private pickrButton: HTMLButtonElement | null = null;\n private openedAt = 0;\n\n override afterOpen(): void {\n this.openedAt = Date.now();\n this.colorInput.nativeElement.value = this.value || '#000000';\n\n this.pickrButton = document.createElement('button');\n this.pickrButton.textContent = 'Open color picker';\n this.pickrButton.style.cssText = 'position:absolute;opacity:0;pointer-events:none;';\n this.editorContainer.nativeElement.appendChild(this.pickrButton);\n const button = this.pickrButton;\n\n this.pickrInstance = Pickr.create({\n el: button,\n theme: 'nano',\n default: this.value || '#000000',\n autoReposition: false,\n padding: 0,\n components: { preview: true, hue: true },\n });\n\n (this.pickrInstance as any)._root.root.style.height = '0';\n (this.pickrInstance as any)._root.root.style.overflow = 'hidden';\n\n this.pickrInstance.on('change', (color: { toHEXA: () => { toString: () => string } } | null) => {\n if (color) {\n const hex = color.toHEXA().toString();\n this.colorInput.nativeElement.value = hex;\n this.setValue(hex);\n }\n });\n\n this.pickrInstance.on('hide', () => {\n if (Date.now() - this.openedAt < 400) {\n this.pickrInstance?.show();\n return;\n }\n this.finishEdit.emit();\n });\n\n this.pickrInstance.show();\n\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n const cellRect = this.editorContainer.nativeElement.getBoundingClientRect();\n\n if (cellRect && this.pickrInstance) {\n (this.pickrInstance as any)._root.app.style.top = `${cellRect.bottom}px`;\n }\n });\n });\n }\n\n override afterClose(): void {\n (this.pickrInstance as any)?._root.app.classList.remove('visible');\n this.pickrInstance?.hide();\n this.pickrInstance?.destroy();\n this.pickrInstance = null;\n this.pickrButton?.remove();\n this.pickrButton = null;\n }\n\n override onFocus(): void {\n this.colorInput.nativeElement.focus();\n }\n}\n\n@Component({\n standalone: true,\n imports: [HotTableModule],\n selector: 'example1-color-picker',\n template: `
`,\n})\nexport class AppComponent {\n readonly data = inputData.map((el) => ({\n ...el,\n color: `#${Math.round(0x1000000 + 0xffffff * Math.random()).toString(16).slice(1).toUpperCase()}`,\n }));\n\n readonly gridSettings: GridSettings = {\n autoRowSize: true,\n rowHeaders: true,\n autoWrapRow: true,\n height: 'auto',\n width: '100%',\n colHeaders: ['ID', 'Item Name', 'Item Color', 'Item No.', 'Cost', 'Value in Stock'],\n columns: [\n { data: 'id', type: 'numeric', width: 80, headerClassName: 'htLeft' },\n { data: 'itemName', type: 'text', width: 200, headerClassName: 'htLeft' },\n {\n data: 'color',\n headerClassName: 'htLeft',\n editor: ColorPickerEditorComponent,\n renderer: ColorRendererComponent,\n validator: colorValidator,\n } as any,\n { data: 'itemNo', type: 'text', width: 100, headerClassName: 'htLeft' },\n { data: 'cost', type: 'numeric', width: 70, headerClassName: 'htLeft' },\n { data: 'valueStock', type: 'numeric', width: 130, headerClassName: 'htRight' },\n ],\n };\n}","/src/app/app.config.ts":"import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';\nimport { registerAllModules } from 'handsontable/registry';\nimport { HOT_GLOBAL_CONFIG, HotGlobalConfig, NON_COMMERCIAL_LICENSE } from '@handsontable/angular-wrapper';\n\nregisterAllModules();\n\nexport const appConfig: ApplicationConfig = {\n providers: [\n provideZoneChangeDetection({ eventCoalescing: true }),\n {\n provide: HOT_GLOBAL_CONFIG,\n useValue: { license: NON_COMMERCIAL_LICENSE } as HotGlobalConfig,\n },\n ],\n};"},"docsPath":"recipes/cell-types/color-picker/angular/example1.ts","breadcrumb":["Recipes","Cell Types","Color picker"],"guide":"recipes/cell-types/color-picker/color-picker.md","guideTitle":"Color picker","exampleId":"example1","exampleTitle":"Standard example","docPermalink":"/recipes/cell-types/color-picker","lang":"Angular"} +{"framework":"angular","displayName":"Recipes ▸ Cell Types ▸ Color picker · Standard example · Angular","tier":2,"engine":"container","sandpackTemplate":null,"sandpackEnvironment":null,"container":"angular","htWrappers":["@handsontable/angular-wrapper"],"entry":"/src/main.ts","htmlEntry":"/src/index.html","devCommand":"pnpm exec ng serve --host 0.0.0.0 --port 3000","buildCommand":"ng build","outputDir":"dist","outputGlob":"dist/*/browser","staticExport":false,"spaMode":false,"port":3000,"installCommand":"pnpm install","htCoreRange":"18.1.0","fileCount":7,"assets":[],"skipped":[],"files":{"/package.json":"{\n \"name\": \"handsontable-angular-example\",\n \"version\": \"1.0.0\",\n \"private\": true,\n \"packageManager\": \"pnpm@10.34.5\",\n \"scripts\": {\n \"ng\": \"ng\",\n \"start\": \"ng serve\",\n \"build\": \"ng build\"\n },\n \"dependencies\": {\n \"handsontable\": \"18.1.0\",\n \"@handsontable/angular-wrapper\": \"18.1.0\",\n \"@angular/animations\": \"22.0.6\",\n \"@angular/common\": \"22.0.6\",\n \"@angular/compiler\": \"22.0.6\",\n \"@angular/core\": \"22.0.6\",\n \"@angular/forms\": \"22.0.6\",\n \"@angular/platform-browser\": \"22.0.6\",\n \"@angular/platform-browser-dynamic\": \"22.0.6\",\n \"@angular/router\": \"22.0.6\",\n \"rxjs\": \"~7.8.2\",\n \"tslib\": \"^2.8.1\",\n \"zone.js\": \"~0.16.2\",\n \"@angular-devkit/build-angular\": \"22.0.6\",\n \"@angular/cli\": \"22.0.6\",\n \"@angular/compiler-cli\": \"22.0.6\",\n \"typescript\": \"~6.0.3\",\n \"@simonwep/pickr\": \"1.10.2\"\n },\n \"devDependencies\": {}\n}","/angular.json":"{\n \"$schema\": \"./node_modules/@angular/cli/lib/config/schema.json\",\n \"version\": 1,\n \"newProjectRoot\": \"projects\",\n \"projects\": {\n \"app\": {\n \"projectType\": \"application\",\n \"root\": \"\",\n \"sourceRoot\": \"src\",\n \"prefix\": \"app\",\n \"architect\": {\n \"build\": {\n \"builder\": \"@angular-devkit/build-angular:application\",\n \"options\": {\n \"outputPath\": \"dist/app\",\n \"index\": \"src/index.html\",\n \"browser\": \"src/main.ts\",\n \"polyfills\": [\n \"zone.js\"\n ],\n \"tsConfig\": \"tsconfig.json\",\n \"assets\": [],\n \"styles\": [],\n \"scripts\": []\n },\n \"configurations\": {\n \"development\": {\n \"optimization\": false,\n \"sourceMap\": true\n }\n },\n \"defaultConfiguration\": \"development\"\n },\n \"serve\": {\n \"builder\": \"@angular-devkit/build-angular:dev-server\",\n \"configurations\": {\n \"development\": {\n \"buildTarget\": \"app:build:development\"\n }\n },\n \"defaultConfiguration\": \"development\"\n }\n }\n }\n }\n}","/tsconfig.json":"{\n \"compilerOptions\": {\n \"outDir\": \"./dist/out-tsc\",\n \"strict\": true,\n \"noImplicitOverride\": true,\n \"noPropertyAccessFromIndexSignature\": true,\n \"noImplicitReturns\": true,\n \"noFallthroughCasesInSwitch\": true,\n \"skipLibCheck\": true,\n \"esModuleInterop\": true,\n \"sourceMap\": true,\n \"declaration\": false,\n \"experimentalDecorators\": true,\n \"moduleResolution\": \"bundler\",\n \"importHelpers\": true,\n \"target\": \"ES2022\",\n \"module\": \"ES2022\",\n \"useDefineForClassFields\": false,\n \"lib\": [\n \"ES2022\",\n \"dom\"\n ]\n },\n \"angularCompilerOptions\": {\n \"enableI18nLegacyMessageIdFormat\": false,\n \"strictInjectionParameters\": true,\n \"strictInputAccessModifiers\": true,\n \"strictTemplates\": true\n }\n}","/src/index.html":"\n\n\n \n Handsontable Angular Example\n \n \n\n\n
\n \n
\n\n","/src/main.ts":"import { bootstrapApplication } from '@angular/platform-browser';\nimport { registerAllModules } from 'handsontable/registry';\nimport { AppComponent } from './app/app.component';\nimport { appConfig } from './app/app.config';\n\nregisterAllModules();\n\nbootstrapApplication(AppComponent, appConfig).catch(err => console.error(err));","/src/app/app.component.ts":"import { Component, ChangeDetectionStrategy, ElementRef, ViewChild } from '@angular/core';\nimport {\n GridSettings,\n HotCellEditorAdvancedComponent,\n HotCellRendererAdvancedComponent,\n HotTableModule\n} from '@handsontable/angular-wrapper';\nimport Pickr from '@simonwep/pickr';\nimport '@simonwep/pickr/dist/themes/nano.min.css';\n\n/* start:skip-in-preview */\nconst inputData = [\n { id: 640329, itemName: 'Lunar Core', itemNo: 'XJ-12', cost: 350000, valueStock: 700000 },\n { id: 863104, itemName: 'Zero Thrusters', itemNo: 'QL-54', cost: 450000, valueStock: 0 },\n { id: 395603, itemName: 'EVA Suits', itemNo: 'PM-67', cost: 150000, valueStock: 7500000 },\n { id: 679083, itemName: 'Solar Panels', itemNo: 'BW-09', cost: 75000, valueStock: 750000 },\n { id: 912663, itemName: 'Comm Array', itemNo: 'ZR-56', cost: 125000, valueStock: 0 },\n { id: 315806, itemName: 'Habitat Dome', itemNo: 'UJ-23', cost: 1000000, valueStock: 3000000 },\n { id: 954632, itemName: 'Oxygen Unit', itemNo: 'FK-87', cost: 600000, valueStock: 9000000 },\n { id: 734944, itemName: 'Processing Rig', itemNo: 'LK-13', cost: 350000, valueStock: 8750000 },\n];\n/* end:skip-in-preview */\n\nconst colorValidator = (value: string): boolean => /^#[0-9A-Fa-f]{6}$/.test(value);\n\n@Component({\n standalone: true,\n selector: 'example1-color-renderer',\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n
\n \n
`,\n styles: `\n :host { height: 100%; width: 100%; }\n .color-picker-cell { display: flex; align-items: center; justify-content: center; }\n .color-picker-swatch { width: 18px; height: 18px; border-radius: 50%; flex-shrink: 0; border: 1px solid rgba(0,0,0,0.15); }\n `,\n})\nexport class ColorRendererComponent extends HotCellRendererAdvancedComponent {}\n\n@Component({\n standalone: true,\n selector: 'example1-color-picker-editor',\n template: `\n
\n \n
\n `,\n styles: `\n :host { width: 100%; height: 100%; }\n .color-picker-editor { width: 100%; height: 100%; border: none; outline: none; box-sizing: border-box !important; cursor: pointer; }\n `,\n})\nexport class ColorPickerEditorComponent extends HotCellEditorAdvancedComponent {\n @ViewChild('colorInput', { static: true }) colorInput!: ElementRef;\n @ViewChild('editorContainer', { static: true }) editorContainer!: ElementRef;\n\n private pickrInstance: Pickr | null = null;\n private pickrButton: HTMLButtonElement | null = null;\n private openedAt = 0;\n\n override afterOpen(): void {\n this.openedAt = Date.now();\n this.colorInput.nativeElement.value = this.value || '#000000';\n\n this.pickrButton = document.createElement('button');\n this.pickrButton.textContent = 'Open color picker';\n this.pickrButton.style.cssText = 'position:absolute;opacity:0;pointer-events:none;';\n this.editorContainer.nativeElement.appendChild(this.pickrButton);\n const button = this.pickrButton;\n\n this.pickrInstance = Pickr.create({\n el: button,\n theme: 'nano',\n default: this.value || '#000000',\n autoReposition: false,\n padding: 0,\n components: { preview: true, hue: true },\n });\n\n (this.pickrInstance as any)._root.root.style.height = '0';\n (this.pickrInstance as any)._root.root.style.overflow = 'hidden';\n\n this.pickrInstance.on('change', (color: { toHEXA: () => { toString: () => string } } | null) => {\n if (color) {\n const hex = color.toHEXA().toString();\n this.colorInput.nativeElement.value = hex;\n this.setValue(hex);\n }\n });\n\n this.pickrInstance.on('hide', () => {\n if (Date.now() - this.openedAt < 400) {\n this.pickrInstance?.show();\n return;\n }\n this.finishEdit.emit();\n });\n\n this.pickrInstance.show();\n\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n const cellRect = this.editorContainer.nativeElement.getBoundingClientRect();\n\n if (cellRect && this.pickrInstance) {\n (this.pickrInstance as any)._root.app.style.top = `${cellRect.bottom}px`;\n }\n });\n });\n }\n\n override afterClose(): void {\n (this.pickrInstance as any)?._root.app.classList.remove('visible');\n this.pickrInstance?.hide();\n this.pickrInstance?.destroy();\n this.pickrInstance = null;\n this.pickrButton?.remove();\n this.pickrButton = null;\n }\n\n override onFocus(): void {\n this.colorInput.nativeElement.focus();\n }\n}\n\n@Component({\n standalone: true,\n imports: [HotTableModule],\n selector: 'example1-color-picker',\n template: `
`,\n})\nexport class AppComponent {\n readonly data = inputData.map((el) => ({\n ...el,\n color: `#${Math.round(0x1000000 + 0xffffff * Math.random()).toString(16).slice(1).toUpperCase()}`,\n }));\n\n readonly gridSettings: GridSettings = {\n autoRowSize: true,\n rowHeaders: true,\n autoWrapRow: true,\n height: 'auto',\n width: '100%',\n colHeaders: ['ID', 'Item Name', 'Item Color', 'Item No.', 'Cost', 'Value in Stock'],\n columns: [\n { data: 'id', type: 'numeric', width: 80, headerClassName: 'htLeft' },\n { data: 'itemName', type: 'text', width: 200, headerClassName: 'htLeft' },\n {\n data: 'color',\n headerClassName: 'htLeft',\n editor: ColorPickerEditorComponent,\n renderer: ColorRendererComponent,\n validator: colorValidator,\n } as any,\n { data: 'itemNo', type: 'text', width: 100, headerClassName: 'htLeft' },\n { data: 'cost', type: 'numeric', width: 70, headerClassName: 'htLeft' },\n { data: 'valueStock', type: 'numeric', width: 130, headerClassName: 'htRight' },\n ],\n };\n}","/src/app/app.config.ts":"import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';\nimport { registerAllModules } from 'handsontable/registry';\nimport { HOT_GLOBAL_CONFIG, HotGlobalConfig, NON_COMMERCIAL_LICENSE } from '@handsontable/angular-wrapper';\n\nregisterAllModules();\n\nexport const appConfig: ApplicationConfig = {\n providers: [\n provideZoneChangeDetection({ eventCoalescing: true }),\n {\n provide: HOT_GLOBAL_CONFIG,\n useValue: { license: NON_COMMERCIAL_LICENSE } as HotGlobalConfig,\n },\n ],\n};"},"docsPath":"recipes/cell-types/color-picker/angular/example1.ts","breadcrumb":["Recipes","Cell Types","Color picker"],"guide":"recipes/cell-types/color-picker/color-picker.md","guideTitle":"Color picker","exampleId":"example1","exampleTitle":"Standard example","docPermalink":"/recipes/cell-types/color-picker","lang":"Angular"} diff --git a/runner/apps/authoring/public/docs-examples/18.1/recipes__cell-types__color-picker__javascript__example1.js.json b/runner/apps/authoring/public/docs-examples/18.1/recipes__cell-types__color-picker__javascript__example1.js.json index 15a728319..7b4786242 100644 --- a/runner/apps/authoring/public/docs-examples/18.1/recipes__cell-types__color-picker__javascript__example1.js.json +++ b/runner/apps/authoring/public/docs-examples/18.1/recipes__cell-types__color-picker__javascript__example1.js.json @@ -1 +1 @@ -{"framework":"javascript","displayName":"Recipes ▸ Cell Types ▸ Color picker · 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.0","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.0\",\n \"vite\": \"^5.4.0\",\n \"@simonwep/pickr\": \"1.10.1\"\n },\n \"scripts\": {\n \"start\": \"vite\",\n \"build\": \"vite build\"\n }\n}","/index.html":"\n\n\n \n \n Handsontable Example\n \n\n\n
\n \n\n","/index.js":"import Handsontable from 'handsontable/base';\nimport { registerAllModules } from 'handsontable/registry';\nimport { editorFactory } from 'handsontable/editors';\nimport { rendererFactory } from 'handsontable/renderers';\nimport Pickr from '@simonwep/pickr';\nimport '@simonwep/pickr/dist/themes/nano.min.css';\n\n// Register all Handsontable's modules.\nregisterAllModules();\n\n/* start:skip-in-preview */\nconst inputData = [\n {\n id: 640329,\n itemName: 'Lunar Core',\n itemNo: 'XJ-12',\n leadEngineer: 'Ellen Ripley',\n cost: 350000,\n inStock: true,\n category: 'Lander',\n itemQuality: 87,\n origin: '🇺🇸 USA',\n quantity: 2,\n valueStock: 700000,\n repairable: false,\n supplierName: 'TechNova',\n restockDate: '2025-08-01',\n operationalStatus: 'Awaiting Parts',\n },\n {\n id: 863104,\n itemName: 'Zero Thrusters',\n itemNo: 'QL-54',\n leadEngineer: 'Sam Bell',\n cost: 450000,\n inStock: false,\n category: 'Propulsion',\n itemQuality: 0,\n origin: '🇩🇪 Germany',\n quantity: 0,\n valueStock: 0,\n repairable: true,\n supplierName: 'PropelMax',\n restockDate: '2025-09-15',\n operationalStatus: 'In Maintenance',\n },\n {\n id: 395603,\n itemName: 'EVA Suits',\n itemNo: 'PM-67',\n leadEngineer: 'Alex Rogan',\n cost: 150000,\n inStock: true,\n category: 'Equipment',\n itemQuality: 79,\n origin: '🇮🇹 Italy',\n quantity: 50,\n valueStock: 7500000,\n repairable: true,\n supplierName: 'SuitCraft',\n restockDate: '2025-10-05',\n operationalStatus: 'Ready for Testing',\n },\n {\n id: 679083,\n itemName: 'Solar Panels',\n itemNo: 'BW-09',\n leadEngineer: 'Dave Bowman',\n cost: 75000,\n inStock: true,\n category: 'Energy',\n itemQuality: 95,\n origin: '🇺🇸 USA',\n quantity: 10,\n valueStock: 750000,\n repairable: false,\n supplierName: 'SolarStream',\n restockDate: '2025-11-10',\n operationalStatus: 'Operational',\n },\n {\n id: 912663,\n itemName: 'Comm Array',\n itemNo: 'ZR-56',\n leadEngineer: 'Louise Banks',\n cost: 125000,\n inStock: false,\n category: 'Communication',\n itemQuality: 0,\n origin: '🇯🇵 Japan',\n quantity: 0,\n valueStock: 0,\n repairable: true,\n supplierName: 'CommTech',\n restockDate: '2025-12-20',\n operationalStatus: 'Decommissioned',\n },\n {\n id: 315806,\n itemName: 'Habitat Dome',\n itemNo: 'UJ-23',\n leadEngineer: 'Dr. Ryan Stone',\n cost: 1000000,\n inStock: true,\n category: 'Shelter',\n itemQuality: 93,\n origin: '🇨🇦 Canada',\n quantity: 3,\n valueStock: 3000000,\n repairable: false,\n supplierName: 'DomeInnovate',\n restockDate: '2026-01-25',\n operationalStatus: 'Operational',\n },\n {\n id: 954632,\n itemName: 'Oxygen Unit',\n itemNo: 'FK-87',\n leadEngineer: 'Dr. Grace Augustine',\n cost: 600000,\n inStock: true,\n category: 'Life Support',\n itemQuality: 85,\n origin: '🇺🇸 USA',\n quantity: 15,\n valueStock: 9000000,\n repairable: true,\n supplierName: 'OxyGenius',\n restockDate: '2026-03-02',\n operationalStatus: 'Awaiting Parts',\n },\n {\n id: 734944,\n itemName: 'Processing Rig',\n itemNo: 'LK-13',\n leadEngineer: 'Jake Sully',\n cost: 350000,\n inStock: true,\n category: 'Mining',\n itemQuality: 81,\n origin: '🇦🇺 Australia',\n quantity: 25,\n valueStock: 8750000,\n repairable: true,\n supplierName: 'RigTech',\n restockDate: '2026-04-15',\n operationalStatus: 'Ready for Testing',\n },\n {\n id: 834662,\n itemName: 'Navigation Module',\n itemNo: 'XP-24',\n leadEngineer: 'Dr. Ellie Arroway',\n cost: 450000,\n inStock: true,\n category: 'Navigation',\n itemQuality: 89,\n origin: '🇫🇷 France',\n quantity: 8,\n valueStock: 3600000,\n repairable: false,\n supplierName: 'NavSolutions',\n restockDate: '2026-05-30',\n operationalStatus: 'In Maintenance',\n },\n {\n id: 714329,\n itemName: 'Surveyor Arm',\n itemNo: 'QA-86',\n leadEngineer: 'Mark Watney',\n cost: 100000,\n inStock: true,\n category: 'Exploration',\n itemQuality: 78,\n origin: '🇺🇸 USA',\n quantity: 40,\n valueStock: 4000000,\n repairable: true,\n supplierName: 'ExploreTech',\n restockDate: '2026-07-12',\n operationalStatus: 'Decommissioned',\n },\n];\n\nconst data = inputData.map((el) => ({\n ...el,\n // eslint-disable-next-line no-mixed-operators\n color: `#${\n // eslint-disable-next-line no-mixed-operators\n Math.round(0x1000000 + 0xffffff * Math.random())\n .toString(16)\n .slice(1)\n .toUpperCase()\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 renderer: rendererFactory(({ td, value }) => {\n td.innerHTML = ``;\n }),\n validator: (value, callback) => {\n callback(value.length === 7 && value[0] == '#'); // validate color format\n },\n editor: editorFactory({\n init(editor) {\n editor.input = editor.hot.rootDocument.createElement('INPUT');\n editor.input.setAttribute('aria-label', 'Open color picker');\n editor.input.classList.add('color-picker-editor');\n },\n afterInit(editor) {\n const button = editor.hot.rootDocument.createElement('button');\n button.textContent = 'Open color picker';\n button.classList.add('color-picker-button');\n editor.input.after(button);\n\n editor.pickr = Pickr.create({\n el: button,\n theme: 'nano',\n default: editor.input.value || '#000000',\n autoReposition: false,\n padding: 0,\n components: {\n preview: true,\n hue: true,\n }\n });\n\n // Collapse the Pickr trigger button so it doesn't add vertical space\n // between the cell editor and the popup.\n editor.pickr._root.root.style.height = '0';\n editor.pickr._root.root.style.overflow = 'hidden';\n\n editor.preventCloseElement = editor.pickr._root.app;\n\n editor.pickr.on('change', (color) => {\n if (color) {\n const hex = color.toHEXA().toString();\n editor.input.value = hex;\n }\n });\n\n editor.pickr.on('hide', () => {\n if (Date.now() - editor._openedAt < 400) {\n editor.pickr.show();\n\n return;\n }\n editor.finishEditing();\n });\n },\n afterOpen(editor) {\n editor._openedAt = Date.now();\n editor.pickr.setColor(editor.input.value || '#000000');\n editor.pickr.show();\n\n // Pickr positions its popup relative to the trigger button with an\n // internal offset. Override the top to sit flush below the cell.\n // Use double-rAF to ensure Pickr's own positioning is complete.\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n const cellRect = editor.TD.getBoundingClientRect();\n\n editor.pickr._root.app.style.top = `${cellRect.bottom}px`;\n });\n });\n },\n afterClose(editor) {\n editor.pickr._root.app.classList.remove('visible');\n editor.pickr.hide();\n },\n getValue(editor) {\n return editor.input.value;\n },\n setValue(editor, value) {\n editor.input.value = value;\n },\n shortcuts: [\n {\n keys: [['Tab']],\n callback: (editor) => {\n editor.pickr.hide();\n },\n },\n ],\n }),\n};\n\n// Define configuration options for the Handsontable\nconst hotOptions = {\n data,\n colHeaders: ['ID', 'Item Name', 'Item Color', 'Item No.', 'Cost', 'Value in Stock'],\n autoRowSize: true,\n rowHeaders: true,\n height: 'auto',\n width: '100%',\n columns: [\n {\n data: 'id',\n type: 'numeric',\n width: 80,\n headerClassName: 'htLeft',\n },\n {\n data: 'itemName',\n type: 'text',\n width: 200,\n headerClassName: 'htLeft',\n },\n {\n data: 'color',\n headerClassName: 'htLeft',\n ...cellDefinition,\n },\n {\n data: 'itemNo',\n type: 'text',\n width: 100,\n headerClassName: 'htLeft',\n },\n {\n data: 'cost',\n type: 'numeric',\n width: 70,\n headerClassName: 'htLeft',\n },\n {\n data: 'valueStock',\n type: 'numeric',\n width: 130,\n headerClassName: 'htRight',\n },\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":".color-picker-cell {\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.color-picker-swatch {\n width: 18px;\n height: 18px;\n border-radius: 50%;\n flex-shrink: 0;\n border: 1px solid rgba(0, 0, 0, 0.15);\n}\n\n.color-picker-editor {\n width: 100%;\n height: 100%;\n border: none;\n outline: none;\n box-sizing: border-box !important;\n cursor: pointer;\n -webkit-appearance: none;\n appearance: none;\n}\n\n.pickr {\n position: absolute;\n top: 0;\n left: 0;\n opacity: 0;\n pointer-events: none;\n}\n\nhtml[data-theme=\"dark\"] .pcr-app {\n background-color: #1a1a1a;\n}"},"docsPath":"recipes/cell-types/color-picker/javascript/example1.js","breadcrumb":["Recipes","Cell Types","Color picker"],"guide":"recipes/cell-types/color-picker/color-picker.md","guideTitle":"Color picker","exampleId":"example1","exampleTitle":"Standard example","docPermalink":"/recipes/cell-types/color-picker","lang":"JavaScript"} +{"framework":"javascript","displayName":"Recipes ▸ Cell Types ▸ Color picker · 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.0","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.0\",\n \"vite\": \"^5.4.0\",\n \"@simonwep/pickr\": \"1.10.2\"\n },\n \"scripts\": {\n \"start\": \"vite\",\n \"build\": \"vite build\"\n }\n}","/index.html":"\n\n\n \n \n Handsontable Example\n \n\n\n
\n \n\n","/index.js":"import Handsontable from 'handsontable/base';\nimport { registerAllModules } from 'handsontable/registry';\nimport { editorFactory } from 'handsontable/editors';\nimport { rendererFactory } from 'handsontable/renderers';\nimport Pickr from '@simonwep/pickr';\nimport '@simonwep/pickr/dist/themes/nano.min.css';\n\n// Register all Handsontable's modules.\nregisterAllModules();\n\n/* start:skip-in-preview */\nconst inputData = [\n {\n id: 640329,\n itemName: 'Lunar Core',\n itemNo: 'XJ-12',\n leadEngineer: 'Ellen Ripley',\n cost: 350000,\n inStock: true,\n category: 'Lander',\n itemQuality: 87,\n origin: '🇺🇸 USA',\n quantity: 2,\n valueStock: 700000,\n repairable: false,\n supplierName: 'TechNova',\n restockDate: '2025-08-01',\n operationalStatus: 'Awaiting Parts',\n },\n {\n id: 863104,\n itemName: 'Zero Thrusters',\n itemNo: 'QL-54',\n leadEngineer: 'Sam Bell',\n cost: 450000,\n inStock: false,\n category: 'Propulsion',\n itemQuality: 0,\n origin: '🇩🇪 Germany',\n quantity: 0,\n valueStock: 0,\n repairable: true,\n supplierName: 'PropelMax',\n restockDate: '2025-09-15',\n operationalStatus: 'In Maintenance',\n },\n {\n id: 395603,\n itemName: 'EVA Suits',\n itemNo: 'PM-67',\n leadEngineer: 'Alex Rogan',\n cost: 150000,\n inStock: true,\n category: 'Equipment',\n itemQuality: 79,\n origin: '🇮🇹 Italy',\n quantity: 50,\n valueStock: 7500000,\n repairable: true,\n supplierName: 'SuitCraft',\n restockDate: '2025-10-05',\n operationalStatus: 'Ready for Testing',\n },\n {\n id: 679083,\n itemName: 'Solar Panels',\n itemNo: 'BW-09',\n leadEngineer: 'Dave Bowman',\n cost: 75000,\n inStock: true,\n category: 'Energy',\n itemQuality: 95,\n origin: '🇺🇸 USA',\n quantity: 10,\n valueStock: 750000,\n repairable: false,\n supplierName: 'SolarStream',\n restockDate: '2025-11-10',\n operationalStatus: 'Operational',\n },\n {\n id: 912663,\n itemName: 'Comm Array',\n itemNo: 'ZR-56',\n leadEngineer: 'Louise Banks',\n cost: 125000,\n inStock: false,\n category: 'Communication',\n itemQuality: 0,\n origin: '🇯🇵 Japan',\n quantity: 0,\n valueStock: 0,\n repairable: true,\n supplierName: 'CommTech',\n restockDate: '2025-12-20',\n operationalStatus: 'Decommissioned',\n },\n {\n id: 315806,\n itemName: 'Habitat Dome',\n itemNo: 'UJ-23',\n leadEngineer: 'Dr. Ryan Stone',\n cost: 1000000,\n inStock: true,\n category: 'Shelter',\n itemQuality: 93,\n origin: '🇨🇦 Canada',\n quantity: 3,\n valueStock: 3000000,\n repairable: false,\n supplierName: 'DomeInnovate',\n restockDate: '2026-01-25',\n operationalStatus: 'Operational',\n },\n {\n id: 954632,\n itemName: 'Oxygen Unit',\n itemNo: 'FK-87',\n leadEngineer: 'Dr. Grace Augustine',\n cost: 600000,\n inStock: true,\n category: 'Life Support',\n itemQuality: 85,\n origin: '🇺🇸 USA',\n quantity: 15,\n valueStock: 9000000,\n repairable: true,\n supplierName: 'OxyGenius',\n restockDate: '2026-03-02',\n operationalStatus: 'Awaiting Parts',\n },\n {\n id: 734944,\n itemName: 'Processing Rig',\n itemNo: 'LK-13',\n leadEngineer: 'Jake Sully',\n cost: 350000,\n inStock: true,\n category: 'Mining',\n itemQuality: 81,\n origin: '🇦🇺 Australia',\n quantity: 25,\n valueStock: 8750000,\n repairable: true,\n supplierName: 'RigTech',\n restockDate: '2026-04-15',\n operationalStatus: 'Ready for Testing',\n },\n {\n id: 834662,\n itemName: 'Navigation Module',\n itemNo: 'XP-24',\n leadEngineer: 'Dr. Ellie Arroway',\n cost: 450000,\n inStock: true,\n category: 'Navigation',\n itemQuality: 89,\n origin: '🇫🇷 France',\n quantity: 8,\n valueStock: 3600000,\n repairable: false,\n supplierName: 'NavSolutions',\n restockDate: '2026-05-30',\n operationalStatus: 'In Maintenance',\n },\n {\n id: 714329,\n itemName: 'Surveyor Arm',\n itemNo: 'QA-86',\n leadEngineer: 'Mark Watney',\n cost: 100000,\n inStock: true,\n category: 'Exploration',\n itemQuality: 78,\n origin: '🇺🇸 USA',\n quantity: 40,\n valueStock: 4000000,\n repairable: true,\n supplierName: 'ExploreTech',\n restockDate: '2026-07-12',\n operationalStatus: 'Decommissioned',\n },\n];\n\nconst data = inputData.map((el) => ({\n ...el,\n // eslint-disable-next-line no-mixed-operators\n color: `#${\n // eslint-disable-next-line no-mixed-operators\n Math.round(0x1000000 + 0xffffff * Math.random())\n .toString(16)\n .slice(1)\n .toUpperCase()\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 renderer: rendererFactory(({ td, value }) => {\n td.innerHTML = ``;\n }),\n validator: (value, callback) => {\n callback(value.length === 7 && value[0] == '#'); // validate color format\n },\n editor: editorFactory({\n init(editor) {\n editor.input = editor.hot.rootDocument.createElement('INPUT');\n editor.input.setAttribute('aria-label', 'Open color picker');\n editor.input.classList.add('color-picker-editor');\n },\n afterInit(editor) {\n const button = editor.hot.rootDocument.createElement('button');\n button.textContent = 'Open color picker';\n button.classList.add('color-picker-button');\n editor.input.after(button);\n\n editor.pickr = Pickr.create({\n el: button,\n theme: 'nano',\n default: editor.input.value || '#000000',\n autoReposition: false,\n padding: 0,\n components: {\n preview: true,\n hue: true,\n }\n });\n\n // Collapse the Pickr trigger button so it doesn't add vertical space\n // between the cell editor and the popup.\n editor.pickr._root.root.style.height = '0';\n editor.pickr._root.root.style.overflow = 'hidden';\n\n editor.preventCloseElement = editor.pickr._root.app;\n\n editor.pickr.on('change', (color) => {\n if (color) {\n const hex = color.toHEXA().toString();\n editor.input.value = hex;\n }\n });\n\n editor.pickr.on('hide', () => {\n if (Date.now() - editor._openedAt < 400) {\n editor.pickr.show();\n\n return;\n }\n editor.finishEditing();\n });\n },\n afterOpen(editor) {\n editor._openedAt = Date.now();\n editor.pickr.setColor(editor.input.value || '#000000');\n editor.pickr.show();\n\n // Pickr positions its popup relative to the trigger button with an\n // internal offset. Override the top to sit flush below the cell.\n // Use double-rAF to ensure Pickr's own positioning is complete.\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n const cellRect = editor.TD.getBoundingClientRect();\n\n editor.pickr._root.app.style.top = `${cellRect.bottom}px`;\n });\n });\n },\n afterClose(editor) {\n editor.pickr._root.app.classList.remove('visible');\n editor.pickr.hide();\n },\n getValue(editor) {\n return editor.input.value;\n },\n setValue(editor, value) {\n editor.input.value = value;\n },\n shortcuts: [\n {\n keys: [['Tab']],\n callback: (editor) => {\n editor.pickr.hide();\n },\n },\n ],\n }),\n};\n\n// Define configuration options for the Handsontable\nconst hotOptions = {\n data,\n colHeaders: ['ID', 'Item Name', 'Item Color', 'Item No.', 'Cost', 'Value in Stock'],\n autoRowSize: true,\n rowHeaders: true,\n height: 'auto',\n width: '100%',\n columns: [\n {\n data: 'id',\n type: 'numeric',\n width: 80,\n headerClassName: 'htLeft',\n },\n {\n data: 'itemName',\n type: 'text',\n width: 200,\n headerClassName: 'htLeft',\n },\n {\n data: 'color',\n headerClassName: 'htLeft',\n ...cellDefinition,\n },\n {\n data: 'itemNo',\n type: 'text',\n width: 100,\n headerClassName: 'htLeft',\n },\n {\n data: 'cost',\n type: 'numeric',\n width: 70,\n headerClassName: 'htLeft',\n },\n {\n data: 'valueStock',\n type: 'numeric',\n width: 130,\n headerClassName: 'htRight',\n },\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":".color-picker-cell {\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.color-picker-swatch {\n width: 18px;\n height: 18px;\n border-radius: 50%;\n flex-shrink: 0;\n border: 1px solid rgba(0, 0, 0, 0.15);\n}\n\n.color-picker-editor {\n width: 100%;\n height: 100%;\n border: none;\n outline: none;\n box-sizing: border-box !important;\n cursor: pointer;\n -webkit-appearance: none;\n appearance: none;\n}\n\n.pickr {\n position: absolute;\n top: 0;\n left: 0;\n opacity: 0;\n pointer-events: none;\n}\n\nhtml[data-theme=\"dark\"] .pcr-app {\n background-color: #1a1a1a;\n}"},"docsPath":"recipes/cell-types/color-picker/javascript/example1.js","breadcrumb":["Recipes","Cell Types","Color picker"],"guide":"recipes/cell-types/color-picker/color-picker.md","guideTitle":"Color picker","exampleId":"example1","exampleTitle":"Standard example","docPermalink":"/recipes/cell-types/color-picker","lang":"JavaScript"} diff --git a/runner/apps/authoring/public/docs-examples/18.1/recipes__cell-types__color-picker__javascript__example1.ts.json b/runner/apps/authoring/public/docs-examples/18.1/recipes__cell-types__color-picker__javascript__example1.ts.json index 24acf8e6e..cb4170bc8 100644 --- a/runner/apps/authoring/public/docs-examples/18.1/recipes__cell-types__color-picker__javascript__example1.ts.json +++ b/runner/apps/authoring/public/docs-examples/18.1/recipes__cell-types__color-picker__javascript__example1.ts.json @@ -1 +1 @@ -{"framework":"typescript","displayName":"Recipes ▸ Cell Types ▸ Color picker · Standard example · TypeScript","tier":1,"engine":"sandpack","sandpackTemplate":"vanilla-ts","sandpackEnvironment":"parcel","container":null,"htWrappers":[],"entry":"/src/main.ts","htmlEntry":"/index.html","devCommand":null,"buildCommand":"vite build","outputDir":"dist","outputGlob":null,"staticExport":false,"spaMode":false,"port":null,"installCommand":"pnpm install","htCoreRange":"18.1.0","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.0\",\n \"vite\": \"^5.4.0\",\n \"typescript\": \"^5.4.0\",\n \"@simonwep/pickr\": \"1.10.1\"\n },\n \"scripts\": {\n \"start\": \"vite\",\n \"build\": \"vite build\"\n }\n}","/index.html":"\n\n\n \n \n Handsontable Example\n \n\n\n
\n \n\n","/index.ts":"import Handsontable from 'handsontable/base';\nimport { registerAllModules } from 'handsontable/registry';\nimport { editorFactory } from 'handsontable/editors';\nimport { rendererFactory } from 'handsontable/renderers';\nimport Pickr from '@simonwep/pickr';\nimport '@simonwep/pickr/dist/themes/nano.min.css';\nimport { CellProperties } from 'handsontable/settings';\n\n// Register all Handsontable's modules.\nregisterAllModules();\n\n/* start:skip-in-preview */\n\nconst inputData = [\n {\n id: 640329,\n itemName: 'Lunar Core',\n itemNo: 'XJ-12',\n leadEngineer: 'Ellen Ripley',\n cost: 350000,\n inStock: true,\n category: 'Lander',\n itemQuality: 87,\n origin: '🇺🇸 USA',\n quantity: 2,\n valueStock: 700000,\n repairable: false,\n supplierName: 'TechNova',\n restockDate: '2025-08-01',\n operationalStatus: 'Awaiting Parts',\n },\n {\n id: 863104,\n itemName: 'Zero Thrusters',\n itemNo: 'QL-54',\n leadEngineer: 'Sam Bell',\n cost: 450000,\n inStock: false,\n category: 'Propulsion',\n itemQuality: 0,\n origin: '🇩🇪 Germany',\n quantity: 0,\n valueStock: 0,\n repairable: true,\n supplierName: 'PropelMax',\n restockDate: '2025-09-15',\n operationalStatus: 'In Maintenance',\n },\n {\n id: 395603,\n itemName: 'EVA Suits',\n itemNo: 'PM-67',\n leadEngineer: 'Alex Rogan',\n cost: 150000,\n inStock: true,\n category: 'Equipment',\n itemQuality: 79,\n origin: '🇮🇹 Italy',\n quantity: 50,\n valueStock: 7500000,\n repairable: true,\n supplierName: 'SuitCraft',\n restockDate: '2025-10-05',\n operationalStatus: 'Ready for Testing',\n },\n {\n id: 679083,\n itemName: 'Solar Panels',\n itemNo: 'BW-09',\n leadEngineer: 'Dave Bowman',\n cost: 75000,\n inStock: true,\n category: 'Energy',\n itemQuality: 95,\n origin: '🇺🇸 USA',\n quantity: 10,\n valueStock: 750000,\n repairable: false,\n supplierName: 'SolarStream',\n restockDate: '2025-11-10',\n operationalStatus: 'Operational',\n },\n {\n id: 912663,\n itemName: 'Comm Array',\n itemNo: 'ZR-56',\n leadEngineer: 'Louise Banks',\n cost: 125000,\n inStock: false,\n category: 'Communication',\n itemQuality: 0,\n origin: '🇯🇵 Japan',\n quantity: 0,\n valueStock: 0,\n repairable: true,\n supplierName: 'CommTech',\n restockDate: '2025-12-20',\n operationalStatus: 'Decommissioned',\n },\n {\n id: 315806,\n itemName: 'Habitat Dome',\n itemNo: 'UJ-23',\n leadEngineer: 'Dr. Ryan Stone',\n cost: 1000000,\n inStock: true,\n category: 'Shelter',\n itemQuality: 93,\n origin: '🇨🇦 Canada',\n quantity: 3,\n valueStock: 3000000,\n repairable: false,\n supplierName: 'DomeInnovate',\n restockDate: '2026-01-25',\n operationalStatus: 'Operational',\n },\n {\n id: 954632,\n itemName: 'Oxygen Unit',\n itemNo: 'FK-87',\n leadEngineer: 'Dr. Grace Augustine',\n cost: 600000,\n inStock: true,\n category: 'Life Support',\n itemQuality: 85,\n origin: '🇺🇸 USA',\n quantity: 15,\n valueStock: 9000000,\n repairable: true,\n supplierName: 'OxyGenius',\n restockDate: '2026-03-02',\n operationalStatus: 'Awaiting Parts',\n },\n {\n id: 734944,\n itemName: 'Processing Rig',\n itemNo: 'LK-13',\n leadEngineer: 'Jake Sully',\n cost: 350000,\n inStock: true,\n category: 'Mining',\n itemQuality: 81,\n origin: '🇦🇺 Australia',\n quantity: 25,\n valueStock: 8750000,\n repairable: true,\n supplierName: 'RigTech',\n restockDate: '2026-04-15',\n operationalStatus: 'Ready for Testing',\n },\n {\n id: 834662,\n itemName: 'Navigation Module',\n itemNo: 'XP-24',\n leadEngineer: 'Dr. Ellie Arroway',\n cost: 450000,\n inStock: true,\n category: 'Navigation',\n itemQuality: 89,\n origin: '🇫🇷 France',\n quantity: 8,\n valueStock: 3600000,\n repairable: false,\n supplierName: 'NavSolutions',\n restockDate: '2026-05-30',\n operationalStatus: 'In Maintenance',\n },\n {\n id: 714329,\n itemName: 'Surveyor Arm',\n itemNo: 'QA-86',\n leadEngineer: 'Mark Watney',\n cost: 100000,\n inStock: true,\n category: 'Exploration',\n itemQuality: 78,\n origin: '🇺🇸 USA',\n quantity: 40,\n valueStock: 4000000,\n repairable: true,\n supplierName: 'ExploreTech',\n restockDate: '2026-07-12',\n operationalStatus: 'Decommissioned',\n }\n];\n\nconst data = inputData.map((el) => ({\n ...el,\n // eslint-disable-next-line no-mixed-operators\n color: `#${\n // eslint-disable-next-line no-mixed-operators\n Math.round(0x1000000 + 0xffffff * Math.random())\n .toString(16)\n .slice(1)\n .toUpperCase()\n }`,\n}));\n/* end:skip-in-preview */\n\n// Get the DOM element with the ID 'example1' where the Handsontable will be rendered\nconst container = document.querySelector('#example1')!;\n\ntype ColorPickerEditor = { input: HTMLInputElement; pickr: ReturnType; preventCloseElement: HTMLElement };\n\nconst cellDefinition: Pick = {\n renderer: rendererFactory(({ td, value }) => {\n td.innerHTML = ``;\n }),\n validator: (value, callback) => {\n callback(value.length === 7 && value[0] == '#'); // validate color format\n },\n editor: editorFactory({\n init(editor) {\n editor.input = editor.hot.rootDocument.createElement('INPUT') as HTMLInputElement;\n editor.input.setAttribute('aria-label', 'Open color picker');\n editor.input.classList.add('color-picker-editor');\n },\n afterInit(editor) {\n const button = editor.hot.rootDocument.createElement('button');\n button.textContent = 'Open color picker';\n button.classList.add('color-picker-button');\n editor.input.after(button);\n\n editor.pickr = Pickr.create({\n el: button,\n theme: 'nano',\n default: editor.input.value || '#000000',\n autoReposition: false,\n padding: 0,\n components: {\n preview: true,\n hue: true,\n }\n });\n\n // Collapse the Pickr trigger button so it doesn't add vertical space\n // between the cell editor and the popup.\n editor.pickr._root.root.style.height = '0';\n editor.pickr._root.root.style.overflow = 'hidden';\n\n editor.preventCloseElement = editor.pickr._root.app;\n\n editor.pickr.on('change', (color: { toHEXA: () => { toString: () => string } } | null) => {\n if (color) {\n const hex = color.toHEXA().toString();\n editor.input.value = hex;\n }\n });\n\n editor.pickr.on('hide', () => {\n if (Date.now() - editor._openedAt < 400) {\n editor.pickr.show();\n\n return;\n }\n editor.finishEditing();\n });\n },\n afterOpen(editor) {\n editor._openedAt = Date.now();\n editor.pickr.setColor(editor.input.value || '#000000');\n editor.pickr.show();\n\n // Pickr positions its popup relative to the trigger button with an\n // internal offset. Override the top to sit flush below the cell.\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n const cellRect = editor.TD.getBoundingClientRect();\n\n editor.pickr._root.app.style.top = `${cellRect.bottom}px`;\n });\n });\n },\n afterClose(editor) {\n editor.pickr._root.app.classList.remove('visible');\n editor.pickr.hide();\n },\n getValue(editor) {\n return editor.input.value;\n },\n setValue(editor, value) {\n editor.input.value = value;\n },\n shortcuts: [\n {\n keys: [['Tab']],\n callback: (editor) => {\n editor.pickr.hide();\n },\n },\n ],\n }),\n};\n\n// Define configuration options for the Handsontable\nconst hotOptions: Handsontable.GridSettings = {\n data,\n colHeaders: ['ID', 'Item Name', 'Item Color', 'Item No.', 'Cost', 'Value in Stock'],\n autoRowSize: true,\n rowHeaders: true,\n height: 'auto',\n width: '100%',\n columns: [\n { \n data: 'id', \n type: 'numeric', \n width: 80, \n headerClassName: 'htLeft' \n },\n {\n data: 'itemName',\n type: 'text',\n width: 200,\n headerClassName: 'htLeft'\n },\n {\n data: 'color',\n headerClassName: 'htLeft',\n ...cellDefinition,\n },\n {\n data: 'itemNo',\n type: 'text',\n width: 100,\n headerClassName: 'htLeft',\n },\n {\n data: 'cost',\n type: 'numeric',\n width: 70,\n headerClassName: 'htLeft',\n },\n {\n data: 'valueStock',\n type: 'numeric',\n width: 130,\n headerClassName: 'htRight',\n },\n\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.ts":"import \"../styles.css\";\nimport \"../index.ts\";","/styles.css":".color-picker-cell {\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.color-picker-swatch {\n width: 18px;\n height: 18px;\n border-radius: 50%;\n flex-shrink: 0;\n border: 1px solid rgba(0, 0, 0, 0.15);\n}\n\n.color-picker-editor {\n width: 100%;\n height: 100%;\n border: none;\n outline: none;\n box-sizing: border-box !important;\n cursor: pointer;\n -webkit-appearance: none;\n appearance: none;\n}\n\n.pickr {\n position: absolute;\n top: 0;\n left: 0;\n opacity: 0;\n pointer-events: none;\n}\n\nhtml[data-theme=\"dark\"] .pcr-app {\n background-color: #1a1a1a;\n}"},"docsPath":"recipes/cell-types/color-picker/javascript/example1.ts","breadcrumb":["Recipes","Cell Types","Color picker"],"guide":"recipes/cell-types/color-picker/color-picker.md","guideTitle":"Color picker","exampleId":"example1","exampleTitle":"Standard example","docPermalink":"/recipes/cell-types/color-picker","lang":"TypeScript"} +{"framework":"typescript","displayName":"Recipes ▸ Cell Types ▸ Color picker · Standard example · TypeScript","tier":1,"engine":"sandpack","sandpackTemplate":"vanilla-ts","sandpackEnvironment":"parcel","container":null,"htWrappers":[],"entry":"/src/main.ts","htmlEntry":"/index.html","devCommand":null,"buildCommand":"vite build","outputDir":"dist","outputGlob":null,"staticExport":false,"spaMode":false,"port":null,"installCommand":"pnpm install","htCoreRange":"18.1.0","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.0\",\n \"vite\": \"^5.4.0\",\n \"typescript\": \"^5.4.0\",\n \"@simonwep/pickr\": \"1.10.2\"\n },\n \"scripts\": {\n \"start\": \"vite\",\n \"build\": \"vite build\"\n }\n}","/index.html":"\n\n\n \n \n Handsontable Example\n \n\n\n
\n \n\n","/index.ts":"import Handsontable from 'handsontable/base';\nimport { registerAllModules } from 'handsontable/registry';\nimport { editorFactory } from 'handsontable/editors';\nimport { rendererFactory } from 'handsontable/renderers';\nimport Pickr from '@simonwep/pickr';\nimport '@simonwep/pickr/dist/themes/nano.min.css';\nimport { CellProperties } from 'handsontable/settings';\n\n// Register all Handsontable's modules.\nregisterAllModules();\n\n/* start:skip-in-preview */\n\nconst inputData = [\n {\n id: 640329,\n itemName: 'Lunar Core',\n itemNo: 'XJ-12',\n leadEngineer: 'Ellen Ripley',\n cost: 350000,\n inStock: true,\n category: 'Lander',\n itemQuality: 87,\n origin: '🇺🇸 USA',\n quantity: 2,\n valueStock: 700000,\n repairable: false,\n supplierName: 'TechNova',\n restockDate: '2025-08-01',\n operationalStatus: 'Awaiting Parts',\n },\n {\n id: 863104,\n itemName: 'Zero Thrusters',\n itemNo: 'QL-54',\n leadEngineer: 'Sam Bell',\n cost: 450000,\n inStock: false,\n category: 'Propulsion',\n itemQuality: 0,\n origin: '🇩🇪 Germany',\n quantity: 0,\n valueStock: 0,\n repairable: true,\n supplierName: 'PropelMax',\n restockDate: '2025-09-15',\n operationalStatus: 'In Maintenance',\n },\n {\n id: 395603,\n itemName: 'EVA Suits',\n itemNo: 'PM-67',\n leadEngineer: 'Alex Rogan',\n cost: 150000,\n inStock: true,\n category: 'Equipment',\n itemQuality: 79,\n origin: '🇮🇹 Italy',\n quantity: 50,\n valueStock: 7500000,\n repairable: true,\n supplierName: 'SuitCraft',\n restockDate: '2025-10-05',\n operationalStatus: 'Ready for Testing',\n },\n {\n id: 679083,\n itemName: 'Solar Panels',\n itemNo: 'BW-09',\n leadEngineer: 'Dave Bowman',\n cost: 75000,\n inStock: true,\n category: 'Energy',\n itemQuality: 95,\n origin: '🇺🇸 USA',\n quantity: 10,\n valueStock: 750000,\n repairable: false,\n supplierName: 'SolarStream',\n restockDate: '2025-11-10',\n operationalStatus: 'Operational',\n },\n {\n id: 912663,\n itemName: 'Comm Array',\n itemNo: 'ZR-56',\n leadEngineer: 'Louise Banks',\n cost: 125000,\n inStock: false,\n category: 'Communication',\n itemQuality: 0,\n origin: '🇯🇵 Japan',\n quantity: 0,\n valueStock: 0,\n repairable: true,\n supplierName: 'CommTech',\n restockDate: '2025-12-20',\n operationalStatus: 'Decommissioned',\n },\n {\n id: 315806,\n itemName: 'Habitat Dome',\n itemNo: 'UJ-23',\n leadEngineer: 'Dr. Ryan Stone',\n cost: 1000000,\n inStock: true,\n category: 'Shelter',\n itemQuality: 93,\n origin: '🇨🇦 Canada',\n quantity: 3,\n valueStock: 3000000,\n repairable: false,\n supplierName: 'DomeInnovate',\n restockDate: '2026-01-25',\n operationalStatus: 'Operational',\n },\n {\n id: 954632,\n itemName: 'Oxygen Unit',\n itemNo: 'FK-87',\n leadEngineer: 'Dr. Grace Augustine',\n cost: 600000,\n inStock: true,\n category: 'Life Support',\n itemQuality: 85,\n origin: '🇺🇸 USA',\n quantity: 15,\n valueStock: 9000000,\n repairable: true,\n supplierName: 'OxyGenius',\n restockDate: '2026-03-02',\n operationalStatus: 'Awaiting Parts',\n },\n {\n id: 734944,\n itemName: 'Processing Rig',\n itemNo: 'LK-13',\n leadEngineer: 'Jake Sully',\n cost: 350000,\n inStock: true,\n category: 'Mining',\n itemQuality: 81,\n origin: '🇦🇺 Australia',\n quantity: 25,\n valueStock: 8750000,\n repairable: true,\n supplierName: 'RigTech',\n restockDate: '2026-04-15',\n operationalStatus: 'Ready for Testing',\n },\n {\n id: 834662,\n itemName: 'Navigation Module',\n itemNo: 'XP-24',\n leadEngineer: 'Dr. Ellie Arroway',\n cost: 450000,\n inStock: true,\n category: 'Navigation',\n itemQuality: 89,\n origin: '🇫🇷 France',\n quantity: 8,\n valueStock: 3600000,\n repairable: false,\n supplierName: 'NavSolutions',\n restockDate: '2026-05-30',\n operationalStatus: 'In Maintenance',\n },\n {\n id: 714329,\n itemName: 'Surveyor Arm',\n itemNo: 'QA-86',\n leadEngineer: 'Mark Watney',\n cost: 100000,\n inStock: true,\n category: 'Exploration',\n itemQuality: 78,\n origin: '🇺🇸 USA',\n quantity: 40,\n valueStock: 4000000,\n repairable: true,\n supplierName: 'ExploreTech',\n restockDate: '2026-07-12',\n operationalStatus: 'Decommissioned',\n }\n];\n\nconst data = inputData.map((el) => ({\n ...el,\n // eslint-disable-next-line no-mixed-operators\n color: `#${\n // eslint-disable-next-line no-mixed-operators\n Math.round(0x1000000 + 0xffffff * Math.random())\n .toString(16)\n .slice(1)\n .toUpperCase()\n }`,\n}));\n/* end:skip-in-preview */\n\n// Get the DOM element with the ID 'example1' where the Handsontable will be rendered\nconst container = document.querySelector('#example1')!;\n\ntype ColorPickerEditor = { input: HTMLInputElement; pickr: ReturnType; preventCloseElement: HTMLElement };\n\nconst cellDefinition: Pick = {\n renderer: rendererFactory(({ td, value }) => {\n td.innerHTML = ``;\n }),\n validator: (value, callback) => {\n callback(value.length === 7 && value[0] == '#'); // validate color format\n },\n editor: editorFactory({\n init(editor) {\n editor.input = editor.hot.rootDocument.createElement('INPUT') as HTMLInputElement;\n editor.input.setAttribute('aria-label', 'Open color picker');\n editor.input.classList.add('color-picker-editor');\n },\n afterInit(editor) {\n const button = editor.hot.rootDocument.createElement('button');\n button.textContent = 'Open color picker';\n button.classList.add('color-picker-button');\n editor.input.after(button);\n\n editor.pickr = Pickr.create({\n el: button,\n theme: 'nano',\n default: editor.input.value || '#000000',\n autoReposition: false,\n padding: 0,\n components: {\n preview: true,\n hue: true,\n }\n });\n\n // Collapse the Pickr trigger button so it doesn't add vertical space\n // between the cell editor and the popup.\n editor.pickr._root.root.style.height = '0';\n editor.pickr._root.root.style.overflow = 'hidden';\n\n editor.preventCloseElement = editor.pickr._root.app;\n\n editor.pickr.on('change', (color: { toHEXA: () => { toString: () => string } } | null) => {\n if (color) {\n const hex = color.toHEXA().toString();\n editor.input.value = hex;\n }\n });\n\n editor.pickr.on('hide', () => {\n if (Date.now() - editor._openedAt < 400) {\n editor.pickr.show();\n\n return;\n }\n editor.finishEditing();\n });\n },\n afterOpen(editor) {\n editor._openedAt = Date.now();\n editor.pickr.setColor(editor.input.value || '#000000');\n editor.pickr.show();\n\n // Pickr positions its popup relative to the trigger button with an\n // internal offset. Override the top to sit flush below the cell.\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n const cellRect = editor.TD.getBoundingClientRect();\n\n editor.pickr._root.app.style.top = `${cellRect.bottom}px`;\n });\n });\n },\n afterClose(editor) {\n editor.pickr._root.app.classList.remove('visible');\n editor.pickr.hide();\n },\n getValue(editor) {\n return editor.input.value;\n },\n setValue(editor, value) {\n editor.input.value = value;\n },\n shortcuts: [\n {\n keys: [['Tab']],\n callback: (editor) => {\n editor.pickr.hide();\n },\n },\n ],\n }),\n};\n\n// Define configuration options for the Handsontable\nconst hotOptions: Handsontable.GridSettings = {\n data,\n colHeaders: ['ID', 'Item Name', 'Item Color', 'Item No.', 'Cost', 'Value in Stock'],\n autoRowSize: true,\n rowHeaders: true,\n height: 'auto',\n width: '100%',\n columns: [\n { \n data: 'id', \n type: 'numeric', \n width: 80, \n headerClassName: 'htLeft' \n },\n {\n data: 'itemName',\n type: 'text',\n width: 200,\n headerClassName: 'htLeft'\n },\n {\n data: 'color',\n headerClassName: 'htLeft',\n ...cellDefinition,\n },\n {\n data: 'itemNo',\n type: 'text',\n width: 100,\n headerClassName: 'htLeft',\n },\n {\n data: 'cost',\n type: 'numeric',\n width: 70,\n headerClassName: 'htLeft',\n },\n {\n data: 'valueStock',\n type: 'numeric',\n width: 130,\n headerClassName: 'htRight',\n },\n\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.ts":"import \"../styles.css\";\nimport \"../index.ts\";","/styles.css":".color-picker-cell {\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.color-picker-swatch {\n width: 18px;\n height: 18px;\n border-radius: 50%;\n flex-shrink: 0;\n border: 1px solid rgba(0, 0, 0, 0.15);\n}\n\n.color-picker-editor {\n width: 100%;\n height: 100%;\n border: none;\n outline: none;\n box-sizing: border-box !important;\n cursor: pointer;\n -webkit-appearance: none;\n appearance: none;\n}\n\n.pickr {\n position: absolute;\n top: 0;\n left: 0;\n opacity: 0;\n pointer-events: none;\n}\n\nhtml[data-theme=\"dark\"] .pcr-app {\n background-color: #1a1a1a;\n}"},"docsPath":"recipes/cell-types/color-picker/javascript/example1.ts","breadcrumb":["Recipes","Cell Types","Color picker"],"guide":"recipes/cell-types/color-picker/color-picker.md","guideTitle":"Color picker","exampleId":"example1","exampleTitle":"Standard example","docPermalink":"/recipes/cell-types/color-picker","lang":"TypeScript"} diff --git a/runner/apps/authoring/public/docs-examples/18.1/recipes__cell-types__color-picker__react__example1.tsx.json b/runner/apps/authoring/public/docs-examples/18.1/recipes__cell-types__color-picker__react__example1.tsx.json index 11e81c02f..3c60f5e10 100644 --- a/runner/apps/authoring/public/docs-examples/18.1/recipes__cell-types__color-picker__react__example1.tsx.json +++ b/runner/apps/authoring/public/docs-examples/18.1/recipes__cell-types__color-picker__react__example1.tsx.json @@ -1 +1 @@ -{"framework":"react","displayName":"Recipes ▸ Cell Types ▸ Color picker · 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.0","fileCount":6,"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.0\",\n \"@handsontable/react-wrapper\": \"18.1.0\",\n \"react\": \"18.x\",\n \"react-dom\": \"18.x\",\n \"vite\": \"^5.4.0\",\n \"@vitejs/plugin-react\": \"^4.0.0\",\n \"@simonwep/pickr\": \"1.10.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":"\n\n\n \n \n Handsontable React Example\n \n\n\n
\n \n\n","/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 { HotTable, HotColumn } from '@handsontable/react-wrapper';\nimport { registerAllModules } from 'handsontable/registry';\nimport { editorFactory } from 'handsontable/editors';\nimport { rendererFactory } from 'handsontable/renderers';\nimport Pickr from '@simonwep/pickr';\nimport '@simonwep/pickr/dist/themes/nano.min.css';\nimport './example1.css';\n\nregisterAllModules();\n\ninterface ColorPickerEditorInstance {\n input: HTMLInputElement;\n pickr: Pickr;\n _openedAt: number;\n preventCloseElement: HTMLElement;\n}\n\nconst colorPickerRenderer = rendererFactory(({ td, value }) => {\n td.innerHTML = ``;\n});\n\nconst colorPickerValidator = (value: string, callback: (valid: boolean) => void) => {\n callback(value.length === 7 && value[0] === '#');\n};\n\nconst colorPickerEditor = editorFactory({\n init(editor) {\n editor.input = editor.hot.rootDocument.createElement('INPUT') as HTMLInputElement;\n editor.input.setAttribute('aria-label', 'Open color picker');\n editor.input.classList.add('color-picker-editor');\n },\n afterInit(editor) {\n const button = editor.hot.rootDocument.createElement('button') as HTMLButtonElement;\n\n button.textContent = 'Open color picker';\n button.classList.add('color-picker-button');\n editor.input.after(button);\n\n editor.pickr = Pickr.create({\n el: button,\n theme: 'nano',\n default: editor.input.value || '#000000',\n autoReposition: false,\n padding: 0,\n components: {\n preview: true,\n hue: true,\n },\n });\n\n (editor.pickr as any)._root.root.style.height = '0';\n (editor.pickr as any)._root.root.style.overflow = 'hidden';\n\n editor.preventCloseElement = (editor.pickr as any)._root.app;\n\n editor.pickr.on('change', (color: Pickr.HSVaColor | null) => {\n if (color) {\n const hex = color.toHEXA().toString();\n\n editor.input.value = hex;\n }\n });\n\n editor.pickr.on('hide', () => {\n if (Date.now() - editor._openedAt < 400) {\n editor.pickr.show();\n\n return;\n }\n editor.finishEditing();\n });\n },\n afterOpen(editor) {\n editor._openedAt = Date.now();\n editor.pickr.setColor(editor.input.value || '#000000');\n editor.pickr.show();\n\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n const cellRect = editor.TD.getBoundingClientRect();\n\n (editor.pickr as any)._root.app.style.top = `${cellRect.bottom}px`;\n });\n });\n },\n afterClose(editor) {\n (editor.pickr as any)._root.app.classList.remove('visible');\n editor.pickr.hide();\n },\n getValue(editor) {\n return editor.input.value;\n },\n setValue(editor, value) {\n editor.input.value = value;\n },\n shortcuts: [\n {\n keys: [['Tab']],\n callback: (editor) => {\n editor.pickr.hide();\n },\n },\n ],\n});\n\n/* start:skip-in-preview */\ninterface InventoryItem {\n id: number;\n itemName: string;\n itemNo: string;\n leadEngineer: string;\n cost: number;\n inStock: boolean;\n category: string;\n itemQuality: number;\n origin: string;\n quantity: number;\n valueStock: number;\n repairable: boolean;\n supplierName: string;\n restockDate: string;\n operationalStatus: string;\n color?: string;\n}\n\nconst inputData: InventoryItem[] = [\n {\n id: 640329,\n itemName: 'Lunar Core',\n itemNo: 'XJ-12',\n leadEngineer: 'Ellen Ripley',\n cost: 350000,\n inStock: true,\n category: 'Lander',\n itemQuality: 87,\n origin: '🇺🇸 USA',\n quantity: 2,\n valueStock: 700000,\n repairable: false,\n supplierName: 'TechNova',\n restockDate: '2025-08-01',\n operationalStatus: 'Awaiting Parts',\n },\n {\n id: 863104,\n itemName: 'Zero Thrusters',\n itemNo: 'QL-54',\n leadEngineer: 'Sam Bell',\n cost: 450000,\n inStock: false,\n category: 'Propulsion',\n itemQuality: 0,\n origin: '🇩🇪 Germany',\n quantity: 0,\n valueStock: 0,\n repairable: true,\n supplierName: 'PropelMax',\n restockDate: '2025-09-15',\n operationalStatus: 'In Maintenance',\n },\n {\n id: 395603,\n itemName: 'EVA Suits',\n itemNo: 'PM-67',\n leadEngineer: 'Alex Rogan',\n cost: 150000,\n inStock: true,\n category: 'Equipment',\n itemQuality: 79,\n origin: '🇮🇹 Italy',\n quantity: 50,\n valueStock: 7500000,\n repairable: true,\n supplierName: 'SuitCraft',\n restockDate: '2025-10-05',\n operationalStatus: 'Ready for Testing',\n },\n {\n id: 679083,\n itemName: 'Solar Panels',\n itemNo: 'BW-09',\n leadEngineer: 'Dave Bowman',\n cost: 75000,\n inStock: true,\n category: 'Energy',\n itemQuality: 95,\n origin: '🇺🇸 USA',\n quantity: 10,\n valueStock: 750000,\n repairable: false,\n supplierName: 'SolarStream',\n restockDate: '2025-11-10',\n operationalStatus: 'Operational',\n },\n {\n id: 912663,\n itemName: 'Comm Array',\n itemNo: 'ZR-56',\n leadEngineer: 'Louise Banks',\n cost: 125000,\n inStock: false,\n category: 'Communication',\n itemQuality: 0,\n origin: '🇯🇵 Japan',\n quantity: 0,\n valueStock: 0,\n repairable: true,\n supplierName: 'CommTech',\n restockDate: '2025-12-20',\n operationalStatus: 'Decommissioned',\n },\n {\n id: 315806,\n itemName: 'Habitat Dome',\n itemNo: 'UJ-23',\n leadEngineer: 'Dr. Ryan Stone',\n cost: 1000000,\n inStock: true,\n category: 'Shelter',\n itemQuality: 93,\n origin: '🇨🇦 Canada',\n quantity: 3,\n valueStock: 3000000,\n repairable: false,\n supplierName: 'DomeInnovate',\n restockDate: '2026-01-25',\n operationalStatus: 'Operational',\n },\n {\n id: 954632,\n itemName: 'Oxygen Unit',\n itemNo: 'FK-87',\n leadEngineer: 'Dr. Grace Augustine',\n cost: 600000,\n inStock: true,\n category: 'Life Support',\n itemQuality: 85,\n origin: '🇺🇸 USA',\n quantity: 15,\n valueStock: 9000000,\n repairable: true,\n supplierName: 'OxyGenius',\n restockDate: '2026-03-02',\n operationalStatus: 'Awaiting Parts',\n },\n {\n id: 734944,\n itemName: 'Processing Rig',\n itemNo: 'LK-13',\n leadEngineer: 'Jake Sully',\n cost: 350000,\n inStock: true,\n category: 'Mining',\n itemQuality: 81,\n origin: '🇦🇺 Australia',\n quantity: 25,\n valueStock: 8750000,\n repairable: true,\n supplierName: 'RigTech',\n restockDate: '2026-04-15',\n operationalStatus: 'Ready for Testing',\n },\n {\n id: 834662,\n itemName: 'Navigation Module',\n itemNo: 'XP-24',\n leadEngineer: 'Dr. Ellie Arroway',\n cost: 450000,\n inStock: true,\n category: 'Navigation',\n itemQuality: 89,\n origin: '🇫🇷 France',\n quantity: 8,\n valueStock: 3600000,\n repairable: false,\n supplierName: 'NavSolutions',\n restockDate: '2026-05-30',\n operationalStatus: 'In Maintenance',\n },\n {\n id: 714329,\n itemName: 'Surveyor Arm',\n itemNo: 'QA-86',\n leadEngineer: 'Mark Watney',\n cost: 100000,\n inStock: true,\n category: 'Exploration',\n itemQuality: 78,\n origin: '🇺🇸 USA',\n quantity: 40,\n valueStock: 4000000,\n repairable: true,\n supplierName: 'ExploreTech',\n restockDate: '2026-07-12',\n operationalStatus: 'Decommissioned',\n },\n];\n\nconst data = inputData.map((el) => ({\n ...el,\n // eslint-disable-next-line no-mixed-operators\n color: `#${\n // eslint-disable-next-line no-mixed-operators\n Math.round(0x1000000 + 0xffffff * Math.random())\n .toString(16)\n .slice(1)\n .toUpperCase()\n }`,\n}));\n/* end:skip-in-preview */\n\nconst ExampleComponent = () => {\n return (\n \n \n \n \n \n \n \n \n );\n};\n\nexport default ExampleComponent;","/src/example1.css":".color-picker-cell {\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.color-picker-swatch {\n width: 18px;\n height: 18px;\n border-radius: 50%;\n flex-shrink: 0;\n border: 1px solid rgba(0, 0, 0, 0.15);\n}\n\n.color-picker-editor {\n width: 100%;\n height: 100%;\n border: none;\n outline: none;\n box-sizing: border-box !important;\n cursor: pointer;\n -webkit-appearance: none;\n appearance: none;\n}\n\n.pickr {\n position: absolute;\n top: 0;\n left: 0;\n opacity: 0;\n pointer-events: none;\n}\n\nhtml[data-theme=\"dark\"] .pcr-app {\n background-color: #1a1a1a;\n}"},"docsPath":"recipes/cell-types/color-picker/react/example1.tsx","breadcrumb":["Recipes","Cell Types","Color picker"],"guide":"recipes/cell-types/color-picker/color-picker.md","guideTitle":"Color picker","exampleId":"example1","exampleTitle":"Standard example","docPermalink":"/recipes/cell-types/color-picker","lang":"React (TS)"} +{"framework":"react","displayName":"Recipes ▸ Cell Types ▸ Color picker · 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.0","fileCount":6,"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.0\",\n \"@handsontable/react-wrapper\": \"18.1.0\",\n \"react\": \"18.x\",\n \"react-dom\": \"18.x\",\n \"vite\": \"^5.4.0\",\n \"@vitejs/plugin-react\": \"^4.0.0\",\n \"@simonwep/pickr\": \"1.10.2\"\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":"\n\n\n \n \n Handsontable React Example\n \n\n\n
\n \n\n","/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 { HotTable, HotColumn } from '@handsontable/react-wrapper';\nimport { registerAllModules } from 'handsontable/registry';\nimport { editorFactory } from 'handsontable/editors';\nimport { rendererFactory } from 'handsontable/renderers';\nimport Pickr from '@simonwep/pickr';\nimport '@simonwep/pickr/dist/themes/nano.min.css';\nimport './example1.css';\n\nregisterAllModules();\n\ninterface ColorPickerEditorInstance {\n input: HTMLInputElement;\n pickr: Pickr;\n _openedAt: number;\n preventCloseElement: HTMLElement;\n}\n\nconst colorPickerRenderer = rendererFactory(({ td, value }) => {\n td.innerHTML = ``;\n});\n\nconst colorPickerValidator = (value: string, callback: (valid: boolean) => void) => {\n callback(value.length === 7 && value[0] === '#');\n};\n\nconst colorPickerEditor = editorFactory({\n init(editor) {\n editor.input = editor.hot.rootDocument.createElement('INPUT') as HTMLInputElement;\n editor.input.setAttribute('aria-label', 'Open color picker');\n editor.input.classList.add('color-picker-editor');\n },\n afterInit(editor) {\n const button = editor.hot.rootDocument.createElement('button') as HTMLButtonElement;\n\n button.textContent = 'Open color picker';\n button.classList.add('color-picker-button');\n editor.input.after(button);\n\n editor.pickr = Pickr.create({\n el: button,\n theme: 'nano',\n default: editor.input.value || '#000000',\n autoReposition: false,\n padding: 0,\n components: {\n preview: true,\n hue: true,\n },\n });\n\n (editor.pickr as any)._root.root.style.height = '0';\n (editor.pickr as any)._root.root.style.overflow = 'hidden';\n\n editor.preventCloseElement = (editor.pickr as any)._root.app;\n\n editor.pickr.on('change', (color: Pickr.HSVaColor | null) => {\n if (color) {\n const hex = color.toHEXA().toString();\n\n editor.input.value = hex;\n }\n });\n\n editor.pickr.on('hide', () => {\n if (Date.now() - editor._openedAt < 400) {\n editor.pickr.show();\n\n return;\n }\n editor.finishEditing();\n });\n },\n afterOpen(editor) {\n editor._openedAt = Date.now();\n editor.pickr.setColor(editor.input.value || '#000000');\n editor.pickr.show();\n\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n const cellRect = editor.TD.getBoundingClientRect();\n\n (editor.pickr as any)._root.app.style.top = `${cellRect.bottom}px`;\n });\n });\n },\n afterClose(editor) {\n (editor.pickr as any)._root.app.classList.remove('visible');\n editor.pickr.hide();\n },\n getValue(editor) {\n return editor.input.value;\n },\n setValue(editor, value) {\n editor.input.value = value;\n },\n shortcuts: [\n {\n keys: [['Tab']],\n callback: (editor) => {\n editor.pickr.hide();\n },\n },\n ],\n});\n\n/* start:skip-in-preview */\ninterface InventoryItem {\n id: number;\n itemName: string;\n itemNo: string;\n leadEngineer: string;\n cost: number;\n inStock: boolean;\n category: string;\n itemQuality: number;\n origin: string;\n quantity: number;\n valueStock: number;\n repairable: boolean;\n supplierName: string;\n restockDate: string;\n operationalStatus: string;\n color?: string;\n}\n\nconst inputData: InventoryItem[] = [\n {\n id: 640329,\n itemName: 'Lunar Core',\n itemNo: 'XJ-12',\n leadEngineer: 'Ellen Ripley',\n cost: 350000,\n inStock: true,\n category: 'Lander',\n itemQuality: 87,\n origin: '🇺🇸 USA',\n quantity: 2,\n valueStock: 700000,\n repairable: false,\n supplierName: 'TechNova',\n restockDate: '2025-08-01',\n operationalStatus: 'Awaiting Parts',\n },\n {\n id: 863104,\n itemName: 'Zero Thrusters',\n itemNo: 'QL-54',\n leadEngineer: 'Sam Bell',\n cost: 450000,\n inStock: false,\n category: 'Propulsion',\n itemQuality: 0,\n origin: '🇩🇪 Germany',\n quantity: 0,\n valueStock: 0,\n repairable: true,\n supplierName: 'PropelMax',\n restockDate: '2025-09-15',\n operationalStatus: 'In Maintenance',\n },\n {\n id: 395603,\n itemName: 'EVA Suits',\n itemNo: 'PM-67',\n leadEngineer: 'Alex Rogan',\n cost: 150000,\n inStock: true,\n category: 'Equipment',\n itemQuality: 79,\n origin: '🇮🇹 Italy',\n quantity: 50,\n valueStock: 7500000,\n repairable: true,\n supplierName: 'SuitCraft',\n restockDate: '2025-10-05',\n operationalStatus: 'Ready for Testing',\n },\n {\n id: 679083,\n itemName: 'Solar Panels',\n itemNo: 'BW-09',\n leadEngineer: 'Dave Bowman',\n cost: 75000,\n inStock: true,\n category: 'Energy',\n itemQuality: 95,\n origin: '🇺🇸 USA',\n quantity: 10,\n valueStock: 750000,\n repairable: false,\n supplierName: 'SolarStream',\n restockDate: '2025-11-10',\n operationalStatus: 'Operational',\n },\n {\n id: 912663,\n itemName: 'Comm Array',\n itemNo: 'ZR-56',\n leadEngineer: 'Louise Banks',\n cost: 125000,\n inStock: false,\n category: 'Communication',\n itemQuality: 0,\n origin: '🇯🇵 Japan',\n quantity: 0,\n valueStock: 0,\n repairable: true,\n supplierName: 'CommTech',\n restockDate: '2025-12-20',\n operationalStatus: 'Decommissioned',\n },\n {\n id: 315806,\n itemName: 'Habitat Dome',\n itemNo: 'UJ-23',\n leadEngineer: 'Dr. Ryan Stone',\n cost: 1000000,\n inStock: true,\n category: 'Shelter',\n itemQuality: 93,\n origin: '🇨🇦 Canada',\n quantity: 3,\n valueStock: 3000000,\n repairable: false,\n supplierName: 'DomeInnovate',\n restockDate: '2026-01-25',\n operationalStatus: 'Operational',\n },\n {\n id: 954632,\n itemName: 'Oxygen Unit',\n itemNo: 'FK-87',\n leadEngineer: 'Dr. Grace Augustine',\n cost: 600000,\n inStock: true,\n category: 'Life Support',\n itemQuality: 85,\n origin: '🇺🇸 USA',\n quantity: 15,\n valueStock: 9000000,\n repairable: true,\n supplierName: 'OxyGenius',\n restockDate: '2026-03-02',\n operationalStatus: 'Awaiting Parts',\n },\n {\n id: 734944,\n itemName: 'Processing Rig',\n itemNo: 'LK-13',\n leadEngineer: 'Jake Sully',\n cost: 350000,\n inStock: true,\n category: 'Mining',\n itemQuality: 81,\n origin: '🇦🇺 Australia',\n quantity: 25,\n valueStock: 8750000,\n repairable: true,\n supplierName: 'RigTech',\n restockDate: '2026-04-15',\n operationalStatus: 'Ready for Testing',\n },\n {\n id: 834662,\n itemName: 'Navigation Module',\n itemNo: 'XP-24',\n leadEngineer: 'Dr. Ellie Arroway',\n cost: 450000,\n inStock: true,\n category: 'Navigation',\n itemQuality: 89,\n origin: '🇫🇷 France',\n quantity: 8,\n valueStock: 3600000,\n repairable: false,\n supplierName: 'NavSolutions',\n restockDate: '2026-05-30',\n operationalStatus: 'In Maintenance',\n },\n {\n id: 714329,\n itemName: 'Surveyor Arm',\n itemNo: 'QA-86',\n leadEngineer: 'Mark Watney',\n cost: 100000,\n inStock: true,\n category: 'Exploration',\n itemQuality: 78,\n origin: '🇺🇸 USA',\n quantity: 40,\n valueStock: 4000000,\n repairable: true,\n supplierName: 'ExploreTech',\n restockDate: '2026-07-12',\n operationalStatus: 'Decommissioned',\n },\n];\n\nconst data = inputData.map((el) => ({\n ...el,\n // eslint-disable-next-line no-mixed-operators\n color: `#${\n // eslint-disable-next-line no-mixed-operators\n Math.round(0x1000000 + 0xffffff * Math.random())\n .toString(16)\n .slice(1)\n .toUpperCase()\n }`,\n}));\n/* end:skip-in-preview */\n\nconst ExampleComponent = () => {\n return (\n \n \n \n \n \n \n \n \n );\n};\n\nexport default ExampleComponent;","/src/example1.css":".color-picker-cell {\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.color-picker-swatch {\n width: 18px;\n height: 18px;\n border-radius: 50%;\n flex-shrink: 0;\n border: 1px solid rgba(0, 0, 0, 0.15);\n}\n\n.color-picker-editor {\n width: 100%;\n height: 100%;\n border: none;\n outline: none;\n box-sizing: border-box !important;\n cursor: pointer;\n -webkit-appearance: none;\n appearance: none;\n}\n\n.pickr {\n position: absolute;\n top: 0;\n left: 0;\n opacity: 0;\n pointer-events: none;\n}\n\nhtml[data-theme=\"dark\"] .pcr-app {\n background-color: #1a1a1a;\n}"},"docsPath":"recipes/cell-types/color-picker/react/example1.tsx","breadcrumb":["Recipes","Cell Types","Color picker"],"guide":"recipes/cell-types/color-picker/color-picker.md","guideTitle":"Color picker","exampleId":"example1","exampleTitle":"Standard example","docPermalink":"/recipes/cell-types/color-picker","lang":"React (TS)"}