Goal
Using Ionic/React 7.0.0 - React 18.2.0
In my IonDatetime component, I want to style calendar day buttons based on
- Input data : (1) available session during a day → Display a green calendar day (2) busy day → red.
- User interaction : available or busy date is clicked, I’d like to pick the color of my choice and prevent base color to apply.
What I tried
- When a calendar day is clicked, I’m setting the date in a state.
- I have a useEffect (with the given state as a dependancy) which is setting the relevant array for my
highlightedDates
props in IonDatetime.
See code
/** style.css **/
.booking-calendar {
--background: unset;
}
/** AdminBooking.tsx **/
interface HighlightedDate {
date: string;
textColor: string;
backgroundColor?: string;
}
const AdminBooking: React.FC<AdminBookingProps> = ({}) => {
const [activeDate, setActiveDate] = useState<string | null>(null);
const [highlightedDates, setHighlightedDates] = useState<HighlightedDate[]>();
const dates = [
{
startDate: "2024-08-02",
sessions : [
{
sessionId: 1,
status: "opened",
name: "Séance route",
program: "Virage, maîtrise frein avant",
supervisor: {
firstName: "Dan"
}
}
],
},
{
startDate: "2024-08-03",
sessions : [
{
sessionId: 2,
status: "full",
name: "Séance route",
program: "Virage, maîtrise frein avant",
supervisor: {
firstName: "Dan"
}
},
{
sessionId: 2,
status: "full",
name: "Séance route",
program: "Virage, maîtrise frein avant",
supervisor: {
firstName: "Dan"
}
}
],
},
{
startDate: "2024-08-04",
sessions : [
{
sessionId: 3,
status: "full",
name: "Séance route",
program: "Virage, maîtrise frein avant",
supervisor: {
firstName: "Dan"
}
},
{
sessionId: 4,
status: "opened",
name: "Séance route",
program: "Virage, maîtrise frein avant",
supervisor: {
firstName: "Dan"
}
}
],
},
]
function handleDateClick(e: any) {
setActiveDate(e.detail.value);
}
useEffect(() => {
const styledDates = dates.map((date) => {
const hasOpenedSession = date.sessions.find((session) => session.status === "opened");
const hasFocus = date.startDate === activeDate?.slice(0, 10);
if (hasFocus) {
return {
date: date.startDate,
textColor:'#fff',
backgroundColor: hasOpenedSession ? '#457d78' : '#c3645f',
}
} else {
return {
date: date.startDate,
textColor: hasOpenedSession ? '#457d78' : '#c3645f',
backgroundColor: '#fff',
}
}
})
console.log({styledDates})
setHighlightedDates(styledDates)
}, [activeDate])
return (
<>
<h2>Calendrier</h2>
<Spacer units={10} />
<IonDatetime
className="booking-calendar"
firstDayOfWeek={1}
id="datetime"
presentation="date"
min={today().toISOString().slice(0, 10)}
highlightedDates={highlightedDates}
onIonChange={(e) => handleDateClick(e)}
></IonDatetime>
</>
);
};
Logs, Screenshots
See console.log output and screen shot
Logs, First log is when August 2nd is clicked, second is when August 3rd is clicked
// First
{
"styledDates": [
{
"date": "2024-08-02",
"textColor": "#fff",
"backgroundColor": "#457d78"
},
{
"date": "2024-08-03",
"textColor": "#c3645f"
},
{
"date": "2024-08-04",
"textColor": "#457d78"
}
]
}
// Second
{
"styledDates": [
{
"date": "2024-08-02",
"textColor": "#457d78"
},
{
"date": "2024-08-03",
"textColor": "#fff",
"backgroundColor": "#c3645f"
},
{
"date": "2024-08-04",
"textColor": "#457d78"
}
]
}
Screenshot 1
Screenshot 2, August 2nd in screenshot 2 (same thing happens for the 3rd but in red)
Screenshot 3, August 4th in screenshot 2
Problem
The styles applies properly when calendar day buttons are just displayed but they don’t apply as expected when the calendar day is active (clicked)
- Programmatically the logic works well, as you can see in the logs (above)
- Using
background
orbackgroundColor
results the same - If I comment
backgroundColor: '#fff'
, calendar day button has a colored background and font from both section of theif hasFocus
applies (see screenshot 1, 2, 3) - If I keep
backgroundColor: '#fff'
, the colored background and font doesn’t apply, just the active style that I do not want (screenshot 0)
Questions
- Am I approaching the issue the wrong way ?
- Does anyone have a clue of how to change style for highlightedDates based on element state ?