Custom Day Cells
Usage
theme: 'ios' You can turn auto theming on and let it decide based on the platform.
Usage
themeVariant: 'light' You can turn auto dark mode on based on system settings.
Usage
touchUi: true
// touch interaction is enabled Use touch interaction on mobile or pointer interaction on desktop.
Usage
locale: localeEn Selecting the locale loads the localized settings and the translated UI text.
Custom Day Cells
Add custom content to the day cells of the calendar. This can be dynamic content based on the date like an activity tracker that uses daily move data from an array of records.
Use the dayContentTemplate option for passing a custom template that will be used when the day cells are being rendered.
Demo
Code
import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import { MbscModule, setOptions } from '@mobiscroll/angular';
setOptions({
locale: ,
theme: ' ',
themeVariant: ' '
});
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
standalone: true,
imports: [CommonModule, MbscModule],
})
export class AppComponent {
activities = [
{
date: '2026-10-18T00:00',
move: 200,
exercise: 360,
stand: 180,
},
{
date: '2026-10-19T00:00',
move: 360,
exercise: 150,
stand: 230,
},
{
date: '2026-10-20T00:00',
move: 180,
exercise: 200,
stand: 280,
},
{
date: '2026-10-21T00:00',
move: 120,
exercise: 150,
stand: 200,
},
{
date: '2026-10-22T00:00',
move: 320,
exercise: 180,
stand: 100,
},
{
date: '2026-10-23T00:00',
move: 120,
exercise: 100,
stand: 200,
},
{
date: '2026-10-24T00:00',
move: 230,
exercise: 170,
stand: 330,
},
{
date: '2026-10-25T00:00',
move: 320,
exercise: 260,
stand: 80,
},
{
date: '2026-10-26T00:00',
move: 200,
exercise: 140,
stand: 180,
},
{
date: '2026-10-27T00:00',
move: 360,
exercise: 300,
stand: 160,
},
{
date: '2026-10-28T00:00',
move: 80,
exercise: 360,
stand: 360,
},
{
date: '2026-10-29T00:00',
move: 220,
exercise: 170,
stand: 290,
},
{
date: '2026-10-30T00:00',
move: 120,
exercise: 40,
stand: 100,
},
{
date: '2026-10-31T00:00',
move: 120,
exercise: 200,
stand: 80,
},
];
getDeg(nr: number) {
return {
rotate1: nr > 180 ? 180 : nr,
rotate2: nr > 180 ? nr - 180 : 0,
};
}
getTransform(rotate: number) {
return 'rotateZ(' + rotate + 'deg)';
}
getActivity(day: any) {
return this.activities.find((obj) => +new Date(obj.date) === +day.date);
}
}
<mbsc-datepicker [controls]="['calendar']" display="inline" [touchUi]="true" [dayContentTemplate]="dayTemp"> </mbsc-datepicker>
<ng-template #dayTemp let-day>
<div class="screen">
<div [ngClass]="{'dial move ': getActivity(day)}">
<div class="dial-background" [ngStyle]="{background: getActivity(day) ? '#752a2a' : ''}"></div>
<div class="dial-container container1">
<div class="wedge" [ngStyle]="{transform: getActivity(day) ? getTransform(getDeg(getActivity(day)!.move).rotate1) : ''}"></div>
</div>
<div class="dial-container container2">
<div class="wedge" [ngStyle]="{transform: getActivity(day) ? getTransform(getDeg(getActivity(day)!.move).rotate2) : ''}"></div>
</div>
<div class="marker start"></div>
<div class="marker end" [ngStyle]="{transform: getActivity(day) ? getTransform(getActivity(day)!.move) : ''}"></div>
</div>
<div [ngClass]="{'dial exercise ': getActivity(day)}">
<div class="dial-background" [ngStyle]="{background: getActivity(day) ? '#4a6915' : ''}"></div>
<div class="dial-container container1">
<div class="wedge" [ngStyle]="{transform: getActivity(day) ? getTransform(getDeg(getActivity(day)!.exercise).rotate1) : ''}"></div>
</div>
<div class="dial-container container2">
<div class="wedge" [ngStyle]="{transform: getActivity(day) ? getTransform(getDeg(getActivity(day)!.exercise).rotate2) : ''}"></div>
</div>
<div class="marker start"></div>
<div class="marker end" [ngStyle]="{transform: getActivity(day) ? getTransform(getActivity(day)!.exercise) : ''}"></div>
</div>
<div [ngClass]="{'dial stand ': getActivity(day)}">
<div class="dial-background" [ngStyle]="{background: getActivity(day) ? '#157b76' : ''}"></div>
<div class="dial-container container1">
<div class="wedge" [ngStyle]="{transform: getActivity(day) ? getTransform(getDeg(getActivity(day)!.stand).rotate1) : ''}"></div>
</div>
<div class="dial-container container2">
<div class="wedge" [ngStyle]="{transform: getActivity(day) ? getTransform(getDeg(getActivity(day)!.stand).rotate2) : ''}"></div>
</div>
<div class="marker start"></div>
<div class="marker end" [ngStyle]="{transform: getActivity(day) ? getTransform(getActivity(day)!.stand) : ''}"></div>
</div>
</div>
</ng-template>
.screen {
position: relative;
width: 2em;
height: 2em;
margin: 5px auto 10px auto;
}
.screen * {
box-sizing: content-box;
}
.screen .dials {
width: 1em;
height: 1em;
border-radius: 50%;
position: absolute;
top: 0.875em;
left: 0;
}
.screen .dial {
border: 1px solid #000;
border-radius: 50%;
}
/**** DIAL 1 ****/
.dial.move {
position: absolute;
width: 2em;
height: 2em;
}
.dial.move::before {
content: '';
width: 0.75em;
height: 0.75em;
position: absolute;
top: -0.29em;
left: calc(50% - 0.1875em);
z-index: 10;
}
.dial.move::after {
content: '';
background: #000;
border-radius: 50%;
width: 1.5em;
height: 1.5em;
position: absolute;
top: 0.25em;
left: 0.25em;
}
.dial.move .dial-container {
position: absolute;
top: 0;
bottom: 0;
width: 1em;
overflow: hidden;
}
.dial.move .wedge {
width: 1em;
height: 2em;
position: absolute;
top: 0;
left: 0;
}
.dial.move .container1 {
left: 1em;
}
.dial.move .container1 .wedge {
border-radius: 2em 0 0 2em;
background: #fc1d20;
left: -1em;
transform-origin: 100% 50%;
}
.dial.move .container2 {
left: 0;
}
.dial.move .container2 .wedge {
background: #fc1d20;
border-radius: 0 2em 2em 0;
transform-origin: 0 50%;
left: 1em;
}
.dial.move .marker {
width: 0.25em;
height: 0.25em;
background: #fc1d20;
border-radius: 50%;
position: absolute;
top: 0;
left: calc(50% - 0.125em);
}
.dial.move .end {
transform-origin: 50% 1em;
}
/**** DIAL 2 ****/
.dial.exercise {
position: absolute;
width: 1.5em;
height: 1.5em;
top: 0.25em;
left: 0.25em;
}
.dial.exercise::before {
content: '';
width: 0.75em;
height: 0.75em;
position: absolute;
top: -0.29em;
left: calc(50% - 0.1875em);
z-index: 10;
}
.dial.exercise::after {
content: '';
background: #000;
border-radius: 50%;
width: 1em;
height: 1em;
position: absolute;
top: 0.25em;
left: 0.25em;
}
.dial.exercise .dial-container {
position: absolute;
top: 0;
bottom: 0;
width: 0.75em;
overflow: hidden;
}
.dial.exercise .wedge {
border-radius: 50%;
width: 0.75em;
height: 1.5em;
position: absolute;
}
.dial.exercise .container1 {
left: 0.75em;
}
.dial.exercise .container1 .wedge {
border-radius: 2em 0 0 2em;
position: absolute;
background: #9cfc33;
left: -0.75em;
transform-origin: 100% 50%;
}
.dial.exercise .container2 {
left: 0;
}
.dial.exercise .container2 .wedge {
background: #9cfc33;
border-radius: 0 2em 2em 0;
transform-origin: 0 50%;
left: 0.75em;
}
.dial.exercise .marker {
width: 0.25em;
height: 0.25em;
background: #9cfc33;
border-radius: 50%;
position: absolute;
top: 0;
left: calc(50% - 0.125em);
}
.dial.exercise .end {
transform-origin: 45% 0.75em;
}
/**** DIAL 3 ****/
.dial.stand {
position: absolute;
width: 1em;
height: 1em;
top: 0.5em;
left: 0.5em;
}
.dial.stand::before {
content: '';
width: 0.75em;
height: 0.75em;
position: absolute;
top: -0.24em;
left: calc(50% - 0.1875em);
z-index: 10;
}
.dial.stand::after {
content: '';
background: #000;
border-radius: 50%;
width: 0.5em;
height: 0.5em;
position: absolute;
top: 0.25em;
left: 0.25em;
}
.dial.stand .dial-container {
position: absolute;
top: 0;
bottom: 0;
width: 1em;
overflow: hidden;
}
.dial.stand .wedge {
border-radius: 50%;
width: 0.5em;
height: 1em;
position: absolute;
}
.dial.stand .container1 {
left: 0.5em;
}
.dial.stand .container1 .wedge {
position: absolute;
background: #32cbd4;
border-radius: 2em 0 0 2em;
left: -0.5em;
transform-origin: 100% 50%;
}
.dial.stand .container2 {
left: 0;
}
.dial.stand .container2 .wedge {
background: #32cbd4;
border-radius: 0 2em 2em 0;
transform-origin: 0 50%;
left: 0.5em;
}
.dial.stand .marker {
width: 0.25em;
height: 0.25em;
background: #32cbd4;
border-radius: 50%;
position: absolute;
top: 0;
left: calc(50% - 0.125em);
}
.dial.stand .end {
transform-origin: 50% 0.5em;
}
.dial-background {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
border-radius: 50%;
}