Skip to content
Magma Design System
Calendar<mds-calendar>Generated from @maggioli-design-system/magma@2.3.0dist/documentation.json. Encapsulation: shadow.
Correct and idiomatic ways to use the <mds-calendar> component, ordered from most common to most specialized. Patterns assume a working knowledge of the shared component rules in agents/conventions.md.
Single-Day Picker
Set the bare single-picker attribute for a plain single-date selector. mdsCalendarChange fires once with { startDate } and no endDate. Seed an initial date via start-date.
<mds-calendar single-picker start-date="2025-06-10"></mds-calendar>
<script>
document.querySelector('mds-calendar').addEventListener('mdsCalendarChange', (e) => {
console.log('Data selezionata:', e.detail.startDate);
});
</script>
Range Picker (default mode)
Range selection is the default: omit single-picker. The first click sets the start date, the second sets the end date. A third click starts a new range from the clicked day. mdsCalendarChange fires on both clicks: after the first one endDate is absent. Preload a range by supplying both start-date and end-date.
<mds-calendar start-date="2025-09-01" end-date="2025-09-15"></mds-calendar>
<script>
document.querySelector('mds-calendar').addEventListener('mdsCalendarChange', (e) => {
const { startDate, endDate } = e.detail;
console.log('Intervallo selezionato:', startDate, '-', endDate);
});
</script>
Restricting the Selectable Window with min / max
Pass ISO 8601 strings to min and max to mark out-of-range days as disabled. Days outside the window are not hidden - they remain visible but cannot be clicked.
<mds-calendar
single-picker
min="2025-01-01"
max="2025-12-31"
></mds-calendar>
Navigating to a Specific Month Programmatically
Use the updateCurrentDate method to jump the visible month without changing the current selection. Pass any ISO date string that falls within the target month.
<mds-calendar id="cal" single-picker></mds-calendar>
<script>
document.querySelector('#cal').updateCurrentDate('2026-03-01');
</script>
Quick-Pick Preselection Shortcuts
The preselection named slot hosts your own shortcuts, for example mds-button elements whose click sets start-date / end-date (mds-input-date-range-preselection works only inside mds-input-date-range). The slot panel becomes visible only if, when the calendar loads, the host contains an element with the class date-preselection--has-preselection; set hide-preselection to keep it collapsed. mdsCalendarPreselect fires after each completed range selection so the shortcuts can re-evaluate their active state.
<mds-calendar start-date="2025-09-01" end-date="2025-09-07">
<div slot="preselection" class="date-preselection--has-preselection">
<mds-button variant="dark" tone="text" label="Ultimi 7 giorni"></mds-button>
<mds-button variant="dark" tone="text" label="Ultimi 30 giorni"></mds-button>
</div>
</mds-calendar>
Paired Calendars Without Duplicate Navigation
Two calendars shown side by side (the pattern used by mds-input-date-range on wide viewports) should expose one previous and one next button in total: hide the inner buttons with hide-previous-button / hide-next-button and lock the header on the day grid with disable-month-year-selection, then keep the two view-date values one month apart from the mdsCalendarNavigate event.
<mds-calendar id="start" view-date="2025-09-01" hide-next-button disable-month-year-selection></mds-calendar>
<mds-calendar id="end" view-date="2025-10-01" hide-previous-button disable-month-year-selection></mds-calendar>
Listening for Selection Changes
Listen on the documented mdsCalendarChange event - not the native change event - so the handler receives the structured { startDate, endDate? } detail object directly from the Shadow DOM.
<mds-calendar id="picker" single-picker></mds-calendar>
<script>
document.querySelector('#picker').addEventListener('mdsCalendarChange', (e) => {
const { startDate } = e.detail;
document.querySelector('#output').textContent = 'Scadenza: ' + startDate;
});
</script>
Embedded inside mds-input-date or mds-input-date-range
<mds-calendar> is the visual engine used internally by mds-input-date and mds-input-date-range. In most product surfaces, reach for those higher-level components. Use <mds-calendar> directly only when you need a standalone always-visible date grid without an associated text input.
<!-- Higher-level: input with calendar overlay -->
<mds-input-field label="Scadenza">
<mds-input-date name="scadenza"></mds-input-date>
</mds-input-field>
<!-- Lower-level: always-visible standalone grid -->
<mds-calendar single-picker></mds-calendar>
Styling Customization via CSS Custom Properties
Adjust the calendar appearance only through the documented --mds-calendar-* CSS custom properties. Set them on the host element or a parent selector; use the semantic color roles so dark mode, named themes and high contrast keep working.
.booking-widget mds-calendar {
--mds-calendar-background: rgb(var(--magma-surface-muted));
--mds-calendar-border-radius: var(--magma-radius-xl);
--mds-calendar-padding: calc(var(--spacing) * 500);
--mds-calendar-cell-gap: calc(var(--spacing) * 100);
--mds-calendar-cell-other-month-visibility: hidden;
}