0.3.2 - 2026-10-08

← All releases

Change Who is affected What to do
A commit whose value equals the cell’s current value records nothing and does not fire onCellChange Code that relied on onCellChange firing every time an editor closed (tracking the last edited cell, enabling a save button) Only real value changes fire now. To react to an editor closing, use onSelectionChange or handle it in the editor itself
A custom renderer always starts at textAlign: 'left', textBaseline: 'middle' and the body text colour A custom renderer whose coordinates were corrected for the alignment the previous column left behind Drop the correction and use the plain coordinates. For another alignment, set it inside the renderer or use args.text({ align })
A type: 'date' column with no format follows the locale’s date pattern (MM/DD/YYYY for en, YYYY-MM-DD for ko, YYYY/MM/DD for ja and zh) Date columns left without a format under the en, ja or zh locale: the cell text, clipboard copy, CSV and Excel format change, and the editor becomes the masked input instead of the native date input Write format: 'YYYY-MM-DD' on the column, or i18n: { dateFormat: 'YYYY-MM-DD' } on the grid, to keep what you had. Use format: 'locale' for the native picker. Nothing changes under ko, whose pattern is YYYY-MM-DD
A date value that reads neither through the column’s pattern nor as ISO text is shown as it is stored, unconverted, and marked invalid A server sending dates in a format other than the column’s (03/01/2020 into a YYYY-MM-DD column) Match the column’s format to the data, or have the server send ISO (2024-03-05) or the column’s own format

Added

  • text(str, opts?) on the custom-renderer arguments. It handles the cell box, the column’s alignment, vertical centring and ellipsis clipping at the cell edge, so a renderer that draws one line of text needs no coordinates. It belongs to a column’s renderer, so cellDecorator does not get it: a decorator draws on top of a cell that is already drawn, still on ctx with x/y/w/h, and the canvas state it inherits is not fixed, so it sets textAlign, textBaseline and fillStyle itself before writing text. opts takes align (defaults to the column’s own alignment), color, size, bold, font and padding. It is only valid while the renderer runs: keeping it and calling it later draws nothing. Anything that is not a line of text (shapes, icons) is still drawn on ctx with x/y/w/h

    registerCellRenderer('stars', () => (ctx, { value, text }) => {
      const n = Math.max(0, Math.min(5, Math.round(Number(value) || 0)));
      text('★'.repeat(n) + '☆'.repeat(5 - n), { color: '#f59e0b', size: 15 });
    });
    

Changed

  • A type: 'date' column with no format of its own follows the locale’s date pattern. It comes from the new dateFormat key of the text packs - MM/DD/YYYY for en, YYYY-MM-DD for ko, YYYY/MM/DD for ja and zh - and i18n: { dateFormat: 'DD.MM.YYYY' } overrides it for a whole grid. A pattern still drives the cell text, the editor’s input mask, validation, clipboard copy, CSV and the Excel number format, so a date column without a format now edits with the masked input rather than the native date input. Use format: 'locale' for the native picker and ISO storage

  • The date editor opens an ISO value in the column’s pattern. A 2024-03-05 in an MM/DD/YYYY column reads 03/05/2024 in the cell but the editor opened on 2024-03-05

Fixed

  • A date value in a format other than the column’s was read with new Date(string) and silently became another date. The engine’s fallback parser reads an unrecognized string month-first, so 03/01/2020 in a default YYYY-MM-DD column became 2020-03-01 (March 1st) whatever the locale. It was not only the cell text: clipboard copy, CSV and Excel export, printing and printGrid() all used that same value. A date value is now read through the column’s pattern or as ISO text, and a value that is neither is used exactly as stored. An ISO timestamp that names its zone (Z, +09:00) is unambiguous, so it is still read as an instant and shown in local time

  • A value that matched the pattern but named a date that does not exist rolled over into the next month or day. 13/01/2020 in an MM/DD/YYYY column became new Date(2020, 12, 1), displayed as January 1st 2021. Month 1 to 12, a day that exists in that month (leap years included) and the hour/minute/second ranges are now checked, and a value outside them is left as it is

  • Opening the editor on a narrow date column showed the cell’s text through the calendar button. The 22px strip the button covers had no background of its own, so once the column was narrow enough for the cell text to reach that far, the text the canvas had drawn underneath stayed visible beside the glyph. The strip now carries the same background as the editor

  • validation.min / max on a date column without a format read the value with Date.parse, bringing the same month-first guess into the comparison: 03/01/2020 was compared as March 1st

  • A custom renderer registered with registerCellRenderer() or columnDefs[].renderer inherited ctx.textAlign from the cell drawn just before it. With a custom column following a right-aligned one, the coordinate in fillText(..., x + padding, ...) was read as the end of the string rather than its start, so the text was drawn on top of the left-hand column while its own cell looked empty. Every custom renderer now starts at textAlign: 'left', textBaseline: 'middle' and the body text colour. The built-in renderers set their own alignment, so nothing changes for them

  • A date value sent as ISO was flagged invalid in a column whose pattern is not ISO. The cell text, clipboard, CSV and Excel all read ISO, but validation asked for the column’s own pattern, so a paste or a setCellValue() of 2024-07-04 into an MM/DD/YYYY column showed the right date in red. A value that reads through the column’s pattern or as ISO now passes; only a value that is neither is flagged

  • The fill handle had no date series in a date column whose pattern is not ISO. It recognised dates only as ISO text, so an en (MM/DD/YYYY) or ja/zh (YYYY/MM/DD) column just repeated the source values. A date series is now read and written in the column’s own pattern (03/01/2020, 03/02/2020 continues with 03/03/2020), with the step, month ends and leap days computed as before

  • A date column of an opts.data grid sorted as text. The leading field of MM/DD/YYYY is the month, so 12/31/2019 came after 03/01/2020. A date column is now read through its pattern and sorted chronologically; a value the pattern cannot read still compares as text

  • Opening a date editor in such a column and pressing Enter recorded an edit. The editor opens an ISO value in the column’s pattern (2024-03-05 as 03/05/2024) and the commit compared the two texts character by character. Two texts standing for the same date now count as unchanged and only close the editor

  • A format: 'locale' column holding a value the native date input cannot take lost it on opening the editor: the browser blanks such a value and that blank was committed. A blank the user did not type no longer commits

  • Reopening a multiselect and closing it without picking anything could record an edit: a stored 'A, B' was rewritten as 'A,B', so spacing or option order alone read as a change. An unchanged selection now gives the stored text back

  • A date column with ss in its format opened an ISO value without the seconds, and that value then failed its own pattern check

  • args.text() could draw outside its cell. The ellipsis measuring only cuts horizontally, so a single glyph bigger than the cell had nothing to cut and reached into the neighbouring columns and rows. It is now clipped to the cell
  • Opening an editor and committing without changing the value (F2 then Enter, re-picking the same dropdown option, opening a date cell and pressing Enter) marked the cell as edited, added it to getEdits() / getChanges() and fired onCellChange. It also pushed an undo step, so an edit that changed nothing had to be undone. A commit whose value equals the cell’s current value now just closes the editor. This covers the built-in editors (text, multiline text, date, dropdown, multiselect, rich text) and custom editors passed through columnDefs[].editor, since both go through the same commit path. Checkbox toggles, paste, the fill handle and setCellValue() still record whatever value they are given

This site uses Just the Docs, a documentation theme for Jekyll.