Troubleshooting
Common issues and solutions when using <lms-calendar>.
Nothing Renders
Symptoms: The page is blank where the calendar should be, or you see just a thin line.
Causes & fixes:
-
Missing peer dependencies —
litandluxonmust be installed alongside@jpahd/kalendus. Duplicate copies can breakinstanceofchecks.npm install @jpahd/kalendus lit luxonVerify a single copy:
npm ls lit luxon -
Module not imported — The component must be imported once for its custom element to register.
import '@jpahd/kalendus'; -
Zero container height — The calendar defaults to
--height: 100%. If its parent has no explicit height, the calendar collapses to zero. See Layout Guide.
Calendar Has Zero Height
The most common issue. The component's :host block sets --height: 100% and --width: 100%. Without an ancestor providing height, it collapses.
Fix: Give the parent an explicit height:
<div style="height: 600px;">
<lms-calendar></lms-calendar>
</div>
Or set the height directly:
lms-calendar {
--height: 80vh;
}
Entries Not Showing
Symptoms: Calendar renders, navigates correctly, but no events appear.
Causes & fixes:
-
Array mutation without reassignment — Lit requires a new array reference to detect changes.
// ❌ Won't trigger update calendar.entries.push(newEntry); // ✅ Triggers update calendar.entries = [...calendar.entries, newEntry]; -
Invalid date/time ranges — Entries where
endis beforestartare silently dropped during validation.// ❌ Dropped: end date before start { date: { start: { day: 15, month: 3, year: 2026 }, end: { day: 10, month: 3, year: 2026 } } } -
Wrong date format — Months are 1-indexed (1–12), not 0-indexed. Days are 1-indexed (1–31).
// ❌ Month 0 is invalid { day: 15, month: 0, year: 2026 } // ✅ January is month 1 { day: 15, month: 1, year: 2026 } -
Entries are on a different month/day — Navigate to the correct date or set
activeDateto match.
Locale Not Updating
Symptoms: Calendar stays in English despite setting locale.
Causes & fixes:
-
Using attribute instead of property — For dynamic locale changes, use property binding:
calendar.locale = 'de'; // ✅ Property assignmentIn Lit templates:
.locale=${'de'}(notlocale="de"— though the attribute works for static values). -
Unsupported locale code — Only these 28 codes are supported:
en,ar,bn,cs,da,de,de-DE,el,es,fi,fr,he,hi,id,it,ja,ko,nb,nl,pl,pt,ru,sv,th,tr,uk,vi,zh-Hans. -
<html lang>mismatch — Iflocaleis not set, the component readsdocument.documentElement.lang. Ensure this matches your desired locale.
Note: The calendar hides its UI chrome (
visibility: hidden) while loading a non-English locale chunk. If you need to know when translations are ready, listen for thelocale-readyevent or awaitcalendar.localeReady. See the Events Reference for details.
Menu Stuck Open
Symptoms: The detail menu overlay doesn't close, or closes but re-opens immediately.
Causes & fixes:
-
Event listener swallowing
menu-close— If you listen onmenu-closeand callstopPropagation(), the internal close handler won't fire. -
Custom menu replacement — If you intercept
open-menuto show a custom panel, callclearSelection()on the triggering<lms-calendar-entry>to reset ARIA state:calendar.addEventListener('open-menu', (e) => { e.stopPropagation(); // After showing your custom UI: const entry = e.composedPath().find((el) => el.tagName === 'LMS-CALENDAR-ENTRY'); entry?.clearSelection(); });
Week View Shows Wrong Number of Columns
Symptoms: Week view shows 3 days instead of 7, or vice versa.
Cause: The condensed week mode is controlled by CSS tokens read at runtime:
lms-calendar {
--week-day-count: 7; /* full-width columns */
--week-mobile-day-count: 3; /* columns below breakpoint */
--week-mobile-breakpoint: 768px;
}
If the calendar's container is narrower than --week-mobile-breakpoint, it switches to --week-mobile-day-count columns automatically.
Fixes:
- To always show 7 days:
--week-mobile-day-count: 7; - To change the threshold:
--week-mobile-breakpoint: 480px; - Widen the container if the calendar is in a narrow sidebar
Year View Not Responsive
Symptoms: Year view shows all 12 months in 3 columns regardless of screen size.
Cause: The year view uses container queries with these tokens:
lms-calendar {
--year-grid-columns: 3;
--year-grid-columns-tablet: 2;
--year-grid-columns-mobile: 1;
}
If the container doesn't support container queries (very old browsers), the grid falls back to the desktop value.
Fix: Ensure your browser supports CSS container queries, or override with a fixed column count.
Events Not Firing
Symptoms: addEventListener callbacks never execute.
Causes & fixes:
-
Listening on wrong element — All events bubble and are composed, so listen on the
<lms-calendar>host:// ✅ Correct document.querySelector('lms-calendar').addEventListener('switchview', handler); // ❌ Won't work: events don't propagate past the component boundary unless composed document.addEventListener('switchview', handler); // works, but may be unintentional -
Framework event binding syntax — In React, use
ref+addEventListenersince React's synthetic events don't support custom elements. In Vue, use@switchview.nativeorrefapproach. -
Calling
stopPropagationelsewhere — Another listener earlier in the chain may be stopping propagation.
Month View Shows Dots Instead of Full Entries
Symptoms: Month view renders small colored dots instead of entry chips with text.
Cause: This is expected responsive behavior. When the calendar's container width is below 768px, month view switches to dot mode for readability.
Fixes:
- Widen the container
- This behavior is based on
ResizeObservermeasuring the actual container width, not the viewport — so a calendar in a narrow sidebar will show dots even on a wide screen
Native Dependency Build Fails on macOS (Node 25+)
Symptoms: bun install or npm install fails with fatal error: 'climits' file not found when building better-sqlite3 or other native addons.
Cause: Node 25.x's node-gyp does not pass the correct macOS SDK include path to the compiler.
Fix: Set CXXFLAGS before installing:
CXXFLAGS="-isysroot $(xcrun --show-sdk-path)" bun install
Or add it to your shell profile (~/.zshrc):
export CXXFLAGS="-isysroot $(xcrun --show-sdk-path)"
If Xcode Command Line Tools are not installed:
xcode-select --install
display: none Breaks Layout
Symptoms: After toggling visibility, the calendar renders at wrong dimensions.
Cause: ResizeObserver cannot measure an element with display: none. When you show the element again, stale dimensions are used.
Fixes:
- Use
visibility: hidden; height: 0; overflow: hidden;instead ofdisplay: none - Reassign
calendar.entries = [...calendar.entries]after making it visible to force re-render - Alternatively, destroy and recreate the element