[v7] TimeGrid loses its time axis and row heights when `slotMinTime` is moved later via `setOption` on a mounted view

Author: david-mcgurrinCreated Sep 10, 2026Updated Sep 12, 2026

Reduced Test Case

https://codepen.io/editor/david-mcgurrin/pen/01a08bd0-4288-734d-8936-adf7a21bb3e2

Do you understand that if a reduced test case is not provided, we will intentionally delay triaging of your ticket?

  • I understand

Which connector are you using (React/Angular/etc)?

No connector (vanilla JS)

Bug Description

Moving slotMinTime later on an already-rendered TimeGrid (plain timeGridDay or resourceTimeGridDay) drops every slot row to its natural height, ignoring slotMinHeight, and the time axis loses all of its labels and collapses to zero width. With the classic theme in the pen the rows go from 40px to about 17px with no axis; with a flatter theme (our production app) they go to about 5px, the whole grid is squashed into a strip under the resource headers and the body looks blank.

It only happens when the new slotMinTime is later and sits at a different offset within the label interval, so the set of labelled slats changes. From a rendered 05:45 start with 15-minute slots (labels every 30 minutes, on :15 and :45):

setOption("slotMinTime", …) Direction Label phase Result
06:45, 07:45 later unchanged (:45) fine
06:00, 07:00, 08:00 later shifts to :00 rows collapse
05:15 earlier unchanged fine
05:00, 04:30 earlier shifts fine
05:45 same same fine

Moving slotMaxTime in either direction is always fine.

It also needs unlabelled (minor) slats to exist: with slotDuration: "00:15" and the default 30-minute label interval it reproduces every time; with slotDuration: "00:30", where every slat carries a label, the same slotMinTime changes render correctly.

The broken state is sticky. None of the following recover it:

  • calendar.render()
  • dispatching a resize event on window
  • setOption on slotDuration, slotLabelInterval, slotMinHeight, height or expandRows
  • changeView to the same view type
  • batchRendering around a change to another view and back

Only a real remount recovers it: changeView to a different view and back (two separate calls), or destroy() followed by render().

What appears to happen internally

I instrumented computeSlatHeight and handleSlatInnerHeights in the TimeGrid layout to log their inputs.

Healthy render, then setOption("slotMinTime", "08:00"):

computeSlatHeight  { expandRows: false, slatCnt: 65, explicitSlatMinHeight: 40, slatInnerHeight: 12.578, scrollerHeight: 854 }
computeSlatHeight  { expandRows: false, slatCnt: 56, explicitSlatMinHeight: 40, slatInnerHeight: 12.578, scrollerHeight: 854 }
handleSlatInnerHeights { size: 14, max: 12.578, vals: [12.578, 12.578, 12.578, 12.578] }
handleSlatInnerHeights { size: 14, max: 0,      vals: [0, 0, 0, 0] }              <-- labels re-reported as 0
computeSlatHeight  { expandRows: false, slatCnt: 56, explicitSlatMinHeight: 40, slatInnerHeight: 0, scrollerHeight: 854 }

Once slatInnerHeight is 0, computeSlatHeight returns [null, false] (the !slatInnerHeight early return), so no explicit height is written to the slat header cells or lanes and they collapse. In the collapsed DOM the axis scroller is 0px wide, the slat header cells are 14px x 0px with an empty style attribute, and the label inner elements never report a non-zero height again, so the state never self-corrects.

The same sequence with setOption("slotMaxTime", "18:00") keeps slatInnerHeight at 12.578 and renders correctly, so it is specifically the removal of leading slatMetas that leaves the label height map full of zeros.

Expected behaviour

Changing slotMinTime at runtime re-renders the grid with the new range and the same row heights, as changing slotMaxTime does.

Actual behaviour

The axis empties and every row loses its height; the grid is unusable until the view is remounted.

Environment

  • fullcalendar / fullcalendar-scheduler 7.0.0 (reproduced on 7.1.0 as well)
  • Chrome 152 on macOS 15.6, also seen in production by end users
  • Options in use: resourceTimeGridDay, slotDuration: "00:15", slotMinHeight: 40, allDaySlot: false, dayMinWidth: 200, expandRows: false

Real-world trigger

A venue booking calendar derives slotMinTime / slotMaxTime from the opening hours of the day being viewed and applies them with setOption after the resources for that day load. Any day that opens later than the day previously viewed (a holiday schedule, for example) moves slotMinTime later and blanks the calendar. Our current workaround is to never move slotMinTime later on a mounted view.

Source: fullcalendar/fullcalendar