Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsBlogPro
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Authors
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

Handsontable Celltype Dev

ASecurity

Use when creating or modifying a Handsontable cell type that composes an editor, renderer, and validator into a reusable configuration object registered by name

22,052 stars
0 votes
0 copies
1 views
Added 9/19/2026
developmentgogitapi

Works with

api

Security Analysis

A100/100

Scanned 9/19/2026

$npx -y skills add handsontable/handsontable --skill handsontable-celltype-dev --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Handsontable Celltype Dev?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Handsontable Celltype Dev
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/handsontable-handsontable-celltype-dev/badge)](https://www.skillsdirectory.com/skills/handsontable-handsontable-celltype-dev)

More formats (shields.io, HTML) on the badges page.

Download with Pro
Files
SKILL.md
---
name: handsontable-celltype-dev
path: handsontable/src/cellTypes/**
description: Use when creating or modifying a Handsontable cell type that composes an editor, renderer, and validator into a reusable configuration object registered by name
---

# Handsontable Cell Type Development

## Structure

Cell types are **composition objects**, not classes. They bundle an editor, renderer, and validator under a single name:

```js
export const MyCellType = {
  CELL_TYPE: 'myType',
  editor: MyEditor,
  renderer: myRenderer,
  validator: myValidator,
  // Optional:
  valueSetter: customSetter,
  valueGetter: customGetter,
  valueFormatter: customFormatter,
  dataType: 'myType',
};
```

When a column or cell sets `type: 'myType'`, Handsontable applies all composed components automatically.

## File structure

```
src/cellTypes/{typeName}/
  {typeName}.ts    # Cell type object
  index.ts         # Re-exports
```

Registry: `src/cellTypes/registry.ts`.

## Registration

```js
import { registerCellType } from '../../cellTypes/registry';
registerCellType(MyCellType);
```

Also export from `src/cellTypes/index.ts` so the type is available in the full bundle.

## Integration with metaSchema

New cell types must be added to `src/dataMap/metaManager/metaSchema.ts` so Handsontable recognizes the type name in configuration. Add the type string to the `type` option's accepted values.

## Key rules

- **Think of cell types as pre-configured bundles.** They exist for convenience - users set one `type` instead of specifying `editor`, `renderer`, and `validator` separately.
- **All components are optional.** A cell type can omit `validator` if no validation is needed, or omit `editor` for read-only display types.
- **Individual overrides win.** If a user sets both `type: 'myType'` and `renderer: customRenderer`, the explicit `renderer` takes precedence over the one from the cell type.
- **`valueSetter` is the ONLY place a type may normalize an incoming value — never the editor alone, and never a plugin.** A value reaches a cell by many routes, and the editor is only one of them: a paste, `setDataAtCell()`, `populateFromArray()`, autofill and undo all bypass it. `valueSetter` runs on every one of those, so a type whose stored shape differs from what the user writes (a key/value `source`, a complex-format type) must resolve it there. Two rules come with that, both learned from DEV-57, where the autocomplete editor resolved a typed label against `source` while nothing else did — a pasted label was stored as a bare string among key/value objects, and a `strict` `dropdown` then marked the cell invalid:
  - **Share the rule with the editor, do not copy it.** The single implementation is `findChoiceByDisplayedValue()` (`utils/cellSource.ts`), called by both `autocompleteEditor#getValue()` and the autocomplete `valueSetter`. Two copies of one matching rule is exactly what let those paths drift.
  - **Anything exported from `src/helpers/**` is public API forever, types included.** `index.ts` spreads those modules onto `Handsontable.helper` and `base.ts` types the namespace as `typeof import('./helpers/object')`, so a new export there is a permanent maintenance commitment and a narrowed signature is a break. That is why `utils/cellSource.ts` holds the whole key/value rule — including `isKeyValueEntry()`, the narrowing form of the public `isKeyValueObject()`. It **delegates** to the public function rather than repeating the shape test, so the two cannot disagree, and `helpers/object.ts` keeps a zero diff. Reach for `src/utils/` for anything a cell type needs.
  - **`valueSetter` takes five arguments: `(value, visualRow, visualCol, cellMeta, source)`.** `utils/valueAccessors.ts` passes all five, so `cellMeta.source`, `cellMeta.allowHtml` and the change source need no plumbing. Type the meta parameter as a `Pick<CellProperties, …>` of the fields you read, so a unit test need not build a whole meta object; read anything else through `this.getCellMetaTransient`, never `this.getCellMeta` (see the core `AGENTS.md`). The `source` parameter is declared **optional** on the public type on purpose — a required fifth parameter would raise the option's minimum call arity and break a consumer that reads the option back out and calls it with four (`.ai/BREAKING-CHANGES.md`).
  - **Never write a delegating setter by hand — re-export.** `dropdownType/accessors/valueSetter.ts` used to be a hand-written delegate, and it dropped `cellMeta`, which left the strict column — the one where the bug is visible — unfixed while the non-strict one worked. It is now `export { valueSetter } from '../../autocompleteType/accessors';`: a re-export has no argument list to keep in sync, so that class of mistake is gone rather than documented. A unit test pins the identity (`DropdownCellType.valueSetter` is `AutocompleteCellType.valueSetter`).
  - **Skip every transformation on `UndoRedo.*`.** `utils/valueAccessors.ts` states the invariant — undo and redo restore what the cell held before, verbatim — and honors it for `emptyValue`. The autocomplete setter did not: it wrapped a restored plain label as `{ key: <label>, value: <label> }` whenever the cell happened to hold an entry, so undoing a column loaded with plain labels produced a fabricated pair a `strict` column then rejected. Return `newValue` untouched when `source` starts with `'UndoRedo.'`.
  - **Guard an empty write.** `isEmpty(newValue)` must skip any resolution, or a `source` entry carrying an empty label stands in for "no value" and `allowEmpty` stops meaning what it says.
  - **Gate the expensive part on a cheap shape check.** The setter runs once per changed cell, so a paste of thousands of rows multiplies whatever it does. `hasKeyValueChoices()` reads only the entries' shape — no string work — so a column whose `source` holds plain strings never pays for a label scan it could not use. Do not memoize the scan itself: a `source` array can be mutated in place by the host application, and a stale displayed-text map would resolve a label to an option no longer offered.
  - **The gate bounds who pays, not how much.** A column that *does* hold key/value entries still runs `findChoiceByDisplayedValue()` per changed cell, and that is a linear scan which calls `stringify()` and `stripTags()` on every choice it walks — `stripTags()` reads the label character by character. Cost is therefore `changed cells × source size`. At realistic dropdown sizes (10–100 options) a 10k-row paste stays in single-digit milliseconds, but a source in the hundreds-to-thousands turns the same paste into roughly a second of scanning. That is the accepted price of never serving a stale option; if a source that large ever needs to be fast, the fix is a map invalidated by identity, not a plain cache.

## Reference implementations

- `src/cellTypes/numericType/numericType.ts` - Composes numeric editor, renderer, and validator.
- `src/cellTypes/textType/textType.ts` - Simplest type, good starting template.
- `src/cellTypes/dateType/dateType.ts` - Date handling with format options.
- `src/cellTypes/checkboxType/checkboxType.ts` - Boolean toggle pattern.

## Common mistakes

- Forgetting to register the cell type in `src/cellTypes/registry.ts`.
- Not adding the type to `metaSchema.ts`, causing Handsontable to ignore the type name.
- Duplicating editor/renderer/validator logic instead of importing existing components.
- Not exporting from `src/cellTypes/index.ts` for the full bundle.

Attribution

handsontablehandsontable
View sourceMore from handsontable →
SSkills DirectorySkills Directory

Your tool, in front of Claude Code builders.

3 founder slots · $299/mo · GSC-verified traffic · sponsors can never buy grades.

See placements

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Your tool, in front of Claude Code builders.

3 founder slots · $299/mo · GSC-verified traffic · sponsors can never buy grades.

See placements

Related Skills

Browser Extension Developer

Use this skill when developing or maintaining browser extension code in the `browser/` directory, including Chrome/Firefox/Edge compatibility, content scripts, background scripts, or i18n updates.

285172 votes

Seo Optimizer

SEO optimization with keyword analysis, readability assessment, technical validation, content quality. Use for search rankings, blog posts, content audits, or encountering keyword density, readability scores, meta tags, schema markup errors.

2222 votes

Google Official Seo Guide

Official Google SEO guide covering search optimization, best practices, Search Console, crawling, indexing, and improving website search visibility based on official Google documentation

1862 votes

Tanstack Start

Build a full-stack TanStack Start app on Cloudflare Workers from scratch — SSR, file-based routing, server functions, D1+Drizzle, better-auth, Tailwind v4+shadcn/ui. Use whenever the user mentions TanStack Start, asks to scaffold a full-stack Cloudflare app with SSR, wants an SSR dashboard, or asks for a React 19 + Cloudflare Workers app with file-based routing and server functions — even if they don't name TanStack Start specifically. No template repo — Claude generates every file fresh per ...

10311 votes

Pentest

PTES-aligned adversarial security audit for backend, frontend, and mobile applications. Produces a CVSS-scored Hacker Report with verified PoCs and phased remediation.

5491 votes
View all in development →