Take gridstack to 13, and handle the grid it may not return

gridstack 13 changed `GridStack.init` to return `GridStack | null` where
11 always handed one back. The dashboard held the result in a
`GridStack | undefined` and called `.on('change')` on it straight after,
so svelte-check stopped on two errors: null is not undefined, and the
value is possibly neither.

Coalesced to undefined so the declared type stays as it was, then
guarded before the listener is attached. `gridEl` is already checked at
the top of the function, so a null here should not occur -- but the type
allows it, and a dashboard that quietly stops persisting drags beats one
that throws inside an effect.

Nothing else in the repository touches gridstack: one import of
`GridStack` and its stylesheet, in this file.

Worth noting `vite build` passes either way. Only `npm run check` sees
this, and no CI job runs it -- the two majors would have gone in
looking clean.
This commit is contained in:
2026-09-10 09:59:14 -07:00
parent be6614182f
commit efc8886bd8
+6 -1
View File
@@ -167,7 +167,12 @@
function setupGrid() { function setupGrid() {
if (!gridEl || !dashboard?.panels) return; if (!gridEl || !dashboard?.panels) return;
grid?.destroy(false); grid?.destroy(false);
grid = GridStack.init({ float: true, cellHeight: 60, column: 12 }, gridEl); // gridstack 13 returns null when it cannot bind to the element, where
// 11 always handed back a grid. `gridEl` is guarded above so this
// should not happen -- but the type says it can, and a missed drag is
// better than a thrown error inside an effect.
grid = GridStack.init({ float: true, cellHeight: 60, column: 12 }, gridEl) ?? undefined;
if (!grid) return;
grid.on('change', (_event: Event, items: GridStackNode[]) => { grid.on('change', (_event: Event, items: GridStackNode[]) => {
for (const item of items) { for (const item of items) {
const panel = dashboard?.panels?.find((p) => p.id === item.id); const panel = dashboard?.panels?.find((p) => p.id === item.id);