// CalendarComponent.qml (For one month) import QtQuick import qs.Common import qs.Common.Styled Item { id: root property int targetYear: new Date().getFullYear() property int targetMonth: new Date().getMonth() // 0-11 property date currentDate: new Date() function getLocalizedDayHeaders() { const locale = Qt.locale(); const headers = []; const firstDay = locale.firstDayOfWeek; for (let i = 0; i < 7; i++) { const dayIndex = (firstDay + i) % 7; const dayDate = new Date(1970, 0, 4 + dayIndex); headers.push(dayDate.toLocaleString(locale, "ddd").substring(0, 1)); } return headers; } function getMonthLayout(year, month) { let date = new Date(year, month, 1); let firstDayOfWeek = date.getDay(); let daysInMonth = new Date(year, month + 1, 0).getDate(); let days = []; for (let i = 0; i < firstDayOfWeek; i++) { days.push(""); } for (let i = 1; i <= daysInMonth; i++) { days.push(i); } while (days.length % 7 !== 0) { days.push(""); } return { monthName: date.toLocaleString(Qt.locale(), "MMMM yyyy"), days: days }; } readonly property var layoutData: getMonthLayout(targetYear, targetMonth) implicitWidth: childrenRect.width implicitHeight: childrenRect.height Column { spacing: 5 // Month Title StyledText { text: root.layoutData.monthName font.bold: true horizontalAlignment: Text.AlignHCenter width: parent.width font.family: Theme.fontFamilyMono } Grid { columns: 7 rowSpacing: 2 columnSpacing: 5 Repeater { model: root.getLocalizedDayHeaders() StyledText { text: modelData horizontalAlignment: Text.AlignHCenter width: 18 font.family: Theme.fontFamilyMono } } Repeater { model: root.layoutData.days StyledText { text: modelData horizontalAlignment: Text.AlignHCenter width: 18 font.family: Theme.fontFamilyMono color: { let isCurrentMonth = root.targetYear === root.currentDate.getFullYear() && root.targetMonth === root.currentDate.getMonth(); let isCurrentDay = isCurrentMonth && modelData === root.currentDate.getDate(); return isCurrentDay ? Theme.color5Bright : Theme.textColor; } } } } } }