├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── bug_report_v4.md │ ├── feature_request.md │ └── feature_request_v4.md ├── RELEASE-TEMPLATE.md └── workflows │ ├── close-inactive-issues.yml │ └── run-vitest.yml ├── .gitignore ├── .npmrc ├── .prettierignore ├── .prettierrc ├── LICENSE.md ├── README.md ├── eslint.config.mjs ├── netlify.toml ├── package.json ├── packages ├── app-extension │ ├── .editorconfig │ ├── .npmignore │ ├── LICENSE.md │ ├── README.md │ ├── jsconfig.json │ ├── package.json │ └── src │ │ ├── boot │ │ ├── vite-register.js │ │ └── webpack-register.js │ │ └── index.js ├── docs │ ├── .editorconfig │ ├── .gitignore │ ├── .npmrc │ ├── .prettierignore │ ├── .prettierrc.json │ ├── README.md │ ├── eslint.config.js │ ├── index.html │ ├── package.json │ ├── postcss.config.js │ ├── public │ │ ├── QCalendarAgenda.png │ │ ├── QCalendarDay.png │ │ ├── QCalendarMonth--mini-mode.png │ │ ├── QCalendarMonth.png │ │ ├── QCalendarResource.png │ │ ├── QCalendarScheduler.png │ │ ├── QCalendarTask.png │ │ ├── favicon.ico │ │ ├── icons │ │ │ ├── favicon-128x128.png │ │ │ ├── favicon-16x16.png │ │ │ ├── favicon-32x32.png │ │ │ └── favicon-96x96.png │ │ ├── q-calendar-month-view-mini-mode-with-selection.png │ │ ├── qcalendar-5day-done-incorrectly.png │ │ ├── qcalendar-agenda-view--column-options.png │ │ ├── qcalendar-agenda-view--planner-1.png │ │ ├── qcalendar-agenda-view--planner.png │ │ ├── qcalendar-agenda-view.png │ │ ├── qcalendar-custom-interval-view.png │ │ ├── qcalendar-day-view--intervals.png │ │ ├── qcalendar-day-view.png │ │ ├── qcalendar-locale-arabic.png │ │ ├── qcalendar-locale-chinese.png │ │ ├── qcalendar-locale-french.png │ │ ├── qcalendar-locale-german.png │ │ ├── qcalendar-locale-romanian.png │ │ ├── qcalendar-logo.png │ │ ├── qcalendar-month-interval-view.png │ │ ├── qcalendar-month-view--week-slot.png │ │ ├── qcalendar-month-view-5day.png │ │ ├── qcalendar-month-view-mini-mode-multi-month-selection.png │ │ ├── qcalendar-month-view-monday-first-day.png │ │ ├── qcalendar-month-view-workweek.png │ │ ├── qcalendar-month-view.png │ │ ├── qcalendar-resource-view--hierarchial.png │ │ ├── qcalendar-resource-view.png │ │ ├── qcalendar-scheduler-view--hierarchial.png │ │ ├── qcalendar-scheduler-view.png │ │ ├── qcalendar-theme-blue.png │ │ ├── qcalendar-theme-brown.png │ │ ├── qcalendar-theme-dark.png │ │ ├── qcalendar-theme-deep-purple.png │ │ ├── qcalendar-theme-indigo.png │ │ ├── qcalendar-theme-teal.png │ │ ├── qcalendar-toolbar.png │ │ ├── qcalendar-week-view-5day.png │ │ ├── qcalendar-week-view-monday-first-day.png │ │ ├── qcalendar-week-view.png │ │ ├── qcalendar-week-view2.png │ │ ├── qcalendar-workweeks.png │ │ ├── qcalendaragenda-planner.png │ │ ├── qcalendarday--column-count.png │ │ ├── qcalendarmonth-event-slots.png │ │ ├── qcalendarmonth-indigo-theme.png │ │ ├── qcalendarmonth-minimode-deep-purple-theme.png │ │ ├── qcalendarmonth-minimode-range-selection.png │ │ ├── qcalendarmonth-workweeks.png │ │ ├── qcalendarresource-children.png │ │ ├── qcalendarscheduler-brown-theme.png │ │ ├── qcalendarscheduler-children.png │ │ ├── qcalendartask-colored-weekends.png │ │ ├── qcalendartask-teal-theme.png │ │ ├── qcalendarweek-blue-theme.png │ │ ├── qcalendarweek-dark-mode.png │ │ └── theme-builder.png │ ├── quasar.config.ts │ ├── quasar.extensions.json │ ├── src │ │ ├── .q-press │ │ │ ├── api │ │ │ │ ├── components │ │ │ │ │ ├── DarkModeToggle.json │ │ │ │ │ ├── MarkdownApi.json │ │ │ │ │ ├── MarkdownApiEntry.json │ │ │ │ │ ├── MarkdownCardLink.json │ │ │ │ │ ├── MarkdownCardTitle.json │ │ │ │ │ ├── MarkdownCode.json │ │ │ │ │ ├── MarkdownCodePrism.json │ │ │ │ │ ├── MarkdownCodepen.json │ │ │ │ │ ├── MarkdownCopyButton.json │ │ │ │ │ ├── MarkdownDrawerSidebar.json │ │ │ │ │ ├── MarkdownDrawerToc.json │ │ │ │ │ ├── MarkdownExample.json │ │ │ │ │ ├── MarkdownHeader.json │ │ │ │ │ ├── MarkdownHeaderIconLinks.json │ │ │ │ │ ├── MarkdownHeaderMenu.json │ │ │ │ │ ├── MarkdownHeaderTextLinks.json │ │ │ │ │ ├── MarkdownInstallation.json │ │ │ │ │ ├── MarkdownLayout.json │ │ │ │ │ ├── MarkdownLink.json │ │ │ │ │ ├── MarkdownPage.json │ │ │ │ │ ├── MarkdownPageFooter.json │ │ │ │ │ ├── MarkdownPageSidebar.json │ │ │ │ │ ├── MarkdownPageToc.json │ │ │ │ │ ├── MarkdownPrerender.json │ │ │ │ │ └── MarkdownTree.json │ │ │ │ └── composables │ │ │ │ │ ├── dark.json │ │ │ │ │ └── scroll.json │ │ │ ├── assets │ │ │ │ └── get-meta.ts │ │ │ ├── components │ │ │ │ ├── DarkModeToggle.vue │ │ │ │ ├── MarkdownApi.vue │ │ │ │ ├── MarkdownApiEntry.ts │ │ │ │ ├── MarkdownCardLink.vue │ │ │ │ ├── MarkdownCardTitle.vue │ │ │ │ ├── MarkdownCode.vue │ │ │ │ ├── MarkdownCodePrism.ts │ │ │ │ ├── MarkdownCodepen.vue │ │ │ │ ├── MarkdownCopyButton.vue │ │ │ │ ├── MarkdownExample.vue │ │ │ │ ├── MarkdownLink.vue │ │ │ │ ├── MarkdownPrerender.ts │ │ │ │ ├── MarkdownTree.vue │ │ │ │ └── markdown-utils.ts │ │ │ ├── composables │ │ │ │ ├── dark.ts │ │ │ │ └── scroll.ts │ │ │ ├── css │ │ │ │ ├── app.scss │ │ │ │ ├── fonts.scss │ │ │ │ ├── prism-theme.scss │ │ │ │ └── themes │ │ │ │ │ ├── default.scss │ │ │ │ │ ├── mystic.scss │ │ │ │ │ ├── newspaper.scss │ │ │ │ │ ├── sunrise.scss │ │ │ │ │ └── tawny.scss │ │ │ ├── layouts │ │ │ │ ├── MarkdownDrawerSidebar.vue │ │ │ │ ├── MarkdownDrawerToc.vue │ │ │ │ ├── MarkdownHeader.vue │ │ │ │ ├── MarkdownHeaderIconLinks.vue │ │ │ │ ├── MarkdownHeaderMenu.ts │ │ │ │ ├── MarkdownHeaderTextLinks.vue │ │ │ │ ├── MarkdownLayout.vue │ │ │ │ ├── MarkdownPage.vue │ │ │ │ ├── MarkdownPageFooter.vue │ │ │ │ ├── MarkdownPageSidebar.scss │ │ │ │ ├── MarkdownPageSidebar.ts │ │ │ │ ├── MarkdownPageToc.vue │ │ │ │ └── MarkdownSearch.vue │ │ │ └── stores │ │ │ │ └── markdown.ts │ │ ├── App.vue │ │ ├── assets │ │ │ └── quasar-logo-vertical.svg │ │ ├── boot │ │ │ └── .gitkeep │ │ ├── components │ │ │ ├── LandingPage │ │ │ │ └── LandingPage.vue │ │ │ ├── NavigationBar.vue │ │ │ ├── PlannerItem.vue │ │ │ ├── ThemeBuilder │ │ │ │ ├── AgendaThemeBuilder.vue │ │ │ │ ├── DayThemeBuilder.vue │ │ │ │ ├── MiniModeThemeBuilder.vue │ │ │ │ ├── MonthThemeBuilder.vue │ │ │ │ ├── ResourceThemeBuilder.vue │ │ │ │ ├── SchedulerThemeBuilder.vue │ │ │ │ ├── TaskThemeBuilder.vue │ │ │ │ └── WeekThemeBuilder.vue │ │ │ ├── ThemeEditor.vue │ │ │ ├── ThemeImporter.vue │ │ │ └── anatomy │ │ │ │ ├── QCalendarAgendaAnatomy.vue │ │ │ │ ├── QCalendarDayAnatomy.vue │ │ │ │ ├── QCalendarMonthAnatomy.vue │ │ │ │ ├── QCalendarMonthMiniModeAnatomy.vue │ │ │ │ ├── QCalendarResourceAnatomy.vue │ │ │ │ ├── QCalendarSchedulerAnatomy.vue │ │ │ │ ├── QCalendarTaskAnatomy.vue │ │ │ │ └── QCalendarWeekAnatomy.vue │ │ ├── css │ │ │ ├── app.scss │ │ │ └── quasar.variables.scss │ │ ├── env.d.ts │ │ ├── examples │ │ │ ├── Agenda │ │ │ │ ├── AgendaAlignment.vue │ │ │ │ ├── AgendaCellWidth.vue │ │ │ │ ├── AgendaColumnCount.vue │ │ │ │ ├── AgendaColumnOptions.vue │ │ │ │ ├── AgendaDark.vue │ │ │ │ ├── AgendaDateType.vue │ │ │ │ ├── AgendaDayWeekMaxDays.vue │ │ │ │ ├── AgendaDisabledBeforeAfter.vue │ │ │ │ ├── AgendaDisabledDays.vue │ │ │ │ ├── AgendaDisabledWeekdays.vue │ │ │ │ ├── AgendaFirstDayMonday.vue │ │ │ │ ├── AgendaFiveDayWorkweek.vue │ │ │ │ ├── AgendaLocale.vue │ │ │ │ ├── AgendaNoActiveDate.vue │ │ │ │ ├── AgendaNow.vue │ │ │ │ ├── AgendaPlanner.vue │ │ │ │ ├── AgendaTheme.vue │ │ │ │ └── AgendaTransitions.vue │ │ │ ├── Day │ │ │ │ ├── Day3Day.vue │ │ │ │ ├── DayAlignment.vue │ │ │ │ ├── DayCellWidth.vue │ │ │ │ ├── DayColumnCount.vue │ │ │ │ ├── DayColumnCountPlus.vue │ │ │ │ ├── DayCustomHeader.vue │ │ │ │ ├── DayDark.vue │ │ │ │ ├── DayDateType.vue │ │ │ │ ├── DayDisabledBeforeAfter.vue │ │ │ │ ├── DayDisabledDays.vue │ │ │ │ ├── DayDisabledWeekdays.vue │ │ │ │ ├── DayDragAndDrop.vue │ │ │ │ ├── DayHour24Format.vue │ │ │ │ ├── DayIntervalCount.vue │ │ │ │ ├── DayIntervalHeight.vue │ │ │ │ ├── DayIntervalMinutes15.vue │ │ │ │ ├── DayIntervalMinutes30.vue │ │ │ │ ├── DayIntervalStart.vue │ │ │ │ ├── DayLocale.vue │ │ │ │ ├── DayMaxDays.vue │ │ │ │ ├── DayModifyIntervals.vue │ │ │ │ ├── DayMonth.vue │ │ │ │ ├── DayNavigation.vue │ │ │ │ ├── DayNoActiveDate.vue │ │ │ │ ├── DayNoHeader.vue │ │ │ │ ├── DayNoScroll.vue │ │ │ │ ├── DayNow.vue │ │ │ │ ├── DaySelectedIntervals.vue │ │ │ │ ├── DaySelection.vue │ │ │ │ ├── DaySlotColumnHeader.vue │ │ │ │ ├── DaySlotDayBody.vue │ │ │ │ ├── DaySlotDayContainerShowCurrentTime.vue │ │ │ │ ├── DaySlotHeadDay.vue │ │ │ │ ├── DaySlotHeadDayEvent.vue │ │ │ │ ├── DaySlotHeadIntervals.vue │ │ │ │ ├── DayTheme.vue │ │ │ │ └── DayTransitions.vue │ │ │ ├── Faq │ │ │ │ ├── MonthDate.vue │ │ │ │ ├── MonthMinWeeks.vue │ │ │ │ └── MonthSticky.vue │ │ │ ├── General │ │ │ │ └── CalendarAll.vue │ │ │ ├── Intervals │ │ │ │ ├── IntervalsMonthCellWidth.vue │ │ │ │ └── IntervalsMonthNavigation.vue │ │ │ ├── MiniMode │ │ │ │ ├── MiniModeBreakpoint.vue │ │ │ │ ├── MiniModeDark.vue │ │ │ │ ├── MiniModeDateType.vue │ │ │ │ ├── MiniModeDisabledBeforeAfter.vue │ │ │ │ ├── MiniModeDisabledDays.vue │ │ │ │ ├── MiniModeDisabledWeekdays.vue │ │ │ │ ├── MiniModeFirstDayMonday.vue │ │ │ │ ├── MiniModeFiveDayWorkweek.vue │ │ │ │ ├── MiniModeLocale.vue │ │ │ │ ├── MiniModeMinWeekdayLabel.vue │ │ │ │ ├── MiniModeMinWeeks.vue │ │ │ │ ├── MiniModeMultiMonthSelection.vue │ │ │ │ ├── MiniModeNavigation.vue │ │ │ │ ├── MiniModeNoActiveDate.vue │ │ │ │ ├── MiniModeNoOutsideDays.vue │ │ │ │ ├── MiniModeNow.vue │ │ │ │ ├── MiniModeQInput.vue │ │ │ │ ├── MiniModeSelectedDates.vue │ │ │ │ ├── MiniModeSelection.vue │ │ │ │ ├── MiniModeTheme.vue │ │ │ │ └── MiniModeWorkweeks.vue │ │ │ ├── Month │ │ │ │ ├── MonthAlignment.vue │ │ │ │ ├── MonthDark.vue │ │ │ │ ├── MonthDateType.vue │ │ │ │ ├── MonthDayHeight.vue │ │ │ │ ├── MonthDayOfYear.vue │ │ │ │ ├── MonthDisabledBeforeAfter.vue │ │ │ │ ├── MonthDisabledDays.vue │ │ │ │ ├── MonthDisabledWeekdays.vue │ │ │ │ ├── MonthDragAndDrop.vue │ │ │ │ ├── MonthFirstDayMonday.vue │ │ │ │ ├── MonthFiveDayWorkweek.vue │ │ │ │ ├── MonthFocusableHoverable.vue │ │ │ │ ├── MonthLabelSize.vue │ │ │ │ ├── MonthLocale.vue │ │ │ │ ├── MonthMinWeeks.vue │ │ │ │ ├── MonthNavigation.vue │ │ │ │ ├── MonthNoActiveDate.vue │ │ │ │ ├── MonthNoOutsideDays.vue │ │ │ │ ├── MonthNow.vue │ │ │ │ ├── MonthSelectedDates.vue │ │ │ │ ├── MonthSelection.vue │ │ │ │ ├── MonthSlotDay.vue │ │ │ │ ├── MonthSlotDayHolidays.vue │ │ │ │ ├── MonthSlotWeek.vue │ │ │ │ ├── MonthTheme.vue │ │ │ │ ├── MonthTransitions.vue │ │ │ │ └── MonthWorkweeks.vue │ │ │ ├── QAvatar │ │ │ │ └── BasicExample.vue │ │ │ ├── Resource │ │ │ │ ├── ResourceChildren.vue │ │ │ │ ├── ResourceCustomHeight.vue │ │ │ │ ├── ResourceDark.vue │ │ │ │ ├── ResourceFocusableHoverable.vue │ │ │ │ ├── ResourceHour24Format.vue │ │ │ │ ├── ResourceModifyIntervals.vue │ │ │ │ ├── ResourceNoSticky.vue │ │ │ │ ├── ResourceSlotHeadResources.vue │ │ │ │ ├── ResourceSlotIntervalLabel.vue │ │ │ │ ├── ResourceSlotResourceIntervals.vue │ │ │ │ ├── ResourceSlotResourceLabel.vue │ │ │ │ ├── ResourceTheme.vue │ │ │ │ └── ResourceWidthHeight.vue │ │ │ ├── Scheduler │ │ │ │ ├── SchedulerAlignment.vue │ │ │ │ ├── SchedulerCellWidth.vue │ │ │ │ ├── SchedulerChildren.vue │ │ │ │ ├── SchedulerCustomHeight.vue │ │ │ │ ├── SchedulerDark.vue │ │ │ │ ├── SchedulerDateType.vue │ │ │ │ ├── SchedulerDisabledBeforeAfter.vue │ │ │ │ ├── SchedulerDisabledDays.vue │ │ │ │ ├── SchedulerDisabledWeekdays.vue │ │ │ │ ├── SchedulerDragAndDrop.vue │ │ │ │ ├── SchedulerFirstDayMonday.vue │ │ │ │ ├── SchedulerFiveDayWorkweek.vue │ │ │ │ ├── SchedulerFocusableHoverable.vue │ │ │ │ ├── SchedulerLocale.vue │ │ │ │ ├── SchedulerNoActiveDate.vue │ │ │ │ ├── SchedulerNow.vue │ │ │ │ ├── SchedulerSlotHeadResources.vue │ │ │ │ ├── SchedulerSlotResourceDays.vue │ │ │ │ ├── SchedulerSlotResourceLabel.vue │ │ │ │ ├── SchedulerTheme.vue │ │ │ │ └── SchedulerWidthHeight.vue │ │ │ ├── Task │ │ │ │ ├── TaskAlignment.vue │ │ │ │ ├── TaskChildren.vue │ │ │ │ ├── TaskColoredWeekends.vue │ │ │ │ ├── TaskCustomHeight.vue │ │ │ │ ├── TaskDark.vue │ │ │ │ ├── TaskDateType.vue │ │ │ │ ├── TaskDisabledBeforeAfter.vue │ │ │ │ ├── TaskDisabledDays.vue │ │ │ │ ├── TaskDisabledWeekdays.vue │ │ │ │ ├── TaskFocusableHoverable.vue │ │ │ │ ├── TaskLocale.vue │ │ │ │ ├── TaskMonth.vue │ │ │ │ ├── TaskMultipleFooterRows.vue │ │ │ │ ├── TaskNoActiveDate.vue │ │ │ │ ├── TaskNoWeekends.vue │ │ │ │ ├── TaskNow.vue │ │ │ │ ├── TaskTheme.vue │ │ │ │ ├── TaskTitleRows.vue │ │ │ │ └── TaskWeek.vue │ │ │ ├── Week │ │ │ │ ├── Week24Hour.vue │ │ │ │ ├── WeekAlignment.vue │ │ │ │ ├── WeekCellWidth.vue │ │ │ │ ├── WeekDark.vue │ │ │ │ ├── WeekDateType.vue │ │ │ │ ├── WeekDisabledBeforeAfter.vue │ │ │ │ ├── WeekDisabledDays.vue │ │ │ │ ├── WeekDisabledWeekdays.vue │ │ │ │ ├── WeekDragAndDrop.vue │ │ │ │ ├── WeekFirstDayMonday.vue │ │ │ │ ├── WeekFiveDayWorkweek.vue │ │ │ │ ├── WeekFocusableHoverable.vue │ │ │ │ ├── WeekIntervalCount.vue │ │ │ │ ├── WeekIntervalHeight.vue │ │ │ │ ├── WeekIntervalMinutes15.vue │ │ │ │ ├── WeekIntervalMinutes30.vue │ │ │ │ ├── WeekIntervalStart.vue │ │ │ │ ├── WeekLocale.vue │ │ │ │ ├── WeekModifyIntervals.vue │ │ │ │ ├── WeekNavigation.vue │ │ │ │ ├── WeekNoActiveDate.vue │ │ │ │ ├── WeekNoHeader.vue │ │ │ │ ├── WeekNoScroll.vue │ │ │ │ ├── WeekNow.vue │ │ │ │ ├── WeekSelectedIntervals.vue │ │ │ │ ├── WeekSelection.vue │ │ │ │ ├── WeekSlotColumnHeader.vue │ │ │ │ ├── WeekSlotDayBody.vue │ │ │ │ ├── WeekSlotDayContainerShowCurrentTime.vue │ │ │ │ ├── WeekSlotDayInterval.vue │ │ │ │ ├── WeekSlotHeadDay.vue │ │ │ │ ├── WeekSlotHeadDayEvent.vue │ │ │ │ ├── WeekSlotHeadDaysEventAbsolute.vue │ │ │ │ ├── WeekSlotHeadIntervals.vue │ │ │ │ ├── WeekTheme.vue │ │ │ │ └── WeekTransitions.vue │ │ │ └── listing.ts │ │ ├── layouts │ │ │ └── ThemeBuilder.vue │ │ ├── markdown │ │ │ ├── _elements.md │ │ │ ├── _elements2.md │ │ │ ├── developing │ │ │ │ ├── faq.md │ │ │ │ ├── qcalendar-agenda.md │ │ │ │ ├── qcalendar-day-intervals.md │ │ │ │ ├── qcalendar-day-week.md │ │ │ │ ├── qcalendar-day.md │ │ │ │ ├── qcalendar-month-mini-mode.md │ │ │ │ ├── qcalendar-month.md │ │ │ │ ├── qcalendar-resource.md │ │ │ │ ├── qcalendar-scheduler.md │ │ │ │ ├── qcalendar-task.md │ │ │ │ ├── qcalendar.md │ │ │ │ └── timestamp.md │ │ │ ├── getting-started │ │ │ │ ├── anatomy-of-a-calendar.md │ │ │ │ ├── installation.md │ │ │ │ ├── introduction.md │ │ │ │ ├── quick-start.md │ │ │ │ ├── themes.md │ │ │ │ └── transitions.md │ │ │ ├── guides │ │ │ │ ├── contributing.md │ │ │ │ ├── faq.md │ │ │ │ ├── release-notes.md │ │ │ │ └── style-guide.md │ │ │ ├── landing-page.md │ │ │ ├── listing.ts │ │ │ ├── other │ │ │ │ ├── contact.md │ │ │ │ ├── contributing │ │ │ │ │ ├── bugs-and-feature-requests.md │ │ │ │ │ ├── call-to-action.md │ │ │ │ │ ├── components.md │ │ │ │ │ ├── documentation.md │ │ │ │ │ ├── overview.md │ │ │ │ │ └── sponsor.md │ │ │ │ ├── migration-guide.md │ │ │ │ └── release-notes.md │ │ │ └── privacy-policy.md │ │ ├── pages │ │ │ └── ErrorNotFound.vue │ │ ├── q-press.globals.d.ts │ │ ├── router │ │ │ ├── index.ts │ │ │ └── routes.ts │ │ ├── siteConfig │ │ │ └── index.ts │ │ ├── stores │ │ │ ├── ThemeBuilder.ts │ │ │ └── index.ts │ │ └── util │ │ │ └── getLocale.js │ └── tsconfig.json └── ui │ ├── .babelrc │ ├── .editorconfig │ ├── .gitignore │ ├── .npmignore │ ├── LICENSE.md │ ├── README.md │ ├── build │ ├── build.api.ts │ ├── build.api2.js │ ├── build.utils.ts │ ├── build.web-types.ts │ ├── config.ts │ ├── entry │ │ ├── QCalendar.cjs.js │ │ ├── QCalendar.esm.js │ │ ├── QCalendar.umd.js │ │ ├── QCalendarAgenda.cjs.js │ │ ├── QCalendarAgenda.esm.js │ │ ├── QCalendarAgenda.umd.js │ │ ├── QCalendarDay.cjs.js │ │ ├── QCalendarDay.esm.js │ │ ├── QCalendarDay.umd.js │ │ ├── QCalendarMonth.cjs.js │ │ ├── QCalendarMonth.esm.js │ │ ├── QCalendarMonth.umd.js │ │ ├── QCalendarResource.cjs.js │ │ ├── QCalendarResource.esm.js │ │ ├── QCalendarResource.umd.js │ │ ├── QCalendarScheduler.cjs.js │ │ ├── QCalendarScheduler.esm.js │ │ ├── QCalendarScheduler.umd.js │ │ ├── QCalendarTask.cjs.js │ │ ├── QCalendarTask.esm.js │ │ ├── QCalendarTask.umd.js │ │ ├── Timestamp.cjs.js │ │ ├── Timestamp.esm.js │ │ ├── Timestamp.umd.js │ │ ├── index.cjs.js │ │ ├── index.esm.js │ │ └── index.umd.js │ ├── index.ts │ ├── script.app-ext.ts │ ├── script.clean.ts │ ├── script.css.ts │ ├── script.javascript.ts │ ├── script.open-umd.ts │ ├── script.version.ts │ └── version │ │ └── version-template.js │ ├── eslint.config.mjs │ ├── package.json │ ├── src │ ├── QCalendar.scss │ ├── QCalendar.ts │ ├── QCalendarAgenda.scss │ ├── QCalendarAgenda.ts │ ├── QCalendarDay.scss │ ├── QCalendarDay.ts │ ├── QCalendarMonth.scss │ ├── QCalendarMonth.ts │ ├── QCalendarResource.scss │ ├── QCalendarResource.ts │ ├── QCalendarScheduler.scss │ ├── QCalendarScheduler.ts │ ├── QCalendarTask.scss │ ├── QCalendarTask.ts │ ├── QCalendarTransitions.scss │ ├── QCalendarVariables.scss │ ├── Timestamp.ts │ ├── api.extends.json │ ├── components │ │ ├── QCalendar.json │ │ ├── QCalendar.ts │ │ ├── QCalendarAgenda.json │ │ ├── QCalendarAgenda.ts │ │ ├── QCalendarDay.json │ │ ├── QCalendarDay.ts │ │ ├── QCalendarMonth.json │ │ ├── QCalendarMonth.ts │ │ ├── QCalendarResource.json │ │ ├── QCalendarResource.ts │ │ ├── QCalendarScheduler.json │ │ ├── QCalendarScheduler.ts │ │ ├── QCalendarTask.json │ │ └── QCalendarTask.ts │ ├── composables │ │ ├── private.useAgenda.json │ │ ├── private.useCellWidth.json │ │ ├── private.useCheckChange.json │ │ ├── private.useColumn.json │ │ ├── private.useCommon.json │ │ ├── private.useInterval.json │ │ ├── private.useMaxDays.json │ │ ├── private.useMonth.json │ │ ├── private.useMove.json │ │ ├── private.useNavigation.json │ │ ├── private.useResource.json │ │ ├── private.useResourceIntervals.json │ │ ├── private.useScheduler.json │ │ ├── private.useTasks.json │ │ ├── private.useTimes.json │ │ ├── useButton.ts │ │ ├── useCalendar.ts │ │ ├── useCellWidth.ts │ │ ├── useCheckChange.ts │ │ ├── useColumn.ts │ │ ├── useCommon.ts │ │ ├── useEmitListeners.ts │ │ ├── useEvents.ts │ │ ├── useFocusHelper.ts │ │ ├── useInterval.ts │ │ ├── useKeyboard.ts │ │ ├── useMaxDays.ts │ │ ├── useMonth.ts │ │ ├── useMouse.ts │ │ ├── useMove.ts │ │ ├── useRenderValues.ts │ │ ├── useTask.ts │ │ └── useTimes.ts │ ├── css │ │ ├── calendar-agenda.scss │ │ ├── calendar-day.scss │ │ ├── calendar-month-mini.scss │ │ ├── calendar-month.scss │ │ ├── calendar-resource.scss │ │ ├── calendar-scheduler.scss │ │ ├── calendar-task.scss │ │ ├── calendar-transitions.scss │ │ ├── calendar-variables.scss │ │ └── q-calendar.scss │ ├── directives │ │ ├── Resize.ts │ │ └── ResizeObserver.ts │ ├── index.scss │ ├── index.ts │ ├── utils │ │ ├── Timestamp.json │ │ ├── Timestamp.ts │ │ ├── helpers.ts │ │ ├── scroll.ts │ │ └── views.ts │ └── version.js │ ├── test │ ├── addToDate.spec.ts │ ├── compareDate.spec.ts │ ├── compareDateTime.spec.ts │ ├── compareTime.spec.ts │ ├── compareTimestamps.spec.ts │ ├── createDayList.spec.ts │ ├── createIntervalList.spec.ts │ ├── createNativeLocaleFormatter.spec.ts │ ├── daysBetween.spec.ts │ ├── daysInMonth.spec.ts │ ├── diffTimestamp.spec.ts │ ├── findWeekday.spec.ts │ ├── getDateTime.spec.ts │ ├── getDayIdentifier.spec.ts │ ├── getEndOfMonth.spec.ts │ ├── getEndOfWeek.spec.ts │ ├── getMonthFormatter.spec.ts │ ├── getMonthNames.spec.ts │ ├── getStartOfMonth.spec.ts │ ├── getStartOfWeek.spec.ts │ ├── getWeekdayFormatter.spec.ts │ ├── getWeekdayNames.spec.ts │ ├── getWorkWeek.spec.ts │ ├── isBetweenDates.spec.ts │ ├── isLeapYear.spec.ts │ ├── isOverlappingDates.spec.ts │ ├── makeDateTime.spec.ts │ ├── maxTimestamp.spec.ts │ ├── minTimestamp.spec.ts │ ├── nextDay.spec.ts │ ├── padNumber.spec.ts │ ├── parseDate.spec.ts │ ├── parseTime.spec.ts │ ├── parseTimestamp.spec.ts │ ├── parsed.spec.ts │ ├── prevDay.spec.ts │ ├── relativeDays.spec.ts │ ├── timeIdentifier.spec.ts │ ├── today.spec.ts │ ├── updateDayOfYear.spec.ts │ ├── updateDisabled.spec.ts │ ├── updateDisabledBeforeAfter.spec.ts │ ├── updateMinutes.spec.ts │ ├── updateRelative.spec.ts │ ├── updateWeekday.spec.ts │ ├── updateWorkWeek.spec.ts │ ├── validateNumber.spec.ts │ ├── validateTimestamp.spec.ts │ └── weeksBetween.spec.ts │ ├── tsconfig.base.json │ ├── tsconfig.json │ ├── types │ ├── index.d.ts │ ├── ts-helpers.d.ts │ └── types.d.ts │ ├── umd-test.html │ └── utility │ ├── checkIndex.js │ └── getExports.js ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── tsconfig.base.json ├── tsconfig.json └── vitest.config.ts /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [hawkeye64, rstoenescu] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with a single custom sponsorship URL -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | For a legitimate bug, in order to process faster, please go here https://codepen.io/Hawkeye64/pen/RwwwKQL, fork the codepen, add code to reproduce the bug and submit link here (don't forget to save your codepen): 11 | 12 | **Describe the bug** 13 | A clear and concise description of what the bug is. 14 | 15 | **To Reproduce** 16 | Steps to reproduce the behavior: 17 | 1. Go to '...' 18 | 2. Click on '....' 19 | 3. Scroll down to '....' 20 | 4. See error 21 | 22 | **Expected behavior** 23 | A clear and concise description of what you expected to happen. 24 | 25 | **Screenshots** 26 | If applicable, add screenshots to help explain your problem. 27 | 28 | **QCalendar (please complete the following information):** 29 | - Version [e.g. 4.0.0] 30 | 31 | **Desktop (please complete the following information):** 32 | - OS: [e.g. iOS] 33 | - Browser [e.g. chrome, safari] 34 | - Version [e.g. 22] 35 | 36 | **Smartphone (please complete the following information):** 37 | - Device: [e.g. iPhone6] 38 | - OS: [e.g. iOS8.1] 39 | - Browser [e.g. stock browser, safari] 40 | - Version [e.g. 22] 41 | 42 | **Additional context** 43 | Add any other context about the problem here. 44 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report_v4.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report (v4) 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: 'v4' 6 | assignees: '' 7 | 8 | --- 9 | 10 | For a legitimate bug, in order to process faster, please go here https://codepen.io/collection/qOBOEG, select the correct CodePen for your Calendar type and fork the codepen, add code to reproduce the bug and submit link here (don't forget to save your codepen): 11 | 12 | **Describe the bug** 13 | A clear and concise description of what the bug is. 14 | 15 | **To Reproduce** 16 | Steps to reproduce the behavior: 17 | 1. Go to '...' 18 | 2. Click on '....' 19 | 3. Scroll down to '....' 20 | 4. See error 21 | 22 | **Expected behavior** 23 | A clear and concise description of what you expected to happen. 24 | 25 | **Screenshots** 26 | If applicable, add screenshots to help explain your problem. 27 | 28 | **QCalendar (please complete the following information):** 29 | - Version [e.g. 4.0.0] 30 | 31 | **Desktop (please complete the following information):** 32 | - OS: [e.g. iOS] 33 | - Browser [e.g. chrome, safari] 34 | - Version [e.g. 22] 35 | 36 | **Smartphone (please complete the following information):** 37 | - Device: [e.g. iPhone6] 38 | - OS: [e.g. iOS8.1] 39 | - Browser [e.g. stock browser, safari] 40 | - Version [e.g. 22] 41 | 42 | **Additional context** 43 | Add any other context about the problem here. 44 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request_v4.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request (v4) 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: 'v4' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/RELEASE-TEMPLATE.md: -------------------------------------------------------------------------------- 1 | # QCalendar v4.x.x 2 | 3 | ## What's Changed 4 | 5 | **Features:** 6 | 7 | **Fixes:** 8 | 9 | --- 10 | 11 | ## Installing 12 | 13 | ``` 14 | $ pnpm add @quasar/quasar-ui-qcalendar 15 | # or 16 | $ yarn add @quasar/quasar-ui-qcalendar 17 | # or 18 | $ quasar ext add @quasar/qcalendar 19 | ``` 20 | 21 | ## Documentation 22 | 23 | [QCalendar v4 documentation](https://qcalendar.netlify.app/) is now hosted by Netlify. Visit the documentation to get more information and a Migration Guide (in the Help section). The documentation is incomplete and is currently being updated. You can help out by PR-ing deficiencies. 24 | 25 | ## Donations 26 | 27 | QCalendar is an open-source MIT licensed project that has been made possible due to the **generous contributions** by [sponsors and backers](https://github.com/sponsors/hawkeye64). If you are interested in supporting this project, please consider: 28 | 29 | - [Becoming a sponsor on Github](https://github.com/users/hawkeye64/sponsorship) 30 | - [One-off donation via PayPal](https://paypal.me/hawkeye64) 31 | -------------------------------------------------------------------------------- /.github/workflows/close-inactive-issues.yml: -------------------------------------------------------------------------------- 1 | name: Close inactive issues 2 | 3 | on: 4 | schedule: 5 | - cron: '5 0 * * *' 6 | 7 | jobs: 8 | close-issues: 9 | runs-on: ubuntu-latest 10 | permissions: 11 | issues: write 12 | pull-requests: write 13 | steps: 14 | - uses: actions/stale@v5 15 | with: 16 | days-before-issue-stale: 7 17 | days-before-issue-close: 7 18 | 19 | days-before-pr-stale: 7 20 | days-before-pr-close: 7 21 | 22 | stale-issue-label: 'stale' 23 | stale-pr-label: 'stale' 24 | 25 | stale-issue-message: 'Bumping this issue because it has been open for 7 days with no activity. Closing automatically in 7 days unless it becomes active again.' 26 | close-issue-message: 'Closing due to inactivity.' 27 | 28 | stale-pr-message: 'Bumping this pull request because it has been open for 7 days with no activity. Closing automatically in 7 days unless it becomes active again.' 29 | close-pr-message: 'Closing due to inactivity.' 30 | 31 | repo-token: ${{ secrets.GITHUB_TOKEN }} 32 | -------------------------------------------------------------------------------- /.github/workflows/run-vitest.yml: -------------------------------------------------------------------------------- 1 | name: Run Vitest Tests 2 | 3 | on: 4 | push: # Trigger on push to any branch 5 | pull_request: # Trigger on pull request to any branch 6 | 7 | jobs: 8 | vitest: 9 | name: Run Vitest 10 | runs-on: ubuntu-latest 11 | strategy: 12 | matrix: 13 | node-version: [20] # Test against multiple Node.js versions 14 | 15 | steps: 16 | # Checkout the repository code 17 | - uses: actions/checkout@v4 18 | 19 | # Install pnpm 20 | - name: Install pnpm 21 | uses: pnpm/action-setup@v4 22 | 23 | # Use Node.js 24 | - name: Use Node.js ${{ matrix.node-version }} 25 | uses: actions/setup-node@v4 26 | with: 27 | node-version: ${{ matrix.node-version }} 28 | cache: 'pnpm' 29 | 30 | # Install dependencies for all packages 31 | - name: Install dependencies 32 | run: pnpm install 33 | 34 | # Build all packages except docs 35 | - name: Build all packages 36 | run: pnpm build 37 | 38 | # Run Vitest tests 39 | - name: Run Vitest tests 40 | run: pnpm test 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .thumbs.db 3 | node_modules 4 | dist 5 | npm-debug.log* 6 | yarn-debug.log* 7 | yarn-error.log* 8 | 9 | # Editor directories and files 10 | .idea 11 | .vscode 12 | *.suo 13 | *.ntvs* 14 | *.njsproj 15 | *.sln 16 | 17 | docs/.quasar/ 18 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | # pnpm-related options 2 | shamefully-hoist=true 3 | strict-peer-dependencies=false 4 | link-workspace-packages=true 5 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | pnpm-lock.yaml 2 | .quasar 3 | dist 4 | node_modules 5 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/prettierrc", 3 | "semi": false, 4 | "singleQuote": true, 5 | "printWidth": 100, 6 | "bracketSpacing": true, 7 | "vueIndentScriptAndStyle": true 8 | } -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) Jeff Galbraith 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | publish = "packages/docs/dist/spa" 3 | command = "pnpm run build" 4 | 5 | [build.environment] 6 | NODE_OPTIONS = "--max_old_space_size=4096" 7 | NODE_VERSION = "20" 8 | PNPM_FLAGS = "--shamefully-hoist" 9 | 10 | [[redirects]] 11 | from = "/*" 12 | to = "/index.html" 13 | status = 200 -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "qcalendar", 3 | "version": "1.0.0", 4 | "description": "QCalendar mono-repo", 5 | "author": "Jeff Galbraith ", 6 | "license": "MIT", 7 | "private": true, 8 | "access": "private", 9 | "packageManager": "pnpm@10.3.0", 10 | "scripts": { 11 | "clean": "rm -rf node_modules pnpm-lock.yaml packages/ui/node_modules packages/docs/node_modules", 12 | "build": "pnpm run build:ui && pnpm run build:docs", 13 | "build:ui": "cd packages/ui && pnpm build", 14 | "build:docs": "cd packages/docs && pnpm build", 15 | "ci:publish": "pnpm -r publish --access public --publish-branch dev", 16 | "test": "vitest run", 17 | "deep": "ncu --deep", 18 | "lint": "eslint -c ./eslint.config.mjs \"packages/**/*.{ts,js,cjs,mjs,vue}\"" 19 | }, 20 | "devDependencies": { 21 | "@eslint/js": "^9.20.0", 22 | "@types/node": "^22.13.2", 23 | "@typescript-eslint/eslint-plugin": "^8.24.0", 24 | "@vitest/coverage-istanbul": "^3.0.5", 25 | "eslint": "^9.20.1", 26 | "globals": "^15.15.0", 27 | "prettier": "^3.5.1", 28 | "typescript": "~5.7.3", 29 | "unbuild": "^3.3.1", 30 | "vitest": "^3.0.5" 31 | } 32 | } -------------------------------------------------------------------------------- /packages/app-extension/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /packages/app-extension/.npmignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .thumbs.db 3 | yarn.lock 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Editor directories and files 9 | .idea 10 | .vscode 11 | *.suo 12 | *.ntvs* 13 | *.njsproj 14 | *.sln 15 | .editorconfig 16 | .eslintignore 17 | .eslintrc.js 18 | -------------------------------------------------------------------------------- /packages/app-extension/LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) Jeff Galbraith 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/app-extension/jsconfig.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "target": "es6" 6 | }, 7 | "exclude": ["node_modules"], 8 | "include": ["src/**/*"] 9 | } -------------------------------------------------------------------------------- /packages/app-extension/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@quasar/quasar-app-extension-qcalendar", 3 | "version": "4.1.2", 4 | "description": "A Quasar App Extension for @quasar/quasar-ui-qcalendar", 5 | "author": "Jeff Galbraith ", 6 | "license": "MIT", 7 | "type": "module", 8 | "main": "src/index.js", 9 | "funding": { 10 | "type": "github", 11 | "url": "https://github.com/sponsors/hawkeye64" 12 | }, 13 | "publishConfig": { 14 | "access": "public" 15 | }, 16 | "bugs": "https://github.com/quasarframework/quasar-ui-qcalendar/issues", 17 | "repository": { 18 | "type": "git", 19 | "url": "git+https://github.com/quasarframework/quasar-ui-qcalendar.git" 20 | }, 21 | "homepage": "https://github.com/quasarframework/quasar-ui-qcalendar", 22 | "keywords": [ 23 | "quasar", 24 | "quasarframework", 25 | "app", 26 | "app extension", 27 | "extension", 28 | "calendar", 29 | "daily", 30 | "weekly", 31 | "monthly", 32 | "events", 33 | "reminders", 34 | "schedule" 35 | ], 36 | "dependencies": { 37 | "@quasar/quasar-ui-qcalendar": "^4.1.2" 38 | }, 39 | "engines": { 40 | "node": "^28 || ^26 || ^24 || ^22 || ^20 || ^18", 41 | "npm": ">= 6.13.4", 42 | "yarn": ">= 1.21.1" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /packages/app-extension/src/boot/vite-register.js: -------------------------------------------------------------------------------- 1 | import { defineBoot } from '@quasar/app-vite/wrappers' 2 | import VuePlugin from '@quasar/quasar-ui-qcalendar' 3 | 4 | export default defineBoot(({ app }) => { 5 | app.use(VuePlugin) 6 | }) 7 | -------------------------------------------------------------------------------- /packages/app-extension/src/boot/webpack-register.js: -------------------------------------------------------------------------------- 1 | import { defineBoot } from '@quasar/app-webpack/wrappers' 2 | import VuePlugin from '@quasar/quasar-ui-qcalendar' 3 | 4 | export default defineBoot(({ app }) => { 5 | app.use(VuePlugin) 6 | }) 7 | -------------------------------------------------------------------------------- /packages/app-extension/src/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Quasar App Extension index/runner script 3 | * (runs on each dev/build) 4 | * 5 | * Docs: https://quasar.dev/app-extensions/development-guide/index-api 6 | * API: https://github.com/quasarframework/quasar/blob/master/app/lib/app-extension/IndexAPI.js 7 | */ 8 | 9 | function extendConf(conf, api) { 10 | if (api.hasVite) { 11 | // register the boot file 12 | conf.boot.push('~@quasar/quasar-app-extension-qcalendar/src/boot/vite-register.js') 13 | } else { 14 | // register the boot file 15 | conf.boot.push('~@quasar/quasar-app-extension-qcalendar/src/boot/webpack-register.js') 16 | // make sure app extension files & ui packages get transpiled 17 | conf.build.transpile = true 18 | conf.build.webpackTranspileDependencies = conf.build.webpackTranspileDependencies || [] 19 | conf.build.webpackTranspileDependencies.push(/quasar-app-extension-qcalendar[\\/]src/) 20 | conf.build.webpackTranspileDependencies.push(/quasar-ui-qcalendar[\\/]src/) 21 | } 22 | 23 | // make sure the stylesheet goes through webpack to avoid SSR issues 24 | conf.css.push('~@quasar/quasar-ui-qcalendar/src/index.scss') 25 | } 26 | 27 | export default function (api) { 28 | // Quasar compatibility check; you may need 29 | // hard dependencies, as in a minimum version of the "quasar" 30 | // package or a minimum version of "@quasar/app" CLI 31 | api.compatibleWith('quasar', '^2.0.0') 32 | 33 | if (api.hasVite === true) { 34 | api.compatibleWith('@quasar/app-vite', '^2.0.0') 35 | } else { 36 | api.compatibleWith('@quasar/app-webpack', '^4.0.0') 37 | } 38 | 39 | // Uncomment the line below if you provide a JSON API for your component 40 | api.registerDescribeApi('QCalendar', '~@quasar/quasar-ui-qcalendar/dist/api/QCalendar.json') 41 | 42 | // We extend /quasar.conf.js 43 | api.extendQuasarConf(extendConf) 44 | } 45 | -------------------------------------------------------------------------------- /packages/docs/.editorconfig: -------------------------------------------------------------------------------- 1 | [*.{js,jsx,mjs,cjs,ts,tsx,mts,cts,vue}] 2 | charset = utf-8 3 | indent_size = 2 4 | indent_style = space 5 | end_of_line = lf 6 | insert_final_newline = true 7 | trim_trailing_whitespace = true 8 | -------------------------------------------------------------------------------- /packages/docs/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .thumbs.db 3 | node_modules 4 | 5 | # Quasar core related directories 6 | .quasar 7 | /dist 8 | /quasar.config.*.temporary.compiled* 9 | 10 | # Cordova related directories and files 11 | /src-cordova/node_modules 12 | /src-cordova/platforms 13 | /src-cordova/plugins 14 | /src-cordova/www 15 | 16 | # Capacitor related directories and files 17 | /src-capacitor/www 18 | /src-capacitor/node_modules 19 | 20 | # Log files 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | 25 | # Editor directories and files 26 | .idea 27 | *.suo 28 | *.ntvs* 29 | *.njsproj 30 | *.sln 31 | 32 | # local .env files 33 | .env.local* 34 | -------------------------------------------------------------------------------- /packages/docs/.npmrc: -------------------------------------------------------------------------------- 1 | # pnpm-related options 2 | shamefully-hoist=true 3 | strict-peer-dependencies=false 4 | # to get the latest compatible packages when creating the project https://github.com/pnpm/pnpm/issues/6463 5 | resolution-mode=highest 6 | -------------------------------------------------------------------------------- /packages/docs/.prettierignore: -------------------------------------------------------------------------------- 1 | # Ignore all Markdown files: 2 | \*_/_.md -------------------------------------------------------------------------------- /packages/docs/.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/prettierrc", 3 | "semi": false, 4 | "singleQuote": true, 5 | "printWidth": 100 6 | } -------------------------------------------------------------------------------- /packages/docs/README.md: -------------------------------------------------------------------------------- 1 | # Quasar App (docs) 2 | 3 | A Quasar Project 4 | 5 | ## Install the dependencies 6 | ```bash 7 | yarn 8 | # or 9 | npm install 10 | ``` 11 | 12 | ### Start the app in development mode (hot-code reloading, error reporting, etc.) 13 | ```bash 14 | quasar dev 15 | ``` 16 | 17 | 18 | ### Lint the files 19 | ```bash 20 | yarn lint 21 | # or 22 | npm run lint 23 | ``` 24 | 25 | 26 | ### Format the files 27 | ```bash 28 | yarn format 29 | # or 30 | npm run format 31 | ``` 32 | 33 | 34 | ### Build the app for production 35 | ```bash 36 | quasar build 37 | ``` 38 | 39 | ### Customize the configuration 40 | See [Configuring quasar.config.js](https://v2.quasar.dev/quasar-cli-vite/quasar-config-js). 41 | -------------------------------------------------------------------------------- /packages/docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <%= productName %> 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /packages/docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "docs", 3 | "version": "0.0.1", 4 | "description": "QCalendar Documentation and examples", 5 | "productName": "QCalendar Docs", 6 | "author": "Jeff ", 7 | "type": "module", 8 | "private": true, 9 | "scripts": { 10 | "lint": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\"", 11 | "format": "prettier --write \"**/*.{js,ts,vue,scss,html,md,json}\" --ignore-path .gitignore", 12 | "test": "echo \"No test specified\" && exit 0", 13 | "dev": "quasar dev", 14 | "build": "quasar build", 15 | "postinstall": "quasar prepare" 16 | }, 17 | "dependencies": { 18 | "@carbon/icons-vue": "^10.99.1", 19 | "@quasar/extras": "^1.16.17", 20 | "date-holidays": "=3.23.21", 21 | "pinia": "^3.0.1", 22 | "prismjs": "^1.29.0", 23 | "quasar": "^2.17.7", 24 | "vue": "^3.5.13", 25 | "vue-router": "^4.5.0" 26 | }, 27 | "devDependencies": { 28 | "@eslint/js": "^9.20.0", 29 | "@md-plugins/quasar-app-extension-q-press": "0.1.0-alpha.29", 30 | "@md-plugins/vite-examples-plugin": "0.1.0-alpha.29", 31 | "@md-plugins/vite-md-plugin": "0.1.0-alpha.29", 32 | "@quasar/app-vite": "^2.1.0", 33 | "@quasar/quasar-ui-qcalendar": "workspace:*", 34 | "@types/markdown-it": "^14.1.2", 35 | "@types/node": "^22.13.2", 36 | "@vue/eslint-config-prettier": "^10.2.0", 37 | "@vue/eslint-config-typescript": "^14.4.0", 38 | "autoprefixer": "^10.4.20", 39 | "eslint": "^9.20.1", 40 | "eslint-plugin-vue": "^9.32.0", 41 | "globals": "^15.15.0", 42 | "markdown-it": "^14.1.0", 43 | "prettier": "^3.5.1", 44 | "typescript": "~5.7.3", 45 | "vite-plugin-checker": "^0.8.0", 46 | "vue-tsc": "^2.2.0" 47 | }, 48 | "engines": { 49 | "node": "^28 || ^26 || ^24 || ^22 || ^20 || ^18", 50 | "npm": ">= 6.13.4", 51 | "yarn": ">= 1.21.1" 52 | } 53 | } -------------------------------------------------------------------------------- /packages/docs/postcss.config.js: -------------------------------------------------------------------------------- 1 | // https://github.com/michael-ciniawsky/postcss-load-config 2 | 3 | import autoprefixer from 'autoprefixer' 4 | // import rtlcss from 'postcss-rtlcss' 5 | 6 | export default { 7 | plugins: [ 8 | // https://github.com/postcss/autoprefixer 9 | autoprefixer({ 10 | overrideBrowserslist: [ 11 | 'last 4 Chrome versions', 12 | 'last 4 Firefox versions', 13 | 'last 4 Edge versions', 14 | 'last 4 Safari versions', 15 | 'last 4 Android versions', 16 | 'last 4 ChromeAndroid versions', 17 | 'last 4 FirefoxAndroid versions', 18 | 'last 4 iOS versions' 19 | ] 20 | }), 21 | 22 | // https://github.com/elchininet/postcss-rtlcss 23 | // If you want to support RTL css, then 24 | // 1. yarn/pnpm/bun/npm install postcss-rtlcss 25 | // 2. optionally set quasar.config.js > framework > lang to an RTL language 26 | // 3. uncomment the following line (and its import statement above): 27 | // rtlcss() 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /packages/docs/public/QCalendarAgenda.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/QCalendarAgenda.png -------------------------------------------------------------------------------- /packages/docs/public/QCalendarDay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/QCalendarDay.png -------------------------------------------------------------------------------- /packages/docs/public/QCalendarMonth--mini-mode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/QCalendarMonth--mini-mode.png -------------------------------------------------------------------------------- /packages/docs/public/QCalendarMonth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/QCalendarMonth.png -------------------------------------------------------------------------------- /packages/docs/public/QCalendarResource.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/QCalendarResource.png -------------------------------------------------------------------------------- /packages/docs/public/QCalendarScheduler.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/QCalendarScheduler.png -------------------------------------------------------------------------------- /packages/docs/public/QCalendarTask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/QCalendarTask.png -------------------------------------------------------------------------------- /packages/docs/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/favicon.ico -------------------------------------------------------------------------------- /packages/docs/public/icons/favicon-128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/icons/favicon-128x128.png -------------------------------------------------------------------------------- /packages/docs/public/icons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/icons/favicon-16x16.png -------------------------------------------------------------------------------- /packages/docs/public/icons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/icons/favicon-32x32.png -------------------------------------------------------------------------------- /packages/docs/public/icons/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/icons/favicon-96x96.png -------------------------------------------------------------------------------- /packages/docs/public/q-calendar-month-view-mini-mode-with-selection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/q-calendar-month-view-mini-mode-with-selection.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendar-5day-done-incorrectly.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendar-5day-done-incorrectly.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendar-agenda-view--column-options.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendar-agenda-view--column-options.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendar-agenda-view--planner-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendar-agenda-view--planner-1.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendar-agenda-view--planner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendar-agenda-view--planner.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendar-agenda-view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendar-agenda-view.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendar-custom-interval-view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendar-custom-interval-view.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendar-day-view--intervals.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendar-day-view--intervals.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendar-day-view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendar-day-view.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendar-locale-arabic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendar-locale-arabic.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendar-locale-chinese.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendar-locale-chinese.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendar-locale-french.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendar-locale-french.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendar-locale-german.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendar-locale-german.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendar-locale-romanian.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendar-locale-romanian.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendar-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendar-logo.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendar-month-interval-view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendar-month-interval-view.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendar-month-view--week-slot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendar-month-view--week-slot.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendar-month-view-5day.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendar-month-view-5day.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendar-month-view-mini-mode-multi-month-selection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendar-month-view-mini-mode-multi-month-selection.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendar-month-view-monday-first-day.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendar-month-view-monday-first-day.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendar-month-view-workweek.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendar-month-view-workweek.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendar-month-view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendar-month-view.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendar-resource-view--hierarchial.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendar-resource-view--hierarchial.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendar-resource-view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendar-resource-view.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendar-scheduler-view--hierarchial.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendar-scheduler-view--hierarchial.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendar-scheduler-view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendar-scheduler-view.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendar-theme-blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendar-theme-blue.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendar-theme-brown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendar-theme-brown.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendar-theme-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendar-theme-dark.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendar-theme-deep-purple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendar-theme-deep-purple.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendar-theme-indigo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendar-theme-indigo.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendar-theme-teal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendar-theme-teal.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendar-toolbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendar-toolbar.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendar-week-view-5day.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendar-week-view-5day.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendar-week-view-monday-first-day.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendar-week-view-monday-first-day.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendar-week-view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendar-week-view.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendar-week-view2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendar-week-view2.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendar-workweeks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendar-workweeks.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendaragenda-planner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendaragenda-planner.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendarday--column-count.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendarday--column-count.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendarmonth-event-slots.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendarmonth-event-slots.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendarmonth-indigo-theme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendarmonth-indigo-theme.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendarmonth-minimode-deep-purple-theme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendarmonth-minimode-deep-purple-theme.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendarmonth-minimode-range-selection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendarmonth-minimode-range-selection.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendarmonth-workweeks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendarmonth-workweeks.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendarresource-children.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendarresource-children.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendarscheduler-brown-theme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendarscheduler-brown-theme.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendarscheduler-children.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendarscheduler-children.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendartask-colored-weekends.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendartask-colored-weekends.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendartask-teal-theme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendartask-teal-theme.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendarweek-blue-theme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendarweek-blue-theme.png -------------------------------------------------------------------------------- /packages/docs/public/qcalendarweek-dark-mode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/qcalendarweek-dark-mode.png -------------------------------------------------------------------------------- /packages/docs/public/theme-builder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/public/theme-builder.png -------------------------------------------------------------------------------- /packages/docs/quasar.extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "@md-plugins/q-press": {} 3 | } -------------------------------------------------------------------------------- /packages/docs/src/.q-press/api/components/DarkModeToggle.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "component", 3 | "meta": { 4 | "docsUrl": "https://path-to-your-docs/dark-mode-toggle" 5 | }, 6 | "props": { 7 | "darkIcon": { 8 | "type": "String", 9 | "desc": "Icon name for dark mode", 10 | "examples": [ 11 | "mdiMoonWaningCrescent" 12 | ], 13 | "default": "mdiMoonWaningCrescent", 14 | "category": "content" 15 | }, 16 | "lightIcon": { 17 | "type": "String", 18 | "desc": "Icon name for light mode", 19 | "examples": [ 20 | "mdiWhiteBalanceSunny" 21 | ], 22 | "default": "mdiWhiteBalanceSunny", 23 | "category": "content" 24 | } 25 | }, 26 | "events": { 27 | "update:mode": { 28 | "desc": "Emitted when the mode is toggled", 29 | "params": { 30 | "mode": { 31 | "type": "String", 32 | "desc": "The current mode ('dark' or 'light')" 33 | } 34 | } 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /packages/docs/src/.q-press/api/components/MarkdownApi.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "component", 3 | "meta": { 4 | "docsUrl": "https://path-to-your-docs/markdown-api" 5 | }, 6 | "props": { 7 | "nameBanner": { 8 | "type": "String", 9 | "desc": "Title to display in the banner", 10 | "examples": [ 11 | "'API Documentation'", 12 | "'Component API'" 13 | ], 14 | "category": "content" 15 | }, 16 | "pageLink": { 17 | "type": "String", 18 | "desc": "URL for the page link", 19 | "examples": [ 20 | "'https://github.com/user/repo/edit/main/docs/page.md'" 21 | ], 22 | "category": "navigation" 23 | } 24 | }, 25 | "events": { 26 | "searchFieldClick": { 27 | "desc": "Emitted when the search field is clicked", 28 | "params": { 29 | "evt": { 30 | "type": "Event", 31 | "desc": "JS event object" 32 | } 33 | } 34 | }, 35 | "filterClick": { 36 | "desc": "Emitted when the filter button is clicked", 37 | "params": { 38 | "evt": { 39 | "type": "Event", 40 | "desc": "JS event object" 41 | } 42 | } 43 | } 44 | }, 45 | "methods": { 46 | "onSearchFieldClick": { 47 | "desc": "Handler for the search field click event", 48 | "params": { 49 | "evt": { 50 | "type": "Event", 51 | "desc": "JS event object" 52 | } 53 | }, 54 | "returns": null 55 | }, 56 | "onFilterClick": { 57 | "desc": "Handler for the filter button click event", 58 | "params": { 59 | "evt": { 60 | "type": "Event", 61 | "desc": "JS event object" 62 | } 63 | }, 64 | "returns": null 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /packages/docs/src/.q-press/api/components/MarkdownCardLink.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "component", 3 | "meta": { 4 | "docsUrl": "https://path-to-your-docs/markdown-card-link" 5 | }, 6 | "props": { 7 | "to": { 8 | "type": "String", 9 | "desc": "The target URL or path for the link", 10 | "examples": [ 11 | "/home", 12 | "https://example.com" 13 | ], 14 | "required": true, 15 | "category": "navigation" 16 | }, 17 | "external": { 18 | "type": "Boolean", 19 | "desc": "Flag to indicate if the link is external", 20 | "category": "navigation" 21 | } 22 | }, 23 | "slots": { 24 | "default": { 25 | "desc": "Slot for custom content inside the link" 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /packages/docs/src/.q-press/api/components/MarkdownCardTitle.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "component", 3 | "meta": { 4 | "docsUrl": "https://path-to-your-docs/markdown-card-title" 5 | }, 6 | "props": { 7 | "title": { 8 | "type": "String", 9 | "desc": "The title text to display", 10 | "examples": [ 11 | "'Introduction'", 12 | "'Chapter 1'" 13 | ], 14 | "category": "content" 15 | }, 16 | "prefix": { 17 | "type": "String", 18 | "desc": "Prefix to add to the slugified title", 19 | "examples": [ 20 | "'section-'" 21 | ], 22 | "category": "content" 23 | } 24 | }, 25 | "events": { 26 | "click": { 27 | "desc": "Emitted when the title is clicked", 28 | "params": { 29 | "evt": { 30 | "type": "Event", 31 | "desc": "JS event object" 32 | } 33 | } 34 | } 35 | }, 36 | "methods": { 37 | "onClick": { 38 | "desc": "Handler for the click event on the title", 39 | "params": { 40 | "evt": { 41 | "type": "Event", 42 | "desc": "JS event object" 43 | } 44 | }, 45 | "returns": null 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /packages/docs/src/.q-press/api/components/MarkdownCode.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "component", 3 | "meta": { 4 | "docsUrl": "https://path-to-your-docs/markdown-code" 5 | }, 6 | "props": { 7 | "code": { 8 | "type": "String", 9 | "desc": "The code to display", 10 | "examples": [ 11 | "'const a = 1;'", 12 | "'
Hello World
'" 13 | ], 14 | "category": "content" 15 | }, 16 | "maxHeight": { 17 | "type": "String", 18 | "desc": "Maximum height for the code block", 19 | "examples": [ 20 | "'200px'", 21 | "'50vh'" 22 | ], 23 | "category": "style" 24 | }, 25 | "lang": { 26 | "type": "String", 27 | "desc": "Language of the code for syntax highlighting", 28 | "default": "js", 29 | "examples": [ 30 | "'js'", 31 | "'html'", 32 | "'css'" 33 | ], 34 | "category": "content" 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /packages/docs/src/.q-press/api/components/MarkdownCodePrism.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "component", 3 | "meta": { 4 | "docsUrl": "https://path-to-your-docs/markdown-code-prism" 5 | }, 6 | "props": { 7 | "code": { 8 | "type": "String", 9 | "desc": "The code to display with syntax highlighting", 10 | "examples": [ 11 | "'const a = 1;'", 12 | "'
Hello World
'" 13 | ], 14 | "required": true, 15 | "category": "content" 16 | }, 17 | "lang": { 18 | "type": "String", 19 | "desc": "Language of the code for syntax highlighting", 20 | "examples": [ 21 | "'js'", 22 | "'html'", 23 | "'css'" 24 | ], 25 | "required": true, 26 | "category": "content" 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /packages/docs/src/.q-press/api/components/MarkdownCodepen.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "component", 3 | "meta": { 4 | "docsUrl": "https://path-to-your-docs/markdown-codepen" 5 | }, 6 | "props": { 7 | "active": { 8 | "type": "Boolean", 9 | "desc": "Flag to indicate if the form should be active", 10 | "category": "state" 11 | }, 12 | "options": { 13 | "type": "String", 14 | "desc": "JSON string containing the CodePen options", 15 | "examples": [ 16 | "'{\"title\":\"My Pen\",\"html\":\"
Hello World
\"}'" 17 | ], 18 | "category": "content" 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /packages/docs/src/.q-press/api/components/MarkdownCopyButton.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "component", 3 | "meta": { 4 | "docsUrl": "https://path-to-your-docs/markdown-copy-button" 5 | }, 6 | "props": { 7 | "lang": { 8 | "type": "String", 9 | "desc": "Language of the code block to copy", 10 | "examples": [ 11 | "'js'", 12 | "'html'", 13 | "'css'" 14 | ], 15 | "category": "content" 16 | } 17 | }, 18 | "events": { 19 | "copy": { 20 | "desc": "Emitted when the copy button is clicked", 21 | "params": { 22 | "evt": { 23 | "type": "Event", 24 | "desc": "JS event object" 25 | } 26 | } 27 | } 28 | }, 29 | "methods": { 30 | "copy": { 31 | "desc": "Method to copy the code block to the clipboard", 32 | "params": {}, 33 | "returns": null 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /packages/docs/src/.q-press/api/components/MarkdownDrawerSidebar.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "component", 3 | "meta": { 4 | "docsUrl": "https://path-to-your-docs/markdown-drawer-toc" 5 | }, 6 | "events": { 7 | "toggleTocDrawer": { 8 | "desc": "Emitted when the close button is clicked to toggle the Table of Contents drawer", 9 | "params": { 10 | "evt": { 11 | "type": "Event", 12 | "desc": "JS event object" 13 | } 14 | } 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /packages/docs/src/.q-press/api/components/MarkdownDrawerToc.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "component", 3 | "meta": { 4 | "docsUrl": "https://path-to-your-docs/markdown-drawer-toc" 5 | }, 6 | "events": { 7 | "toggleTocDrawer": { 8 | "desc": "Emitted when the close button is clicked to toggle the Table of Contents drawer", 9 | "params": { 10 | "evt": { 11 | "type": "Event", 12 | "desc": "JS event object" 13 | } 14 | } 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /packages/docs/src/.q-press/api/components/MarkdownExample.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "component", 3 | "meta": { 4 | "docsUrl": "https://path-to-your-docs/markdown-example" 5 | }, 6 | "props": { 7 | "title": { 8 | "type": "String", 9 | "desc": "Title of the example", 10 | "examples": [ 11 | "'Example 1'", 12 | "'Sample Code'" 13 | ], 14 | "category": "content" 15 | }, 16 | "noGithub": { 17 | "type": "Boolean", 18 | "desc": "Flag to indicate if the GitHub button should be hidden", 19 | "category": "behavior" 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /packages/docs/src/.q-press/api/components/MarkdownHeader.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "component", 3 | "meta": { 4 | "docsUrl": "https://path-to-your-docs/markdown-header" 5 | }, 6 | "props": { 7 | "heightHint": { 8 | "type": "Number", 9 | "desc": "Height hint for the header", 10 | "examples": [ 11 | 128, 12 | 64 13 | ], 14 | "category": "style" 15 | } 16 | }, 17 | "events": { 18 | "toggleMenuDrawer": { 19 | "desc": "Emitted when the menu button is clicked to toggle the menu drawer", 20 | "params": { 21 | "evt": { 22 | "type": "Event", 23 | "desc": "JS event object" 24 | } 25 | } 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /packages/docs/src/.q-press/api/components/MarkdownHeaderIconLinks.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "component", 3 | "meta": { 4 | "docsUrl": "https://path-to-your-docs/markdown-header-icon-links" 5 | }, 6 | "props": { 7 | "menu": { 8 | "type": "Array", 9 | "desc": "Array of menu entries to display as icon links in the header", 10 | "examples": [ 11 | "[{ icon: 'home', path: '/' }, { icon: 'info', path: '/about' }]" 12 | ], 13 | "category": "content" 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /packages/docs/src/.q-press/api/components/MarkdownHeaderTextLinks.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "component", 3 | "meta": { 4 | "docsUrl": "https://path-to-your-docs/markdown-header-text-links" 5 | }, 6 | "props": { 7 | "menu": { 8 | "type": "Array", 9 | "desc": "Array of menu items to display in the header", 10 | "examples": [ 11 | "[{ name: 'Home', path: '/' }, { name: 'Docs', path: '/docs' }]" 12 | ], 13 | "category": "content" 14 | }, 15 | "mqPrefix": { 16 | "type": "String", 17 | "desc": "Prefix for media query classes", 18 | "examples": [ 19 | "'md'", 20 | "'lg'" 21 | ], 22 | "category": "style" 23 | }, 24 | "navClass": { 25 | "type": "String", 26 | "desc": "Additional CSS class to apply to navigation items", 27 | "examples": [ 28 | "'custom-nav-class'" 29 | ], 30 | "category": "style" 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /packages/docs/src/.q-press/api/components/MarkdownInstallation.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "component", 3 | "meta": { 4 | "docsUrl": "https://path-to-your-docs/markdown-installation" 5 | }, 6 | "props": { 7 | "title": { 8 | "type": "String", 9 | "desc": "Title of the installation section", 10 | "examples": [ 11 | "'Installation'", 12 | "'Setup Guide'" 13 | ], 14 | "category": "content" 15 | }, 16 | "id": { 17 | "type": "String", 18 | "desc": "ID for the installation card", 19 | "examples": [ 20 | "'installation-section'" 21 | ], 22 | "category": "content" 23 | }, 24 | "tabList": { 25 | "type": "Array", 26 | "desc": "List of tabs to display", 27 | "examples": [ 28 | "['npm', 'yarn', 'pnpm']" 29 | ], 30 | "category": "content" 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /packages/docs/src/.q-press/api/components/MarkdownLayout.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "component", 3 | "meta": { 4 | "docsUrl": "https://path-to-your-docs/markdown-layout" 5 | }, 6 | "props": { 7 | "pageClass": { 8 | "type": "String", 9 | "desc": "CSS class to apply to the q-page component", 10 | "examples": [ 11 | "'custom-page-class'" 12 | ], 13 | "category": "style" 14 | }, 15 | "pageContentClass": { 16 | "type": "String", 17 | "desc": "CSS class to apply to the page content container", 18 | "examples": [ 19 | "'custom-page-content-class'" 20 | ], 21 | "category": "style" 22 | }, 23 | "isFullscreen": { 24 | "type": "Boolean", 25 | "desc": "Flag to indicate if the page is in fullscreen mode", 26 | "category": "state" 27 | } 28 | }, 29 | "events": { 30 | "scroll": { 31 | "desc": "Emitted when the page is scrolled", 32 | "params": { 33 | "evt": { 34 | "type": "Event", 35 | "desc": "JS event object" 36 | } 37 | } 38 | } 39 | }, 40 | "methods": { 41 | "onPageScroll": { 42 | "desc": "Handler for the page scroll event", 43 | "params": { 44 | "evt": { 45 | "type": "Event", 46 | "desc": "JS event object" 47 | } 48 | }, 49 | "returns": null 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /packages/docs/src/.q-press/api/components/MarkdownLink.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "component", 3 | "meta": { 4 | "docsUrl": "https://path-to-your-docs/markdown-link" 5 | }, 6 | "props": { 7 | "to": { 8 | "type": "String", 9 | "desc": "The target URL or path for the link", 10 | "examples": [ 11 | "/home", 12 | "https://example.com" 13 | ], 14 | "required": true, 15 | "category": "navigation" 16 | } 17 | }, 18 | "slots": { 19 | "default": { 20 | "desc": "Slot for custom content inside the link" 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /packages/docs/src/.q-press/api/components/MarkdownPage.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "component", 3 | "meta": { 4 | "docsUrl": "https://path-to-your-docs/markdown-page" 5 | }, 6 | "props": { 7 | "overline": { 8 | "type": "String", 9 | "desc": "Text to display as an `overline` above the title", 10 | "examples": [ 11 | "'Introduction'", 12 | "'Chapter 1'" 13 | ], 14 | "category": "content" 15 | }, 16 | "title": { 17 | "type": "String", 18 | "desc": "Title of the markdown page", 19 | "examples": [ 20 | "'Getting Started'", 21 | "'API Reference'" 22 | ], 23 | "category": "content" 24 | }, 25 | "badge": { 26 | "type": "String", 27 | "desc": "Badge text to display next to the title", 28 | "examples": [ 29 | "'New'", 30 | "'Updated'" 31 | ], 32 | "category": "content" 33 | }, 34 | "editLink": { 35 | "type": "String", 36 | "desc": "URL for the edit link", 37 | "examples": [ 38 | "'https://github.com/user/repo/edit/main/docs/page.md'" 39 | ], 40 | "category": "navigation" 41 | }, 42 | "isFullscreen": { 43 | "type": "Boolean", 44 | "desc": "Flag to indicate if the page is in `fullscreen` mode", 45 | "category": "state" 46 | } 47 | }, 48 | "slots": { 49 | "default": { 50 | "desc": "Slot for the main content of the markdown page" 51 | } 52 | }, 53 | "events": { 54 | "edit": { 55 | "desc": "Emitted when the edit button is clicked", 56 | "params": { 57 | "evt": { 58 | "type": "Event", 59 | "desc": "JS event object" 60 | } 61 | } 62 | } 63 | }, 64 | "methods": { 65 | "toggleFullscreen": { 66 | "desc": "Toggle the fullscreen mode of the markdown page", 67 | "params": {}, 68 | "returns": null 69 | } 70 | } 71 | } -------------------------------------------------------------------------------- /packages/docs/src/.q-press/api/components/MarkdownPageFooter.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "component", 3 | "meta": { 4 | "docsUrl": "https://path-to-your-docs/markdown-page-footer" 5 | }, 6 | "props": { 7 | "fullscreen": { 8 | "type": "Boolean", 9 | "desc": "Flag to indicate if the page is in fullscreen mode", 10 | "category": "state" 11 | }, 12 | "links": { 13 | "type": "Array", 14 | "desc": "Array of link objects to display in the footer", 15 | "examples": [ 16 | "[{ name: 'Home', path: '/' }, { name: 'Docs', path: '/docs' }]" 17 | ], 18 | "category": "content" 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /packages/docs/src/.q-press/api/components/MarkdownPageSidebar.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "plugin", 3 | "meta": { 4 | "docsUrl": "https://path-to-your-docs/markdown-page-sidebar" 5 | }, 6 | "functions": { 7 | "getParentProxy": { 8 | "desc": "Retrieves the parent proxy of a given component proxy.", 9 | "params": { 10 | "proxy": { 11 | "type": "ComponentProxy", 12 | "desc": "The component proxy to retrieve the parent for." 13 | } 14 | }, 15 | "returns": { 16 | "type": "ComponentProxy | undefined", 17 | "desc": "The parent component proxy, or undefined if not found." 18 | } 19 | } 20 | }, 21 | "types": { 22 | "ComponentProxy": { 23 | "desc": "Interface representing a component proxy.", 24 | "properties": { 25 | "$parent": { 26 | "type": "ComponentProxy", 27 | "desc": "The parent component proxy." 28 | }, 29 | "$": { 30 | "type": "Object", 31 | "desc": "Internal Vue instance properties.", 32 | "properties": { 33 | "parent": { 34 | "type": "Object", 35 | "desc": "The parent Vue instance.", 36 | "properties": { 37 | "proxy": { 38 | "type": "ComponentProxy", 39 | "desc": "The parent component proxy." 40 | }, 41 | "parent": { 42 | "type": "ComponentProxy", 43 | "desc": "The grandparent component proxy." 44 | } 45 | } 46 | } 47 | } 48 | }, 49 | "show": { 50 | "type": "Function", 51 | "desc": "Function to show the component." 52 | } 53 | } 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /packages/docs/src/.q-press/api/components/MarkdownPageToc.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "component", 3 | "meta": { 4 | "docsUrl": "https://path-to-your-docs/markdown-page-toc" 5 | }, 6 | "events": { 7 | "click": { 8 | "desc": "Emitted when a Table of Contents item is clicked", 9 | "params": { 10 | "tocItem": { 11 | "type": "Object", 12 | "desc": "The Table of Contents item that was clicked" 13 | } 14 | } 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /packages/docs/src/.q-press/api/components/MarkdownPrerender.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "component", 3 | "meta": { 4 | "docsUrl": "https://path-to-your-docs/markdown-prerender" 5 | }, 6 | "props": { 7 | "title": { 8 | "type": "String", 9 | "desc": "Title of the prerendered content", 10 | "examples": [ 11 | "'Example Title'", 12 | "'Sample Content'" 13 | ], 14 | "category": "content" 15 | }, 16 | "tabs": { 17 | "type": "Array", 18 | "desc": "List of tabs to display", 19 | "examples": [ 20 | "['Tab 1', 'Tab 2']" 21 | ], 22 | "category": "content" 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /packages/docs/src/.q-press/api/components/MarkdownTree.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "component", 3 | "meta": { 4 | "docsUrl": "https://path-to-your-docs/markdown-tree" 5 | }, 6 | "props": { 7 | "nodes": { 8 | "type": "Array", 9 | "desc": "Array of nodes to display in the tree", 10 | "examples": [ 11 | "[{ id: 1, l: 'Node 1', c: [{ id: 2, l: 'Child Node' }] }]" 12 | ], 13 | "category": "content" 14 | } 15 | }, 16 | "slots": { 17 | "default-header": { 18 | "desc": "Slot for custom content in the tree node header", 19 | "scope": { 20 | "prop": { 21 | "type": "Object", 22 | "desc": "Properties of the tree node" 23 | } 24 | } 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /packages/docs/src/.q-press/api/composables/dark.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "component", 3 | "meta": { 4 | "docsUrl": "https://path-to-your-docs/dark" 5 | }, 6 | "functions": { 7 | "useDark": { 8 | "desc": "Composable function to manage dark mode settings.", 9 | "returns": { 10 | "type": "Object", 11 | "desc": "An object containing the dark mode state and functions to initialize and toggle dark mode.", 12 | "properties": { 13 | "isDark": { 14 | "type": "ComputedRef", 15 | "desc": "A computed reference to the current dark mode state." 16 | }, 17 | "initDark": { 18 | "type": "Function", 19 | "desc": "Function to initialize the dark mode state based on cookies." 20 | }, 21 | "toggleDark": { 22 | "type": "Function", 23 | "desc": "Function to toggle the dark mode state and update cookies." 24 | } 25 | } 26 | } 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /packages/docs/src/.q-press/api/composables/scroll.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "plugin", 3 | "meta": { 4 | "docsUrl": "https://path-to-your-docs/scroll" 5 | }, 6 | "functions": { 7 | "useScroll": { 8 | "desc": "Composable function to manage scroll behavior.", 9 | "returns": { 10 | "type": "Object", 11 | "desc": "An object containing functions to manage scroll behavior.", 12 | "properties": { 13 | "scrollToCurrentAnchor": { 14 | "type": "Function", 15 | "desc": "Function to scroll to the current anchor in the route.", 16 | "params": { 17 | "isRouteChange": { 18 | "type": "boolean", 19 | "desc": "Flag to indicate if the scroll is due to a route change." 20 | } 21 | }, 22 | "returns": null 23 | }, 24 | "scrollToTop": { 25 | "type": "Function", 26 | "desc": "Function to scroll to the top of the page.", 27 | "params": {}, 28 | "returns": null 29 | } 30 | } 31 | } 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /packages/docs/src/.q-press/assets/get-meta.ts: -------------------------------------------------------------------------------- 1 | export default function getMeta(title: string, desc: string) { 2 | return { 3 | title: { 4 | name: 'title', 5 | content: title, 6 | }, 7 | ogTitle: { 8 | name: 'og:title', 9 | content: title, 10 | }, 11 | twitterTitle: { 12 | name: 'twitter:title', 13 | content: title, 14 | }, 15 | 16 | description: { 17 | name: 'description', 18 | content: desc, 19 | }, 20 | ogDesc: { 21 | name: 'og:description', 22 | content: desc, 23 | }, 24 | twitterDesc: { 25 | name: 'twitter:description', 26 | content: desc, 27 | }, 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/docs/src/.q-press/components/MarkdownCardLink.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 20 | 21 | 26 | -------------------------------------------------------------------------------- /packages/docs/src/.q-press/components/MarkdownCardTitle.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 28 | -------------------------------------------------------------------------------- /packages/docs/src/.q-press/components/MarkdownCode.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 32 | -------------------------------------------------------------------------------- /packages/docs/src/.q-press/components/MarkdownCodePrism.ts: -------------------------------------------------------------------------------- 1 | import Prism from 'prismjs' 2 | import { h, computed, defineComponent, type PropType } from 'vue' 3 | 4 | export default defineComponent({ 5 | name: 'MarkdownCodePrism', 6 | 7 | props: { 8 | code: { 9 | type: String as PropType, 10 | required: true, 11 | }, 12 | lang: { 13 | type: String as PropType, 14 | required: true, 15 | }, 16 | }, 17 | 18 | setup(props) { 19 | const html = computed(() => { 20 | if (!props.code || !props.lang) { 21 | return '' 22 | } 23 | 24 | return Prism.highlight(props.code, Prism.languages[props.lang] as Prism.Grammar, props.lang) 25 | }) 26 | 27 | return () => 28 | h( 29 | 'pre', 30 | { 31 | class: `markdown-code language-${props.lang}`, 32 | }, 33 | [h('code', { innerHTML: html.value })], 34 | ) 35 | }, 36 | }) 37 | -------------------------------------------------------------------------------- /packages/docs/src/.q-press/components/MarkdownLink.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 20 | 21 | 39 | -------------------------------------------------------------------------------- /packages/docs/src/.q-press/composables/dark.ts: -------------------------------------------------------------------------------- 1 | import { useQuasar } from 'quasar' 2 | import { useMarkdownStore } from '../stores/markdown' 3 | import { computed, watch } from 'vue' 4 | 5 | export function useDark() { 6 | const $q = useQuasar() 7 | const markdownStore = useMarkdownStore() 8 | 9 | const isDark = computed(() => markdownStore.dark) 10 | 11 | function initDark() { 12 | markdownStore.dark = $q.cookies.get('theme') !== 'light' 13 | $q.dark.set(markdownStore.dark) 14 | } 15 | 16 | function toggleDark() { 17 | $q.dark.toggle() 18 | markdownStore.dark = $q.dark.isActive 19 | 20 | $q.cookies.set('theme', markdownStore.dark ? 'dark' : 'light', { 21 | path: '/', 22 | sameSite: 'Strict', 23 | expires: 400, 24 | }) 25 | } 26 | 27 | watch( 28 | () => markdownStore.dark, 29 | (val) => { 30 | $q.dark.set(val) 31 | }, 32 | ) 33 | 34 | return { 35 | isDark, 36 | initDark, 37 | toggleDark, 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /packages/docs/src/.q-press/css/themes/default.scss: -------------------------------------------------------------------------------- 1 | @use 'sass:color'; 2 | 3 | $primary: #214466; 4 | $secondary: #266660; 5 | $accent: #853394; 6 | 7 | $positive: #2ecc71; 8 | $negative: #ff1732; 9 | $info: #10a0ff; 10 | $warning: #ffd52d; 11 | 12 | $brand-primary: #00bfff; 13 | $brand-secondary: #4b555c; 14 | $brand-accent: #ea5e13; 15 | $brand-dark: #2c3e50; 16 | $brand-light: #f5f5f5; 17 | $brand-medium: #6b7f86; 18 | $brand-light-text: #4d4d4d; 19 | $brand-light-bg: #fefefe; 20 | $brand-dark-bg: #080e1a; 21 | $brand-dark-text: #cbcbcb; 22 | $brand-light-codeblock-bg: #f5f5f5; 23 | $brand-light-codeblock-text: #4d4d4d; 24 | $brand-dark-codeblock-bg: #121212; 25 | $brand-dark-codeblock-text: #e6e6e6; 26 | 27 | $header-btn-color--light: #757575; 28 | $header-btn-hover-color--light: #212121; 29 | $header-btn-color--dark: #929397; 30 | $header-btn-hover-color--dark: #fff; 31 | 32 | $light-pill: $brand-light; 33 | $light-text: $brand-light-text; 34 | $light-bg: $brand-light-bg; 35 | 36 | $dark-pill: scale-color($brand-primary, $lightness: -80%); 37 | $dark-text: $brand-dark-text; 38 | $dark-bg: $brand-dark-bg; 39 | 40 | $separator-color: $brand-accent; 41 | $separator-color-dark: $brand-accent; 42 | 43 | $font-size: 16px; 44 | $font-size-brand: 16px; 45 | $font-weight-brand: 500; 46 | $font-weight-technical: 400; 47 | $letter-spacing-brand: 0.7px; 48 | 49 | $font-family-technical: 50 | 'Roboto', 51 | -apple-system, 52 | Avenir, 53 | BlinkMacSystemFont, 54 | 'Segoe UI', 55 | Helvetica, 56 | Arial, 57 | sans-serif; 58 | $font-family-examples: $font-family-technical; 59 | $font-family-brand: 'Montserrat', $font-family-technical; 60 | 61 | $shadow--large: 0 24px 24px 0 rgba(0, 179, 255, 0.24); 62 | $shadow--medium: 0 6px 6px 0 rgba($brand-primary, 0.38); 63 | $shadow--small: 0 6px 6px 0 rgba($brand-primary, 0.28); 64 | 65 | // also update QHeader :height-hint 66 | $header-height: 55px; 67 | $header-transition: 0.6s cubic-bezier(0.25, 0.8, 0.5, 1); 68 | $header-quick-transition: 0.28s ease-in-out; 69 | -------------------------------------------------------------------------------- /packages/docs/src/.q-press/css/themes/newspaper.scss: -------------------------------------------------------------------------------- 1 | @use 'sass:color'; 2 | 3 | // Newspaper Theme Variables 4 | $primary: #000000; 5 | $secondary: #333333; 6 | $accent: #666666; 7 | 8 | $positive: #2ecc71; 9 | $negative: #ff1732; 10 | $info: #10a0ff; 11 | $warning: #ffd52d; 12 | 13 | $brand-primary: #8793fc; 14 | $brand-secondary: #333333; 15 | $brand-accent: #666666; 16 | $brand-dark: #000000; 17 | $brand-light: #ffffff; 18 | $brand-medium: #808080; 19 | $brand-light-text: #333333; 20 | $brand-light-bg: #f5f5f5; 21 | $brand-dark-bg: #000000; 22 | $brand-dark-text: #ffffff; 23 | $brand-light-codeblock-bg: #f5f5f5; 24 | $brand-light-codeblock-text: #333333; 25 | $brand-dark-codeblock-bg: #1a1a1a; 26 | $brand-dark-codeblock-text: #e6e6e6; 27 | 28 | $header-btn-color--light: #4d4d4d; 29 | $header-btn-hover-color--light: #1a1a1a; 30 | $header-btn-color--dark: #999999; 31 | $header-btn-hover-color--dark: #cccccc; 32 | 33 | $light-pill: $brand-light; 34 | $light-text: $brand-light-text; 35 | $light-bg: $brand-light-bg; 36 | 37 | $dark-pill: scale-color($brand-primary, $lightness: -60%); 38 | $dark-text: $brand-dark-text; 39 | $dark-bg: $brand-dark-bg; 40 | 41 | $separator-color: $brand-accent; 42 | $separator-color-dark: $brand-accent; 43 | 44 | $font-size: 16px; 45 | $font-size-brand: 16px; 46 | $font-weight-brand: 500; 47 | $font-weight-technical: 400; 48 | $letter-spacing-brand: 0.7px; 49 | 50 | $font-family-technical: 51 | 'Roboto', 52 | -apple-system, 53 | Avenir, 54 | BlinkMacSystemFont, 55 | 'Segoe UI', 56 | Helvetica, 57 | Arial, 58 | sans-serif; 59 | $font-family-examples: $font-family-technical; 60 | $font-family-brand: 'Montserrat', $font-family-technical; 61 | 62 | $shadow--large: 0 24px 24px 0 rgba(0, 179, 255, 0.24); 63 | $shadow--medium: 0 6px 6px 0 rgba($brand-primary, 0.38); 64 | $shadow--small: 0 6px 6px 0 rgba($brand-primary, 0.28); 65 | 66 | // also update QHeader :height-hint 67 | $header-height: 55px; 68 | $header-transition: 0.6s cubic-bezier(0.25, 0.8, 0.5, 1); 69 | $header-quick-transition: 0.28s ease-in-out; 70 | -------------------------------------------------------------------------------- /packages/docs/src/.q-press/css/themes/sunrise.scss: -------------------------------------------------------------------------------- 1 | @use 'sass:color'; 2 | 3 | // Sunrise Theme Variables 4 | $primary: #e74c3c; 5 | $secondary: #8e44ad; 6 | $accent: #f39c12; 7 | 8 | $positive: #2ecc71; 9 | $negative: #ff1732; 10 | $info: #10a0ff; 11 | $warning: #ffd52d; 12 | 13 | $brand-primary: #e74c3c; 14 | $brand-secondary: #5186bb; 15 | $brand-accent: #f39c12; 16 | $brand-dark: #2c3e50; 17 | $brand-light: #ecf0f1; 18 | $brand-medium: #95a5a6; 19 | $brand-light-text: #2c3e50; 20 | $brand-light-bg: #ecf0f1; 21 | $brand-dark-bg: #34495e; 22 | $brand-dark-text: #ecf0f1; 23 | $brand-light-codeblock-bg: #ecf0f1; 24 | $brand-light-codeblock-text: #2c3e50; 25 | $brand-dark-codeblock-bg: #2c3e50; 26 | $brand-dark-codeblock-text: #ecf0f1; 27 | 28 | $header-btn-color--light: #c0392b; 29 | $header-btn-hover-color--light: #e74c3c; 30 | $header-btn-color--dark: #c0392b; 31 | $header-btn-hover-color--dark: #e74c3c; 32 | 33 | $light-pill: $brand-light; 34 | $light-text: $brand-light-text; 35 | $light-bg: $brand-light-bg; 36 | 37 | $dark-pill: scale-color($brand-dark, $lightness: 20%); 38 | $dark-text: $brand-dark-text; 39 | $dark-bg: $brand-dark-bg; 40 | 41 | $separator-color: $brand-accent; 42 | $separator-color-dark: $brand-accent; 43 | 44 | $font-size: 16px; 45 | $font-size-brand: 16px; 46 | $font-weight-brand: 500; 47 | $font-weight-technical: 400; 48 | $letter-spacing-brand: 0.7px; 49 | 50 | $font-family-technical: 51 | 'Roboto', 52 | -apple-system, 53 | Avenir, 54 | BlinkMacSystemFont, 55 | 'Segoe UI', 56 | Helvetica, 57 | Arial, 58 | sans-serif; 59 | $font-family-examples: $font-family-technical; 60 | $font-family-brand: 'Montserrat', $font-family-technical; 61 | 62 | $shadow--large: 0 24px 24px 0 rgba(0, 179, 255, 0.24); 63 | $shadow--medium: 0 6px 6px 0 rgba($brand-primary, 0.38); 64 | $shadow--small: 0 6px 6px 0 rgba($brand-primary, 0.28); 65 | 66 | // also update QHeader :height-hint 67 | $header-height: 55px; 68 | $header-transition: 0.6s cubic-bezier(0.25, 0.8, 0.5, 1); 69 | $header-quick-transition: 0.28s ease-in-out; 70 | -------------------------------------------------------------------------------- /packages/docs/src/.q-press/css/themes/tawny.scss: -------------------------------------------------------------------------------- 1 | @use 'sass:color'; 2 | 3 | // Tawny Theme Variables 4 | $primary: #8b4513; 5 | $secondary: #a0522d; 6 | $accent: #d2691e; 7 | 8 | $positive: #2ecc71; 9 | $negative: #ff1732; 10 | $info: #10a0ff; 11 | $warning: #ffd52d; 12 | 13 | $brand-primary: #8b4513; 14 | $brand-secondary: #a0522d; 15 | $brand-accent: #d2691e; 16 | $brand-dark: #5c4033; 17 | $brand-light: #f5f5dc; 18 | $brand-medium: #c19a6b; 19 | $brand-light-text: #5c4033; 20 | $brand-light-bg: #f5f5dc; 21 | $brand-dark-bg: #3e2723; 22 | $brand-dark-text: #f5f5dc; 23 | $brand-light-codeblock-bg: #fdfdfd; 24 | $brand-light-codeblock-text: #5c4033; 25 | $brand-dark-codeblock-bg: #5c4033; 26 | $brand-dark-codeblock-text: #f5f5dc; 27 | 28 | $header-btn-color--light: #8b4513; 29 | $header-btn-hover-color--light: #a0522d; 30 | $header-btn-color--dark: #d2691e; 31 | $header-btn-hover-color--dark: #cd853f; 32 | 33 | $light-pill: $brand-light; 34 | $light-text: $brand-light-text; 35 | $light-bg: $brand-light-bg; 36 | 37 | $dark-pill: scale-color($brand-primary, $lightness: -80%); 38 | $dark-text: $brand-dark-text; 39 | $dark-bg: $brand-dark-bg; 40 | 41 | $separator-color: $brand-accent; 42 | $separator-color-dark: $brand-accent; 43 | 44 | $font-size: 16px; 45 | $font-size-brand: 16px; 46 | $font-weight-brand: 500; 47 | $font-weight-technical: 400; 48 | $letter-spacing-brand: 0.7px; 49 | 50 | $font-family-technical: 51 | 'Roboto', 52 | -apple-system, 53 | Avenir, 54 | BlinkMacSystemFont, 55 | 'Segoe UI', 56 | Helvetica, 57 | Arial, 58 | sans-serif; 59 | $font-family-examples: $font-family-technical; 60 | $font-family-brand: 'Montserrat', $font-family-technical; 61 | 62 | $shadow--large: 0 24px 24px 0 rgba(0, 179, 255, 0.24); 63 | $shadow--medium: 0 6px 6px 0 rgba($brand-primary, 0.38); 64 | $shadow--small: 0 6px 6px 0 rgba($brand-primary, 0.28); 65 | 66 | // also update QHeader :height-hint 67 | $header-height: 55px; 68 | $header-transition: 0.6s cubic-bezier(0.25, 0.8, 0.5, 1); 69 | $header-quick-transition: 0.28s ease-in-out; 70 | -------------------------------------------------------------------------------- /packages/docs/src/.q-press/layouts/MarkdownDrawerSidebar.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | 33 | -------------------------------------------------------------------------------- /packages/docs/src/.q-press/layouts/MarkdownDrawerToc.vue: -------------------------------------------------------------------------------- 1 | 28 | 29 | 38 | -------------------------------------------------------------------------------- /packages/docs/src/.q-press/layouts/MarkdownHeaderIconLinks.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 37 | -------------------------------------------------------------------------------- /packages/docs/src/.q-press/layouts/MarkdownHeaderTextLinks.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 47 | -------------------------------------------------------------------------------- /packages/docs/src/.q-press/layouts/MarkdownPageSidebar.scss: -------------------------------------------------------------------------------- 1 | .markdown-page-menu { 2 | font-size: ($font-size - 2px); 3 | 4 | .q-icon { 5 | font-size: 24px; 6 | } 7 | 8 | .q-item__section--avatar { 9 | color: $brand-primary; 10 | min-width: 28px; 11 | padding-right: 12px; 12 | } 13 | 14 | .q-expansion-item__content { 15 | margin-left: 18px; 16 | padding-left: 4px; 17 | border-left: 1px solid $separator-color; 18 | 19 | .q-expansion-item__content { 20 | margin-left: 26px; 21 | padding-left: 2px !important; 22 | 23 | .q-item { 24 | padding-left: 16px !important; 25 | margin-left: 2px; 26 | } 27 | } 28 | } 29 | 30 | .q-expansion-item__toggle-icon { 31 | color: $grey-5; 32 | } 33 | 34 | .q-expansion-item--expanded > div > .q-item { 35 | > .q-item__section--main { 36 | color: $brand-primary; 37 | } 38 | > .q-item__section--side .q-expansion-item__toggle-icon { 39 | color: $brand-primary; 40 | } 41 | } 42 | 43 | &__deep-expansion > .q-expansion-item__container > .q-item { 44 | .q-item__section--avatar { 45 | min-width: 16px; 46 | padding-left: 8px; 47 | padding-right: 0; 48 | } 49 | } 50 | } 51 | 52 | body.body--dark .markdown-page-menu .q-expansion-item__content { 53 | border-left-color: $separator-dark-color; 54 | } 55 | -------------------------------------------------------------------------------- /packages/docs/src/.q-press/layouts/MarkdownPageToc.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 24 | -------------------------------------------------------------------------------- /packages/docs/src/App.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 24 | -------------------------------------------------------------------------------- /packages/docs/src/boot/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/src/boot/.gitkeep -------------------------------------------------------------------------------- /packages/docs/src/components/NavigationBar.vue: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /packages/docs/src/css/app.scss: -------------------------------------------------------------------------------- 1 | // app global css in SCSS form 2 | @import '../.q-press/css/app.scss'; 3 | @import '../.q-press/css/fonts.scss'; 4 | @import '../.q-press/css/prism-theme.scss'; 5 | 6 | @import 'quasar/src/css/variables.sass'; 7 | 8 | .subcontent { 9 | display: flex; 10 | flex-direction: column; 11 | justify-content: start; 12 | width: 100%; 13 | margin: 0 6px 6px 6px; 14 | } 15 | 16 | .list-item { 17 | text-align: left; 18 | justify-content: flex-start; 19 | margin: 2px; 20 | text-decoration: none; 21 | display: block; 22 | padding: 2px 4px; 23 | border: 1px solid #007bff; 24 | border-radius: 4px; 25 | background-color: #007bff; 26 | color: white; 27 | cursor: pointer; 28 | transition: 29 | background-color 0.3s, 30 | border-color 0.3s; 31 | 32 | &:hover { 33 | background-color: #0056b3; 34 | border-color: #0056b3; 35 | } 36 | 37 | &:active { 38 | background-color: #004085; 39 | border-color: #004085; 40 | } 41 | } 42 | 43 | .line { 44 | line-height: 1.58em; 45 | margin-top: 8px; 46 | margin-bottom: 4px; 47 | text-align: center; 48 | } 49 | 50 | .highlight { 51 | box-shadow: inset 0 0 0 1px rgba(0, 191, 255, 0.85) !important; 52 | min-height: 6px !important; 53 | padding: 1px !important; 54 | transition: box-shadow 0.3s ease; 55 | } 56 | 57 | .anatomy { 58 | .q-item { 59 | border-radius: 8px; 60 | } 61 | 62 | .q-item--active { 63 | color: #00bfff !important; 64 | transition: 65 | color 0.3s ease, 66 | background-color 0.3s ease; 67 | } 68 | } 69 | 70 | .q-dark div, 71 | .body--dark div { 72 | .highlight { 73 | box-shadow: inset 0 0 0 1px rgba(238, 255, 0, 0.65) !important; 74 | min-height: 6px !important; 75 | padding: 1px !important; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /packages/docs/src/css/quasar.variables.scss: -------------------------------------------------------------------------------- 1 | // Quasar SCSS (& Sass) Variables 2 | // -------------------------------------------------- 3 | // To customize the look and feel of this app, you can override 4 | // the Sass/SCSS variables found in Quasar's source Sass/SCSS files. 5 | 6 | // Check documentation for full list of Quasar variables 7 | 8 | // Your own variables (that are declared here) and Quasar's own 9 | // ones will be available out of the box in your .vue/.scss/.sass files 10 | 11 | // It's highly recommended to change the default colors 12 | // to match your app's branding. 13 | // Tip: Use the "Theme Builder" on Quasar's documentation website. 14 | 15 | $primary: #1976d2; 16 | $secondary: #26a69a; 17 | $accent: #9c27b0; 18 | 19 | $dark: #1d1d1d; 20 | $dark-page: #121212; 21 | 22 | $positive: #21ba45; 23 | $negative: #c10015; 24 | $info: #31ccec; 25 | $warning: #f2c037; 26 | 27 | @import '../.q-press/css/themes/default.scss'; 28 | -------------------------------------------------------------------------------- /packages/docs/src/env.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace NodeJS { 2 | interface ProcessEnv { 3 | NODE_ENV: string 4 | VUE_ROUTER_MODE: 'hash' | 'history' | 'abstract' | undefined 5 | VUE_ROUTER_BASE: string | undefined 6 | } 7 | } 8 | 9 | declare module '@carbon/icons-vue/es/checkbox/16' 10 | declare module '@carbon/icons-vue/es/checkbox/24' 11 | declare module '@carbon/icons-vue/es/checkbox--checked/16' 12 | declare module '@carbon/icons-vue/es/checkbox--checked/24' 13 | declare module '@carbon/icons-vue/es/location/16' 14 | declare module '@carbon/icons-vue/es/email/16' 15 | declare module '@carbon/icons-vue/es/phone/16' 16 | declare module '@carbon/icons-vue/es/construction/16' 17 | declare module '@carbon/icons-vue/es/calendar/16' 18 | declare module '@carbon/icons-vue/es/currency--dollar/16' 19 | declare module '@carbon/icons-vue/es/alarm/16' 20 | declare module '@carbon/icons-vue/es/add--alt/16' 21 | declare module '@carbon/icons-vue/es/checkmark--outline/16' 22 | declare module '@carbon/icons-vue/es/pending/16' 23 | declare module '@carbon/icons-vue/es/undefined/16' 24 | -------------------------------------------------------------------------------- /packages/docs/src/examples/QAvatar/BasicExample.vue: -------------------------------------------------------------------------------- 1 | 12 | -------------------------------------------------------------------------------- /packages/docs/src/examples/listing.ts: -------------------------------------------------------------------------------- 1 | // used by routes.js; 2 | // placing it here to generate shorter string lengths as keys 3 | export default import.meta.glob('./**/*.vue') 4 | -------------------------------------------------------------------------------- /packages/docs/src/markdown/developing/faq.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: FAQ 3 | desc: Knowledge is Power 4 | examples: Faq 5 | --- 6 | 7 | Here you will find useful bespoke information on how to use the calendars. These mainly come as a result from question in the issues. 8 | 9 | ## Month (Sticky Header) 10 | 11 | In this example, check out the custom `.my-sticky` css class. This works in conjunction with a parent whose height is horter than the height needed to display the calendar and setting it's style to `overflow: auto`. 12 | 13 | 14 | 15 | ## Month (Show Month) 16 | 17 | In this example, it shows how you can display the currently displayed month and year. It uses the browser's `Intl.DateTimeFormat` to do the formatting. 18 | 19 | 20 | 21 | ## Month (Min. Weeks) 22 | 23 | In this example, it shows how you can display the minimum number of weeks displayed in a month. The reason form doing this is to make sure the calendar is always the same height. 24 | 25 | 26 | -------------------------------------------------------------------------------- /packages/docs/src/markdown/developing/qcalendar-day-intervals.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: QCalendarDay (Intervals) 3 | desc: Developing with QCalendarDay 4 | examples: Intervals 5 | --- 6 | 7 | 10 | 11 | 12 | 13 | ## Month Cell Width 14 | 15 | 16 | 17 | ## Month Navigation 18 | 19 | 20 | -------------------------------------------------------------------------------- /packages/docs/src/markdown/developing/qcalendar.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: QCalendar 3 | desc: Developing with QCalendar 4 | examples: General 5 | --- 6 | 7 | The QCalendar component is a wrapper around all other calendar components. It can take the same properties and has all the same slots -- combined. There are some edge-cases where this would be useful, but in general, avoid using it. Because it wraps ALL calendars, you will get no tree-shaking benefits. 8 | 9 | ::: warning 10 | Use the QCalendar (wrapper) only if necessary. By using this component, all calendar components will be loaded whether you use them or not. 11 | ::: 12 | 13 | It has one additional property to specify what determines the calendar type to be displayed. 14 | 15 | | Property | Type | Example | 16 | | -------- | ------ | ------- | 17 | | mode | String | day | 18 | 19 | Available values are: `day` (default), `month`, `agenda`, `resource`, `scheduler`, and `task`. 20 | 21 | When using multi-calendars in this way, be sure to guard your slots to avoid errors and issues. For instance, the `footer-task` slot would get an error as an invalid slot for month mode. You can gaurd like this: 22 | 23 | ```html 24 | 30 | ``` 31 | 32 | 35 | 36 | 37 | 38 | ## All 39 | 40 | 41 | -------------------------------------------------------------------------------- /packages/docs/src/markdown/developing/timestamp.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Timestamp 3 | desc: Developing with Timestamp 4 | --- 5 | 6 | **Timestamp** is the low-level API that QCalendar uses internally to manipulate calendars. We have made it into its own package so you can use it if you wish. 7 | 8 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /packages/docs/src/markdown/getting-started/anatomy-of-a-calendar.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Anatomy of a Calendar 3 | desc: Identify the parts of a Calendar 4 | keys: All about QCalendar 5 | --- 6 | 7 | Make a selection on the left of a calendar to see the result on the right. This will show you the available slots and where they are applied. 8 | 9 | ::: warning 10 | Some selections may not show up correctly because of `sticky` being used, which causes the sticky section to be above the highlighted area. 11 | ::: 12 | 13 | ## QCalendarDay 14 | 15 | 18 | 19 | 20 | ## QCalendarDay (week) 21 | 22 | 25 | 26 | 27 | ## QCalendarMonth 28 | 29 | 32 | 33 | 34 | ## QCalendarMonth (mini-mode) 35 | 36 | 39 | 40 | 41 | ## QCalendarScheduler 42 | 43 | 46 | 47 | 48 | ## QCalendarResource 49 | 50 | 53 | 54 | 55 | ## QCalendarAgenda 56 | 57 | 60 | 61 | 62 | ## QCalendarTask 63 | 64 | 67 | 68 | -------------------------------------------------------------------------------- /packages/docs/src/markdown/getting-started/themes.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Themes 3 | desc: Enhancing the looks of your calendar 4 | keys: Designing with QCalendar 5 | --- 6 | 7 | Themes are an additional way for you to have control over the way your calendar looks. This is done with [CSS custom properties (variables)](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties). CSS custom properties are part of modern web programming. For the most part, a lot of the CSS custom properties used by QCalendar are general in nature. Meaning, they are used by all calendar modes. 8 | 9 | Most of the CSS custom properties are just for color (both background and text), while others are for borders with color, and some are for other miscellaneous, like width or font size. Out of the colored-based ones, they are in pairs: One for browser [Dark Mode](https://css-tricks.com/a-complete-guide-to-dark-mode-on-the-web/) and the other for normal operational mode. 10 | 11 | All the available properties are available in the [Theme Builder](/theme-builder). 12 | 13 | The Theme Builder editors know what should be edited, but they don't prevent you from making errors or mistakes in design. For instance, one thing you can do but may have undesirable results is if you change border widths. This is not recommended. -------------------------------------------------------------------------------- /packages/docs/src/markdown/getting-started/transitions.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: QCalendar Transitions 3 | desc: Using QCalendar Transitions 4 | keys: All about QCalendar 5 | --- 6 | 7 | Transitions allow your calendar component to be animated when the view changes (ie: next/prev day, week, month, etc). It is turned on using the `animated` property and works in conjunction with the `transiton-prev` and `transiton-next` properties. 8 | 9 | To use transitions, you must include the `QCalendarTransitions.scss` or `QCalendarTransitions.css`, depending on your needs. 10 | 11 | In your sass file: 12 | 13 | ```js 14 | @import '@quasar/quasar-ui-qcalendar/src/QCalendarTransitions.scss' 15 | ``` 16 | 17 | In your Vue file (in a script section): 18 | 19 | ```js 20 | import '@quasar/quasar-ui-qcalendar/QCalendarTransitions.css' 21 | ``` 22 | 23 | ## Transitions 24 | 25 | Transitions are a way to make your calendar come alive for your end-user. When a calendar changes to a previous or next week/month, instead of just instantly displaying it, we can use the `animated` property to turn on transitions. 26 | 27 | | Property | Type | Example | 28 | | -------- | ------- | ------- | 29 | | animated | Boolean | | 30 | 31 | Then you can use the `transiton-prev` and `transiton-next` properties to change the default behavior, which is `slide-right` and `slide-left`, respectively. 32 | 33 | | Property | Type | Example | 34 | | -------------- | ------ | --------------------- | 35 | | transiton-prev | String | slide-right (default) | 36 | | transiton-next | String | slide-left (default) | 37 | 38 | ### Transitions types 39 | 40 | QCalendar supports the following transition types: 41 | 42 | | Roll | Slide | Jump | Misc | 43 | | ---------- | ----------- | ---------- | ------ | 44 | | roll-right | slide-right | jump-right | fade | 45 | | roll-left | slide-left | jump-left | scale | 46 | | roll-up | slide-up | jump-up | rotate | 47 | | roll-down | slide-down | jump-down | spin | 48 | | | | | flip | 49 | -------------------------------------------------------------------------------- /packages/docs/src/markdown/guides/release-notes.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/src/markdown/guides/release-notes.md -------------------------------------------------------------------------------- /packages/docs/src/markdown/guides/style-guide.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/docs/src/markdown/guides/style-guide.md -------------------------------------------------------------------------------- /packages/docs/src/markdown/landing-page.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: QCalendar | Build Beautiful, Responsive Calendars for Vue and Quasar 3 | desc: QCalendar 4 | editLink: false 5 | --- 6 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /packages/docs/src/markdown/listing.ts: -------------------------------------------------------------------------------- 1 | // used by routes.js; 2 | // placing it here to generate shorter string lengths as keys 3 | export default import.meta.glob('./**/*.md') 4 | -------------------------------------------------------------------------------- /packages/docs/src/markdown/other/contact.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Contact 3 | desc: Contacting us 4 | keys: Help 5 | --- 6 | 7 | Have a question about QCalendar? We're here to help. Before you start, be sure to check the following resources to see if your topic has already been covered. 8 | 9 | ## Check existing resources 10 | 11 | ### QCalendar GitHub issues 12 | 13 | As a first step, it's always good to search open and closed issues on the QCalendar [GitHub repo](https://github.com/quasarframework/quasar-ui-qcalendar/tree/dev). 14 | 15 | ### QCalendar GitHub discussions 16 | 17 | Don't forget to look into the [GitHub Discussions](https://github.com/quasarframework/quasar-ui-qcalendar/discussions). 18 | 19 | ## Provide a suggestion/contribution 20 | 21 | ### GitHub issues 22 | 23 | File on the [GitHub Issues](https://github.com/quasarframework/quasar-ui-qcalendar/issues) location. 24 | 25 | ### GitHub pull requests (PR) 26 | 27 | If you have a specific fix or contribution, you can generate a pull request on the [QCalendar repo](https://github.com/quasarframework/quasar-ui-qcalendar/tree/dev). 28 | 29 | ## Start a discussion 30 | 31 | ### GitHub discussions 32 | 33 | If it's not an issue, bug, or feature request, you can use the [GitHub Discussions](https://github.com/quasarframework/quasar-ui-qcalendar/discussions) to ask questions. 34 | 35 | ### Discord 36 | 37 | Use the [Quasar Discord](https://chat.quasar.dev) and head to the `#app-extensions` channel. 38 | 39 | ### Twitter 40 | 41 | The creator/maintainer of QCalendar can be contacted on Twitter: [@jgalbraith64](https://twitter.com/jgalbraith64). 42 | -------------------------------------------------------------------------------- /packages/docs/src/markdown/other/contributing/bugs-and-feature-requests.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Bugs and Feature Requests 3 | desc: 4 | keys: Contributing 5 | --- 6 | 7 | ## Checking for known issues 8 | 9 | ### GitHub 10 | 11 | We use GitHub to track our bugs. If you have a bug to report or wish to request a new feature, please check the [existing issues](https://github.com/quasarframework/quasar-ui-qcalendar/issues) before opening a new one. There may already be something similar in the works. 12 | 13 | ### QCalendar website 14 | 15 | Please take some time to explore the content on this website before opening an issue. The site is comprehensive and most guidelines and components are well documented. 16 | 17 | ## Creating an issue 18 | 19 | Report bugs, request features and leave feedback with a [GitHub issue](https://github.com/quasarframework/quasar-ui-qcalendar/issues). 20 | 21 | ## GitHub pull requests 22 | 23 | If you have a specific fix or contribution, start by generating a pull request in the appropriate [QCalendar repo](https://github.com/quasarframework/quasar-ui-qcalendar/pulls). 24 | 25 | ## Requests for comment 26 | 27 | For changes that are larger in scale, an RFC (request for comment) may be appropriate. You can do that in the [QCalendar discussions](https://github.com/quasarframework/quasar-ui-qcalendar/discussions). 28 | 29 | ## Need more help? 30 | 31 | If you have more questions about issues or requesting features, there are multiple ways to reach us at [Contact us](/help/contact-us). 32 | -------------------------------------------------------------------------------- /packages/docs/src/markdown/other/contributing/call-to-action.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Call to Action 3 | desc: Things that need help from the community 4 | keys: Contributing 5 | --- 6 | 7 | ## Helping out 8 | 9 | This **Call to action** page is where items can be listed where community involvement will be greatly appreciated. In this respect, so that more time can be devoted to the components and not the docs site. If you take something on, please coordinate in the [Discussions](https://github.com/quasarframework/quasar-ui-qcalendar/discussions) area so there are not duplicated efforts. 10 | 11 | ### Docs site 12 | 13 | The Docs site has several empty pages that need to be filled in. If you think you are up to it, pick one and help out. 14 | 15 | In particular, all of the "Getting started" pages (one for each calendar type) need info after the API display component. 16 | 17 | ### Testing 18 | 19 | Only the Timestamp library has some Jest testing done on it. It'd be very welcomed if someone could write up tests for the UI components. 20 | 21 | ### JSON API 22 | 23 | Each calendar component, as well as the Timestamp library, has an associated JSON file. Except for the Timestamp one, they are all missing functionality that needs to be added or updated and reviewed. 24 | 25 | ### Examples 26 | 27 | A lot of the examples (in the `examples` folder) have been converted to Vue Composition API, and better yet, to use ` 28 | -------------------------------------------------------------------------------- /packages/docs/src/q-press.globals.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.md' 2 | 3 | // Define types for headers 4 | interface TocMenuItem { 5 | id: string 6 | level: number 7 | title: string 8 | link?: string 9 | deep?: boolean 10 | sub?: boolean 11 | onClick?: () => void 12 | children?: TocMenuItem[] 13 | } 14 | 15 | // Define types for Markdown modules 16 | interface MarkdownModule { 17 | title?: string 18 | headers?: TocMenuItem[] 19 | frontmatter?: Record 20 | filename?: string 21 | render: (..._args: unknown[]) => unknown 22 | } 23 | 24 | // Define types for menu items 25 | interface MenuItem { 26 | name: string 27 | path?: string 28 | icon?: string 29 | iconColor?: string 30 | rightIcon?: string 31 | rightIconColor?: string 32 | badge?: string 33 | children?: MenuItem[] | undefined 34 | external?: boolean 35 | expanded?: boolean 36 | } 37 | -------------------------------------------------------------------------------- /packages/docs/src/router/index.ts: -------------------------------------------------------------------------------- 1 | import { defineRouter } from '#q-app/wrappers' 2 | import { 3 | createMemoryHistory, 4 | createRouter, 5 | createWebHashHistory, 6 | createWebHistory, 7 | } from 'vue-router' 8 | import routes from './routes' 9 | 10 | /* 11 | * If not building with SSR mode, you can 12 | * directly export the Router instantiation; 13 | * 14 | * The function below can be async too; either use 15 | * async/await or return a Promise which resolves 16 | * with the Router instance. 17 | */ 18 | 19 | export default defineRouter(function (/* { store, ssrContext } */) { 20 | const createHistory = process.env.SERVER 21 | ? createMemoryHistory 22 | : process.env.VUE_ROUTER_MODE === 'history' 23 | ? createWebHistory 24 | : createWebHashHistory 25 | 26 | const Router = createRouter({ 27 | scrollBehavior: () => ({ left: 0, top: 0 }), 28 | /// @ts-expect-error later 29 | routes, 30 | 31 | // Leave this as is and make changes in quasar.conf.js instead! 32 | // quasar.conf.js -> build -> vueRouterMode 33 | // quasar.conf.js -> build -> publicPath 34 | history: createHistory(process.env.VUE_ROUTER_BASE), 35 | }) 36 | 37 | return Router 38 | }) 39 | -------------------------------------------------------------------------------- /packages/docs/src/stores/index.ts: -------------------------------------------------------------------------------- 1 | import { defineStore } from '#q-app/wrappers' 2 | import { createPinia } from 'pinia' 3 | 4 | /* 5 | * When adding new properties to stores, you should also 6 | * extend the `PiniaCustomProperties` interface. 7 | * @see https://pinia.vuejs.org/core-concepts/plugins.html#typing-new-store-properties 8 | */ 9 | declare module 'pinia' { 10 | // eslint-disable-next-line @typescript-eslint/no-empty-object-type 11 | export interface PiniaCustomProperties { 12 | // add your custom properties here, if any 13 | } 14 | } 15 | 16 | /* 17 | * If not building with SSR mode, you can 18 | * directly export the Store instantiation; 19 | * 20 | * The function below can be async too; either use 21 | * async/await or return a Promise which resolves 22 | * with the Store instance. 23 | */ 24 | 25 | export default defineStore((/* { ssrContext } */) => { 26 | const pinia = createPinia() 27 | 28 | // You can add Pinia plugins here 29 | // pinia.use(SomePiniaPlugin) 30 | 31 | return pinia 32 | }) 33 | -------------------------------------------------------------------------------- /packages/docs/src/util/getLocale.js: -------------------------------------------------------------------------------- 1 | export const getLocale = () => { 2 | if (navigator.languages && navigator.languages.length > 0) { 3 | return navigator.languages[0] 4 | } else { 5 | return navigator.userLanguages || navigator.language || navigator.browserLanguages || 'en-US' 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/docs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./.quasar/tsconfig.json", 3 | "compilerOptions": { 4 | "resolveJsonModule": true 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /packages/ui/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["@babel/plugin-syntax-dynamic-import"], 3 | "env": { 4 | "test": { 5 | "plugins": ["dynamic-import-node"], 6 | "presets": [ 7 | [ 8 | "@babel/preset-env", 9 | { 10 | "modules": "commonjs", 11 | "targets": { 12 | "node": "current" 13 | } 14 | } 15 | ] 16 | ] 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/ui/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /packages/ui/.gitignore: -------------------------------------------------------------------------------- 1 | # Testing 2 | /test/jest/coverage 3 | 4 | ui/node_modules 5 | ui/dev/yarn.lock 6 | ui/dev/node_modules 7 | 8 | demo/node_modules 9 | 10 | ./dist 11 | -------------------------------------------------------------------------------- /packages/ui/.npmignore: -------------------------------------------------------------------------------- 1 | /build 2 | /dev 3 | umd-test.html 4 | 5 | .DS_Store 6 | .thumbs.db 7 | yarn.lock 8 | npm-debug.log* 9 | yarn-debug.log* 10 | yarn-error.log* 11 | jsconfig.json 12 | 13 | # Editor directories and files 14 | .idea 15 | .vscode 16 | *.suo 17 | *.ntvs* 18 | *.njsproj 19 | *.sln 20 | .editorconfig 21 | 22 | # Linters 23 | .eslintignore 24 | .eslintrc.js 25 | .babelrc 26 | 27 | # Testing 28 | /test 29 | .env.jest 30 | jest.config.js 31 | -------------------------------------------------------------------------------- /packages/ui/LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) Jeff Galbraith 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/ui/build/build.api2.js: -------------------------------------------------------------------------------- 1 | import path from 'path' 2 | import { fileURLToPath } from 'url' 3 | import quasarJsonApi from 'quasar-json-api' 4 | 5 | // Convert __dirname to ES module equivalent 6 | const __filename = fileURLToPath(import.meta.url) 7 | const __dirname = path.dirname(__filename) 8 | 9 | globalThis.rootDir = path.resolve(__dirname, '..') 10 | globalThis.distDir = path.resolve(__dirname, '../dist') 11 | 12 | quasarJsonApi({ 13 | buildVetur: false, 14 | buildTypes: true, 15 | forcedTypes: ['Timestamp'], 16 | }) 17 | -------------------------------------------------------------------------------- /packages/ui/build/config.ts: -------------------------------------------------------------------------------- 1 | import { createRequire } from 'module' 2 | const require = createRequire(import.meta.url) 3 | const { name, author, version } = require('../package.json') 4 | const year = new Date().getFullYear() 5 | 6 | // prettier-ignore 7 | export default { 8 | name, 9 | version, 10 | banner: 11 | '/*!\n' 12 | + ' * ' + name + ' v' + version + '\n' 13 | + ' * (c) ' + year + ' ' + author + '\n' 14 | + ' * Released under the MIT License.\n' 15 | + ' */\n' 16 | } 17 | -------------------------------------------------------------------------------- /packages/ui/build/entry/QCalendar.cjs.js: -------------------------------------------------------------------------------- 1 | export * from '../../src/QCalendar' 2 | -------------------------------------------------------------------------------- /packages/ui/build/entry/QCalendar.esm.js: -------------------------------------------------------------------------------- 1 | import Plugin from '../../src/QCalendar' 2 | 3 | export * from '../../src/QCalendar' 4 | export default Plugin 5 | -------------------------------------------------------------------------------- /packages/ui/build/entry/QCalendar.umd.js: -------------------------------------------------------------------------------- 1 | import Plugin from '../../src/QCalendar' 2 | export default Plugin 3 | -------------------------------------------------------------------------------- /packages/ui/build/entry/QCalendarAgenda.cjs.js: -------------------------------------------------------------------------------- 1 | import Plugin from '../../src/QCalendarAgenda' 2 | 3 | export default Plugin 4 | -------------------------------------------------------------------------------- /packages/ui/build/entry/QCalendarAgenda.esm.js: -------------------------------------------------------------------------------- 1 | import Plugin from '../../src/QCalendarAgenda' 2 | 3 | export * from '../../src/QCalendarAgenda' 4 | export default Plugin 5 | -------------------------------------------------------------------------------- /packages/ui/build/entry/QCalendarAgenda.umd.js: -------------------------------------------------------------------------------- 1 | import Plugin from '../../src/QCalendarAgenda' 2 | export default Plugin 3 | -------------------------------------------------------------------------------- /packages/ui/build/entry/QCalendarDay.cjs.js: -------------------------------------------------------------------------------- 1 | export * from '../../src/QCalendarDay' 2 | -------------------------------------------------------------------------------- /packages/ui/build/entry/QCalendarDay.esm.js: -------------------------------------------------------------------------------- 1 | import Plugin from '../../src/QCalendarDay' 2 | 3 | export * from '../../src/QCalendarDay' 4 | export default Plugin 5 | -------------------------------------------------------------------------------- /packages/ui/build/entry/QCalendarDay.umd.js: -------------------------------------------------------------------------------- 1 | import Plugin from '../../src/QCalendarDay' 2 | export default Plugin 3 | -------------------------------------------------------------------------------- /packages/ui/build/entry/QCalendarMonth.cjs.js: -------------------------------------------------------------------------------- 1 | export * from '../../src/QCalendarMonth' 2 | -------------------------------------------------------------------------------- /packages/ui/build/entry/QCalendarMonth.esm.js: -------------------------------------------------------------------------------- 1 | import Plugin from '../../src/QCalendarMonth' 2 | 3 | export * from '../../src/QCalendarMonth' 4 | export default Plugin 5 | -------------------------------------------------------------------------------- /packages/ui/build/entry/QCalendarMonth.umd.js: -------------------------------------------------------------------------------- 1 | import Plugin from '../../src/QCalendarMonth' 2 | export default Plugin 3 | -------------------------------------------------------------------------------- /packages/ui/build/entry/QCalendarResource.cjs.js: -------------------------------------------------------------------------------- 1 | export * from '../../src/QCalendarResource' 2 | -------------------------------------------------------------------------------- /packages/ui/build/entry/QCalendarResource.esm.js: -------------------------------------------------------------------------------- 1 | import Plugin from '../../src/QCalendarResource' 2 | 3 | export * from '../../src/QCalendarResource' 4 | export default Plugin 5 | -------------------------------------------------------------------------------- /packages/ui/build/entry/QCalendarResource.umd.js: -------------------------------------------------------------------------------- 1 | import Plugin from '../../src/QCalendarResource' 2 | export default Plugin 3 | -------------------------------------------------------------------------------- /packages/ui/build/entry/QCalendarScheduler.cjs.js: -------------------------------------------------------------------------------- 1 | export * from '../../src/QCalendarScheduler' 2 | -------------------------------------------------------------------------------- /packages/ui/build/entry/QCalendarScheduler.esm.js: -------------------------------------------------------------------------------- 1 | import Plugin from '../../src/QCalendarScheduler' 2 | 3 | export * from '../../src/QCalendarScheduler' 4 | export default Plugin 5 | -------------------------------------------------------------------------------- /packages/ui/build/entry/QCalendarScheduler.umd.js: -------------------------------------------------------------------------------- 1 | import Plugin from '../../src/QCalendarScheduler' 2 | export default Plugin 3 | -------------------------------------------------------------------------------- /packages/ui/build/entry/QCalendarTask.cjs.js: -------------------------------------------------------------------------------- 1 | export * from '../../src/QCalendarTask' 2 | -------------------------------------------------------------------------------- /packages/ui/build/entry/QCalendarTask.esm.js: -------------------------------------------------------------------------------- 1 | import Plugin from '../../src/QCalendarTask' 2 | 3 | export * from '../../src/QCalendarTask' 4 | export default Plugin 5 | -------------------------------------------------------------------------------- /packages/ui/build/entry/QCalendarTask.umd.js: -------------------------------------------------------------------------------- 1 | import Plugin from '../../src/QCalendarTask' 2 | export default Plugin 3 | -------------------------------------------------------------------------------- /packages/ui/build/entry/Timestamp.cjs.js: -------------------------------------------------------------------------------- 1 | export * from '../../src/Timestamp' 2 | -------------------------------------------------------------------------------- /packages/ui/build/entry/Timestamp.esm.js: -------------------------------------------------------------------------------- 1 | import Plugin from '../../src/Timestamp' 2 | 3 | export * from '../../src/Timestamp' 4 | export default Plugin 5 | -------------------------------------------------------------------------------- /packages/ui/build/entry/Timestamp.umd.js: -------------------------------------------------------------------------------- 1 | import Plugin from '../../src/Timestamp' 2 | export default Plugin 3 | -------------------------------------------------------------------------------- /packages/ui/build/entry/index.cjs.js: -------------------------------------------------------------------------------- 1 | export * from '../../src/index' 2 | -------------------------------------------------------------------------------- /packages/ui/build/entry/index.esm.js: -------------------------------------------------------------------------------- 1 | import Plugin from '../../src/index' 2 | 3 | export * from '../../src/index' 4 | export default Plugin 5 | -------------------------------------------------------------------------------- /packages/ui/build/entry/index.umd.js: -------------------------------------------------------------------------------- 1 | import Plugin from '../../src/index' 2 | export default Plugin 3 | -------------------------------------------------------------------------------- /packages/ui/build/script.clean.ts: -------------------------------------------------------------------------------- 1 | /*global console */ 2 | import { rimrafSync } from 'rimraf' 3 | import path from 'node:path' 4 | import { fileURLToPath } from 'node:url' 5 | 6 | const __filename = fileURLToPath(import.meta.url) 7 | const __dirname = path.dirname(__filename) 8 | 9 | rimrafSync(path.resolve(__dirname, '../dist/*')) 10 | console.log(' 💥 Cleaned build artifacts.\n') 11 | -------------------------------------------------------------------------------- /packages/ui/build/script.open-umd.ts: -------------------------------------------------------------------------------- 1 | import path, { resolve } from 'node:path' 2 | import open from 'open' 3 | import { fileURLToPath } from 'node:url' 4 | 5 | // Convert __dirname to ES module equivalent 6 | const __filename = fileURLToPath(import.meta.url) 7 | const __dirname = path.dirname(__filename) 8 | 9 | open(resolve(__dirname, '../umd-test.html')) 10 | -------------------------------------------------------------------------------- /packages/ui/build/script.version.ts: -------------------------------------------------------------------------------- 1 | import fs from 'node:fs' 2 | import path from 'node:path' 3 | import { fileURLToPath } from 'node:url' 4 | import { createRequire } from 'node:module' 5 | const require = createRequire(import.meta.url) 6 | 7 | // Convert __dirname to ES module equivalent 8 | const __filename = fileURLToPath(import.meta.url) 9 | const __dirname = path.dirname(__filename) 10 | 11 | // get version 12 | const { version } = require('../package.json') 13 | 14 | // read in the template as text 15 | let template = fs.readFileSync(path.resolve(__dirname, './version/version-template.js'), 'utf-8') 16 | 17 | // do the replacement 18 | template = template.replace('__UI_VERSION__', `'${version}'`) 19 | 20 | // write the file 21 | fs.writeFileSync(path.resolve(__dirname, '../src/version.js'), template, 'utf-8') 22 | -------------------------------------------------------------------------------- /packages/ui/build/version/version-template.js: -------------------------------------------------------------------------------- 1 | export const version = __UI_VERSION__ -------------------------------------------------------------------------------- /packages/ui/src/QCalendar.scss: -------------------------------------------------------------------------------- 1 | @use './css/q-calendar.scss'; 2 | @use './css/calendar-day.scss'; 3 | @use './css/calendar-month.scss'; 4 | @use './css/calendar-month-mini.scss'; 5 | @use './css/calendar-agenda.scss'; 6 | @use './css/calendar-resource.scss'; 7 | @use './css/calendar-scheduler.scss'; 8 | @use './css/calendar-task.scss'; 9 | -------------------------------------------------------------------------------- /packages/ui/src/QCalendar.ts: -------------------------------------------------------------------------------- 1 | import { App as Application } from 'vue' 2 | import QCalendar from './components/QCalendar' 3 | import QCalendarAgenda from './components/QCalendarAgenda' 4 | import QCalendarDay from './components/QCalendarDay' 5 | import QCalendarMonth from './components/QCalendarMonth' 6 | import QCalendarResource from './components/QCalendarResource' 7 | import QCalendarScheduler from './components/QCalendarScheduler' 8 | import QCalendarTask from './components/QCalendarTask' 9 | import { version } from './version.js' 10 | 11 | import * as Timestamp from './utils/Timestamp' 12 | import * as helpers from './utils/helpers' 13 | 14 | // Explicitly export individual named properties 15 | export * from './utils/Timestamp' 16 | export * from './utils/helpers' 17 | 18 | export { 19 | version, 20 | QCalendar, 21 | QCalendarAgenda, 22 | QCalendarDay, 23 | QCalendarMonth, 24 | QCalendarResource, 25 | QCalendarScheduler, 26 | QCalendarTask, 27 | } 28 | 29 | export default { 30 | version, 31 | QCalendar, 32 | QCalendarAgenda, 33 | QCalendarDay, 34 | QCalendarMonth, 35 | QCalendarResource, 36 | QCalendarScheduler, 37 | QCalendarTask, 38 | ...Timestamp, 39 | ...helpers, 40 | 41 | install(app: Application): void { 42 | app.component(String(QCalendar.name), QCalendar) 43 | }, 44 | } 45 | -------------------------------------------------------------------------------- /packages/ui/src/QCalendarAgenda.scss: -------------------------------------------------------------------------------- 1 | @use './css/q-calendar.scss'; 2 | @use './css/calendar-agenda.scss'; 3 | -------------------------------------------------------------------------------- /packages/ui/src/QCalendarAgenda.ts: -------------------------------------------------------------------------------- 1 | import { App as Application } from 'vue' 2 | import QCalendarAgenda from './components/QCalendarAgenda' 3 | import { version } from './version.js' 4 | 5 | import * as Timestamp from './utils/Timestamp' 6 | import * as helpers from './utils/helpers' 7 | 8 | // Explicitly export individual named properties 9 | export * from './utils/Timestamp' 10 | export * from './utils/helpers' 11 | 12 | export { version, QCalendarAgenda } 13 | 14 | export default { 15 | version, 16 | QCalendarAgenda, 17 | ...Timestamp, 18 | ...helpers, 19 | 20 | install(app: Application): void { 21 | app.component(String(QCalendarAgenda.name), QCalendarAgenda) 22 | }, 23 | } 24 | -------------------------------------------------------------------------------- /packages/ui/src/QCalendarDay.scss: -------------------------------------------------------------------------------- 1 | @use './css/q-calendar.scss'; 2 | @use './css/calendar-day.scss'; 3 | -------------------------------------------------------------------------------- /packages/ui/src/QCalendarDay.ts: -------------------------------------------------------------------------------- 1 | import { App as Application } from 'vue' 2 | import QCalendarDay from './components/QCalendarDay' 3 | import { version } from './version.js' 4 | 5 | import * as Timestamp from './utils/Timestamp' 6 | import * as helpers from './utils/helpers' 7 | 8 | // Explicitly export individual named properties 9 | export * from './utils/Timestamp' 10 | export * from './utils/helpers' 11 | 12 | export { version, QCalendarDay } 13 | 14 | export default { 15 | version, 16 | QCalendarDay, 17 | ...Timestamp, 18 | ...helpers, 19 | 20 | install(app: Application): void { 21 | app.component(String(QCalendarDay.name), QCalendarDay) 22 | }, 23 | } 24 | -------------------------------------------------------------------------------- /packages/ui/src/QCalendarMonth.scss: -------------------------------------------------------------------------------- 1 | @use './css/q-calendar.scss'; 2 | @use './css/calendar-month.scss'; 3 | @use './css/calendar-month-mini.scss'; 4 | -------------------------------------------------------------------------------- /packages/ui/src/QCalendarMonth.ts: -------------------------------------------------------------------------------- 1 | import { App as Application } from 'vue' 2 | import QCalendarMonth from './components/QCalendarMonth' 3 | import { version } from './version.js' 4 | 5 | import * as Timestamp from './utils/Timestamp' 6 | import * as helpers from './utils/helpers' 7 | 8 | // Explicitly export individual named properties 9 | export * from './utils/Timestamp' 10 | export * from './utils/helpers' 11 | 12 | export { version, QCalendarMonth } 13 | 14 | export default { 15 | version, 16 | QCalendarMonth, 17 | ...Timestamp, 18 | ...helpers, 19 | 20 | install(app: Application): void { 21 | app.component(String(QCalendarMonth.name), QCalendarMonth) 22 | }, 23 | } 24 | -------------------------------------------------------------------------------- /packages/ui/src/QCalendarResource.scss: -------------------------------------------------------------------------------- 1 | @use './css/q-calendar.scss'; 2 | @use './css/calendar-resource.scss'; 3 | -------------------------------------------------------------------------------- /packages/ui/src/QCalendarResource.ts: -------------------------------------------------------------------------------- 1 | import { App as Application } from 'vue' 2 | import QCalendarResource from './components/QCalendarResource' 3 | import { version } from './version.js' 4 | 5 | import * as Timestamp from './utils/Timestamp' 6 | import * as helpers from './utils/helpers' 7 | 8 | // Explicitly export individual named properties 9 | export * from './utils/Timestamp' 10 | export * from './utils/helpers' 11 | 12 | export { version, QCalendarResource } 13 | 14 | export default { 15 | version, 16 | QCalendarResource, 17 | ...Timestamp, 18 | ...helpers, 19 | 20 | install(app: Application): void { 21 | app.component(String(QCalendarResource.name), QCalendarResource) 22 | }, 23 | } 24 | -------------------------------------------------------------------------------- /packages/ui/src/QCalendarScheduler.scss: -------------------------------------------------------------------------------- 1 | @use './css/q-calendar.scss'; 2 | @use './css/calendar-scheduler.scss'; 3 | -------------------------------------------------------------------------------- /packages/ui/src/QCalendarScheduler.ts: -------------------------------------------------------------------------------- 1 | import { App as Application } from 'vue' 2 | import QCalendarScheduler from './components/QCalendarScheduler' 3 | import { version } from './version.js' 4 | 5 | import * as Timestamp from './utils/Timestamp' 6 | import * as helpers from './utils/helpers' 7 | 8 | // Explicitly export individual named properties 9 | export * from './utils/Timestamp' 10 | export * from './utils/helpers' 11 | 12 | export { version, QCalendarScheduler } 13 | 14 | export default { 15 | version, 16 | QCalendarScheduler, 17 | ...Timestamp, 18 | ...helpers, 19 | 20 | install(app: Application): void { 21 | app.component(String(QCalendarScheduler.name), QCalendarScheduler) 22 | }, 23 | } 24 | -------------------------------------------------------------------------------- /packages/ui/src/QCalendarTask.scss: -------------------------------------------------------------------------------- 1 | @use './css/q-calendar.scss'; 2 | @use './css/calendar-task.scss'; 3 | -------------------------------------------------------------------------------- /packages/ui/src/QCalendarTask.ts: -------------------------------------------------------------------------------- 1 | import { App as Application } from 'vue' 2 | import QCalendarTask from './components/QCalendarTask' 3 | import { version } from './version.js' 4 | 5 | import * as Timestamp from './utils/Timestamp' 6 | import * as helpers from './utils/helpers' 7 | 8 | // Explicitly export individual named properties 9 | export * from './utils/Timestamp' 10 | export * from './utils/helpers' 11 | 12 | export { version, QCalendarTask } 13 | 14 | export default { 15 | version, 16 | QCalendarTask, 17 | ...Timestamp, 18 | ...helpers, 19 | 20 | install(app: Application): void { 21 | app.component(String(QCalendarTask.name), QCalendarTask) 22 | }, 23 | } 24 | -------------------------------------------------------------------------------- /packages/ui/src/QCalendarTransitions.scss: -------------------------------------------------------------------------------- 1 | @use './css/calendar-transitions.scss'; 2 | -------------------------------------------------------------------------------- /packages/ui/src/QCalendarVariables.scss: -------------------------------------------------------------------------------- 1 | @use './css/calendar-variables.scss'; 2 | -------------------------------------------------------------------------------- /packages/ui/src/Timestamp.ts: -------------------------------------------------------------------------------- 1 | import { version } from './version.js' 2 | 3 | import * as Timestamp from './utils/Timestamp' 4 | import * as helpers from './utils/helpers' 5 | 6 | // Explicitly export individual named properties 7 | export * from './utils/Timestamp' 8 | export * from './utils/helpers' 9 | 10 | export { version } 11 | 12 | export default { 13 | version, 14 | ...Timestamp, 15 | ...helpers, 16 | } 17 | -------------------------------------------------------------------------------- /packages/ui/src/composables/private.useAgenda.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quasarframework/quasar-ui-qcalendar/ff4d6e93ab27a1432bdff0dfc1d72ddc5a61393f/packages/ui/src/composables/private.useAgenda.json -------------------------------------------------------------------------------- /packages/ui/src/composables/private.useCellWidth.json: -------------------------------------------------------------------------------- 1 | { 2 | "props": { 3 | "cell-width": { 4 | "type": [ 5 | "String", 6 | "Number" 7 | ], 8 | "category": "behavior", 9 | "desc": "Sets day cell width and turns on sticky mode. Width must be css measurement if a string, otherwise it's in pixels", 10 | "default": "# 100", 11 | "__runtimeDefault": true, 12 | "examples": [ 13 | "'100px'" 14 | ] 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /packages/ui/src/composables/private.useCheckChange.json: -------------------------------------------------------------------------------- 1 | { 2 | "events": { 3 | "change": { 4 | "desc": "Emitted when the view's dates change", 5 | "params": { 6 | "scope": { 7 | "type": "Object", 8 | "desc": "The data that cjanged", 9 | "definition": { 10 | "start": { 11 | "type": "String", 12 | "desc": "The new start Timestamp", 13 | "__exemption": [ 14 | "examples" 15 | ] 16 | }, 17 | "end": { 18 | "type": "String", 19 | "desc": "The new end Timestamp", 20 | "__exemption": [ 21 | "examples" 22 | ] 23 | }, 24 | "days": { 25 | "type": "Array", 26 | "tsType": "TimestampArray", 27 | "desc": "An array of Timestamps between start and end", 28 | "__exemption": [ 29 | "examples" 30 | ] 31 | } 32 | } 33 | } 34 | } 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /packages/ui/src/composables/private.useMaxDays.json: -------------------------------------------------------------------------------- 1 | { 2 | "props": { 3 | "max-days": { 4 | "type": "Number", 5 | "category": "model", 6 | "desc": "The number of days to be displayed. Do not use with `week` or `month` views (set to 0 if setting the view dynamically)", 7 | "default": "7", 8 | "examples": [ 9 | "14", 10 | "10" 11 | ] 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /packages/ui/src/composables/private.useMove.json: -------------------------------------------------------------------------------- 1 | { 2 | "events": { 3 | "moved": { 4 | "desc": "Emitted when the date is moved", 5 | "params": { 6 | "timestamp": { 7 | "type": "Timestamp", 8 | "tsType": "Timestamp", 9 | "desc": "The Timestamp object of the move", 10 | "__exemption": [ 11 | "examples" 12 | ] 13 | } 14 | } 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /packages/ui/src/composables/private.useNavigation.json: -------------------------------------------------------------------------------- 1 | { 2 | "props": { 3 | "use-navigation": { 4 | "type": "Boolean", 5 | "desc": "Allows keyboard navigation", 6 | "category": "behavior" 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /packages/ui/src/composables/private.useTimes.json: -------------------------------------------------------------------------------- 1 | { 2 | "props": { 3 | "now": { 4 | "type": "String", 5 | "category": "model", 6 | "desc": "This is the currently displayed date (highlighted). If not set, then the current date is used", 7 | "default": "'now'", 8 | "examples": [ 9 | "'2019-04-01'", 10 | "'2020-08-08'" 11 | ] 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /packages/ui/src/composables/useButton.ts: -------------------------------------------------------------------------------- 1 | import { h, VNode } from 'vue' 2 | import useFocusHelper from './useFocusHelper' 3 | 4 | interface ButtonProps { 5 | focusable: boolean 6 | focusType: string[] 7 | } 8 | 9 | export default function useButton(): { 10 | renderButton: ( 11 | _props: ButtonProps, 12 | _data: Record, 13 | _slotData: VNode | VNode[] | string, 14 | ) => VNode 15 | } { 16 | function renderButton( 17 | { focusable, focusType }: ButtonProps, 18 | data: Record, 19 | slotData: VNode | VNode[] | string, 20 | ): VNode { 21 | // Ensure the button is focusable based on props 22 | const isFocusable = focusable && focusType.includes('date') 23 | 24 | return h('button', { ...data, tabindex: isFocusable ? 0 : -1 }, [ 25 | slotData, 26 | isFocusable && useFocusHelper(), 27 | ]) 28 | } 29 | 30 | return { renderButton } 31 | } 32 | -------------------------------------------------------------------------------- /packages/ui/src/composables/useCellWidth.ts: -------------------------------------------------------------------------------- 1 | // cellWidth composables 2 | import { computed, ComputedRef } from 'vue' 3 | 4 | export const useCellWidthProps = { 5 | cellWidth: [Number, String], 6 | } 7 | 8 | /** 9 | * Determines whether the cell width is defined. 10 | * @param {Object} props - The component props. 11 | * @returns {Object} - The `isSticky` computed property. 12 | */ 13 | /** 14 | * Determines whether the cell width is defined. 15 | * @param {Object} props - The component props. 16 | * @returns {Object} - The `isSticky` computed property. 17 | */ 18 | /** 19 | * @param {Object} props - The component props. 20 | * @returns {Object} - An object containing the `isSticky` computed property. 21 | */ 22 | export interface CellWidthProps { 23 | cellWidth?: number | string 24 | } 25 | 26 | interface UseCellWidthReturn { 27 | isSticky: ComputedRef 28 | } 29 | 30 | export default function useCellWidth(props: CellWidthProps): UseCellWidthReturn { 31 | const isSticky = computed(() => props.cellWidth !== undefined) 32 | 33 | return { 34 | isSticky, 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /packages/ui/src/composables/useCheckChange.ts: -------------------------------------------------------------------------------- 1 | import { Ref } from 'vue' 2 | import { Timestamp } from '../utils/Timestamp' 3 | 4 | export const useCheckChangeEmits = ['change'] as const 5 | 6 | export interface CheckChangeProps { 7 | days: Ref 8 | lastStart: Ref 9 | lastEnd: Ref 10 | } 11 | 12 | export interface CheckChangeEvent { 13 | start: string 14 | end: string 15 | days: Timestamp[] 16 | } 17 | 18 | interface CheckChangeReturn { 19 | checkChange: () => boolean 20 | } 21 | 22 | export default function useCheckChange( 23 | emit: (_event: 'change', _payload: CheckChangeEvent) => void, 24 | { days, lastStart, lastEnd }: CheckChangeProps, 25 | ): CheckChangeReturn { 26 | function checkChange(): boolean { 27 | const dayList = days.value 28 | if (dayList.length === 0) return false 29 | 30 | const start = dayList[0]!.date 31 | const end = dayList[dayList.length - 1]!.date 32 | 33 | if (!lastStart.value || !lastEnd.value || start !== lastStart.value || end !== lastEnd.value) { 34 | lastStart.value = start 35 | lastEnd.value = end 36 | emit('change', { start, end, days: dayList }) 37 | return true 38 | } 39 | 40 | return false 41 | } 42 | 43 | return { checkChange } 44 | } 45 | -------------------------------------------------------------------------------- /packages/ui/src/composables/useColumn.ts: -------------------------------------------------------------------------------- 1 | import { PropType } from 'vue' 2 | import { validateNumber } from '../utils/Timestamp' 3 | 4 | export interface ColumnObject { 5 | [key: string]: any 6 | } 7 | 8 | export type ColumnObjectArray = ColumnObject[] 9 | 10 | export interface ColumnProps { 11 | columnCount: number | string 12 | columnIndexStart: number | string 13 | } 14 | 15 | export const useColumnProps = { 16 | columnCount: { 17 | type: [Number, String] as PropType, 18 | default: 0, 19 | validator: validateNumber, 20 | }, 21 | columnIndexStart: { 22 | type: [Number, String] as PropType, 23 | default: 0, 24 | validator: validateNumber, 25 | }, 26 | } as const 27 | -------------------------------------------------------------------------------- /packages/ui/src/composables/useEmitListeners.ts: -------------------------------------------------------------------------------- 1 | import { computed, getCurrentInstance, ComponentInternalInstance, ComputedRef } from 'vue' 2 | 3 | /** 4 | * Regular expression to match event listeners starting with 'on'. 5 | */ 6 | const listenerRE = /^on[A-Z]/ 7 | 8 | export type EmitListeners = ComputedRef> 9 | 10 | /** 11 | * Provides computed event listeners from the component instance. 12 | * @param {ComponentInternalInstance | null} vm - Vue's component instance (defaults to `getCurrentInstance()`). 13 | * @returns {{ emitListeners: EmitListeners }} - Computed map of event listeners. 14 | */ 15 | export default function useEmitListeners( 16 | vm: ComponentInternalInstance | null = getCurrentInstance(), 17 | ): { emitListeners: EmitListeners } { 18 | return { 19 | emitListeners: computed(() => { 20 | const listeners: Record = {} 21 | 22 | // Ensure vm and vm.vnode are defined before accessing props 23 | if (vm?.vnode?.props) { 24 | Object.keys(vm.vnode.props).forEach((key) => { 25 | if (listenerRE.test(key)) { 26 | listeners[key] = true 27 | } 28 | }) 29 | } 30 | 31 | return listeners 32 | }), 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/ui/src/composables/useEvents.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Utility functions for event handling. 3 | */ 4 | 5 | interface EventUtilsReturn { 6 | isKeyCode: (_evt: KeyboardEvent, _keyCodes: number | number[]) => boolean 7 | } 8 | 9 | export default function useEventUtils(): EventUtilsReturn { 10 | /** 11 | * Checks if the event's keyCode matches any of the specified keyCodes. 12 | * @param {KeyboardEvent} evt - The keyboard event. 13 | * @param {number | number[]} keyCodes - The key code or an array of key codes to check against. 14 | * @returns {boolean} True if the keyCode matches, false otherwise. 15 | */ 16 | function isKeyCode(evt: KeyboardEvent, keyCodes: number | number[]): boolean { 17 | return (Array.isArray(keyCodes) ? keyCodes : [keyCodes]).includes(evt.keyCode) 18 | } 19 | 20 | return { 21 | isKeyCode, 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/ui/src/composables/useFocusHelper.ts: -------------------------------------------------------------------------------- 1 | import { h, VNode } from 'vue' 2 | 3 | /** 4 | * Creates an accessible focus helper span element. 5 | * @returns {VNode[]} An array containing a single span VNode. 6 | */ 7 | export default function useFocusHelper(): VNode[] { 8 | const spanProps = { 9 | 'aria-hidden': 'true', 10 | class: 'q-calendar__focus-helper', 11 | } 12 | 13 | return [h('span', spanProps)] 14 | } 15 | -------------------------------------------------------------------------------- /packages/ui/src/composables/useMaxDays.ts: -------------------------------------------------------------------------------- 1 | import { PropType } from 'vue' 2 | 3 | /** 4 | * Interface for maxDays prop. 5 | */ 6 | export interface MaxDaysProps { 7 | maxDays: number 8 | } 9 | 10 | /** 11 | * Defines the maxDays prop for components. 12 | */ 13 | export const useMaxDaysProps = { 14 | maxDays: { 15 | type: Number as PropType, 16 | default: 1, 17 | }, 18 | } as const 19 | -------------------------------------------------------------------------------- /packages/ui/src/directives/Resize.ts: -------------------------------------------------------------------------------- 1 | /* global window */ 2 | import { Directive, DirectiveBinding } from 'vue' 3 | 4 | interface ResizeData { 5 | callback: () => void 6 | // `options` can be either a boolean or an object implementing AddEventListenerOptions. 7 | options: boolean | AddEventListenerOptions 8 | } 9 | 10 | // Extend HTMLElement to include our custom property. 11 | interface HTMLElementWithResize extends HTMLElement { 12 | _onResize?: ResizeData 13 | } 14 | 15 | const ResizeDirective: Directive = { 16 | mounted(el: HTMLElementWithResize, binding: DirectiveBinding) { 17 | const { modifiers, value } = binding 18 | if (!value) return 19 | 20 | const callback = value as () => void 21 | // If modifiers are provided and not empty, use them as options; otherwise, default to { passive: true }. 22 | const options = 23 | Object.keys(modifiers).length > 0 24 | ? (modifiers as unknown as AddEventListenerOptions) 25 | : { passive: true } 26 | 27 | window.addEventListener('resize', callback, options) 28 | el._onResize = { 29 | callback, 30 | options, 31 | } 32 | 33 | // If the "quiet" modifier is not set, call the callback immediately. 34 | if (!modifiers.quiet) { 35 | callback() 36 | } 37 | }, 38 | 39 | beforeUnmount(el: HTMLElementWithResize) { 40 | if (!el._onResize) return 41 | 42 | const { callback, options } = el._onResize 43 | window.removeEventListener('resize', callback, options) 44 | delete el._onResize 45 | }, 46 | } 47 | 48 | export default ResizeDirective 49 | -------------------------------------------------------------------------------- /packages/ui/src/index.scss: -------------------------------------------------------------------------------- 1 | @use './css/calendar-variables.scss'; 2 | @use './css/calendar-transitions.scss'; 3 | @use './css/q-calendar.scss'; 4 | @use './css/calendar-agenda.scss'; 5 | @use './css/calendar-day.scss'; 6 | @use './css/calendar-task.scss'; 7 | @use './css/calendar-month.scss'; 8 | @use './css/calendar-resource.scss'; 9 | @use './css/calendar-scheduler.scss'; 10 | -------------------------------------------------------------------------------- /packages/ui/src/index.ts: -------------------------------------------------------------------------------- 1 | import { App as Application } from 'vue' 2 | import QCalendar from './components/QCalendar.js' 3 | import QCalendarAgenda from './components/QCalendarAgenda.js' 4 | import QCalendarDay from './components/QCalendarDay.js' 5 | import QCalendarMonth from './components/QCalendarMonth.js' 6 | import QCalendarResource from './components/QCalendarResource.js' 7 | import QCalendarScheduler from './components/QCalendarScheduler.js' 8 | import QCalendarTask from './components/QCalendarTask.js' 9 | 10 | import { version } from './version.js' 11 | 12 | import * as Timestamp from './utils/Timestamp.js' 13 | import * as helpers from './utils/helpers.js' 14 | 15 | // Explicitly export individual named properties 16 | export * from './utils/Timestamp.js' 17 | export * from './utils/helpers.js' 18 | 19 | export { 20 | version, 21 | QCalendar, 22 | QCalendarAgenda, 23 | QCalendarDay, 24 | QCalendarMonth, 25 | QCalendarResource, 26 | QCalendarScheduler, 27 | QCalendarTask, 28 | } 29 | 30 | export default { 31 | version, 32 | QCalendar, 33 | QCalendarAgenda, 34 | QCalendarDay, 35 | QCalendarMonth, 36 | QCalendarResource, 37 | QCalendarScheduler, 38 | QCalendarTask, 39 | ...Timestamp, 40 | ...helpers, 41 | 42 | // Vue plugin 43 | install(app: Application): void { 44 | app.component(String(QCalendar.name), QCalendar) 45 | app.component(String(QCalendarAgenda.name), QCalendarAgenda) 46 | app.component(String(QCalendarDay.name), QCalendarDay) 47 | app.component(String(QCalendarMonth.name), QCalendarMonth) 48 | app.component(String(QCalendarResource.name), QCalendarResource) 49 | app.component(String(QCalendarScheduler.name), QCalendarScheduler) 50 | app.component(String(QCalendarTask.name), QCalendarTask) 51 | }, 52 | } 53 | -------------------------------------------------------------------------------- /packages/ui/src/utils/helpers.ts: -------------------------------------------------------------------------------- 1 | export function convertToUnit(input: any, unit = 'px'): string | undefined { 2 | if (!input) { 3 | return undefined 4 | } else if (isNaN(input)) { 5 | return String(input) 6 | } else if (input === 'auto') { 7 | return input 8 | } else { 9 | return `${Number(input)}${unit}` 10 | } 11 | } 12 | 13 | export function indexOf(array: any[], cb: (_element: any, _index: number) => boolean): number { 14 | for (let i = 0; i < array.length; i++) { 15 | if (cb(array[i], i) === true) { 16 | return i 17 | } 18 | } 19 | return -1 20 | } 21 | 22 | export function minCharWidth(str: string, count: number): string { 23 | if (count === 0) return str 24 | return str.slice(0, count) 25 | } 26 | 27 | export default { 28 | convertToUnit, 29 | indexOf, 30 | minCharWidth, 31 | } 32 | -------------------------------------------------------------------------------- /packages/ui/src/utils/views.ts: -------------------------------------------------------------------------------- 1 | export function validateView(view: string): boolean { 2 | return [ 3 | 'month', 4 | 'week', 5 | 'day', 6 | '2day', 7 | '3day', 8 | '4day', 9 | '5day', 10 | '6day', 11 | 'month-scheduler', 12 | 'week-scheduler', 13 | 'custom-scheduler', 14 | 'scheduler', 15 | 'day-scheduler', 16 | '2day-scheduler', 17 | '3day-scheduler', 18 | '4day-scheduler', 19 | '5day-scheduler', 20 | '6day-scheduler', 21 | 'resource', 22 | 'day-resource', 23 | 'month-agenda', 24 | 'week-agenda', 25 | 'custom-agenda', 26 | 'agenda', 27 | 'day-agenda', 28 | '2day-agenda', 29 | '3day-agenda', 30 | '4day-agenda', 31 | '5day-agenda', 32 | '6day-agenda', 33 | 'month-interval', 34 | 'custom-interval', 35 | ].includes(view) 36 | } 37 | -------------------------------------------------------------------------------- /packages/ui/src/version.js: -------------------------------------------------------------------------------- 1 | export const version = '4.1.2' -------------------------------------------------------------------------------- /packages/ui/test/compareDate.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import * as timestamp from '../src/utils/Timestamp' 3 | 4 | describe('[TIMESTAMP] compareDate', () => { 5 | it('Compare 2 dates are the same', () => { 6 | const ts1 = timestamp.parsed('2020-01-01') 7 | const ts2 = timestamp.parsed('2020-01-01') 8 | const tests = timestamp.compareDate(ts1, ts2) 9 | expect(tests).toBe(true) 10 | }) 11 | 12 | it('Compare 2 dates are NOT the same', () => { 13 | const ts1 = timestamp.parsed('2020-01-01') 14 | const ts2 = timestamp.parsed('2020-12-31') 15 | const tests = timestamp.compareDate(ts1, ts2) 16 | expect(tests).toBe(false) 17 | }) 18 | 19 | it('Compare 2 dates are the same with Date', () => { 20 | const ts1 = timestamp.parsed('2020-01-01') 21 | const ts2 = timestamp.parseDate(new Date(2020, 0, 1)) // January is month 0 22 | const tests = timestamp.compareDate(ts1, ts2) 23 | expect(tests).toBe(true) 24 | }) 25 | 26 | it('Compare 2 dates are NOT the same with Date', () => { 27 | const ts1 = timestamp.parsed('2020-01-01') 28 | const ts2 = timestamp.parseDate(new Date(2020, 11, 31)) // December is month 11 29 | const tests = timestamp.compareDate(ts1, ts2) 30 | expect(tests).toBe(false) 31 | }) 32 | }) 33 | -------------------------------------------------------------------------------- /packages/ui/test/compareDateTime.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import * as timestamp from '../src/utils/Timestamp' 3 | 4 | describe('[TIMESTAMP] compareDateTime', () => { 5 | it('Compare 2 date/time are the same', () => { 6 | const ts1 = timestamp.parsed('2020-01-01 01:00') 7 | const ts2 = timestamp.parsed('2020-01-01 01:00') 8 | const tests = timestamp.compareDateTime(ts1, ts2) 9 | expect(tests).toBe(true) 10 | }) 11 | 12 | it('Compare 2 date/time are NOT the same', () => { 13 | const ts1 = timestamp.parsed('2020-01-01 01:00') 14 | const ts2 = timestamp.parsed('2020-12-31 01:00') 15 | const tests = timestamp.compareDateTime(ts1, ts2) 16 | expect(tests).toBe(false) 17 | }) 18 | 19 | it('Compare 2 date/time are the same with Date', () => { 20 | const ts1 = timestamp.parsed('2020-01-01 01:00') 21 | const ts2 = timestamp.parseDate(new Date(2020, 0, 1, 1, 0, 0)) // January is month 0 22 | const tests = timestamp.compareDateTime(ts1, ts2) 23 | expect(tests).toBe(true) 24 | }) 25 | 26 | it('Compare 2 date/time are NOT the same with Date', () => { 27 | const ts1 = timestamp.parsed('2020-01-01 01:00') 28 | const ts2 = timestamp.parseDate(new Date(2020, 11, 31, 1, 0, 0)) // December is month 11 29 | const tests = timestamp.compareDateTime(ts1, ts2) 30 | expect(tests).toBe(false) 31 | }) 32 | }) 33 | -------------------------------------------------------------------------------- /packages/ui/test/compareTime.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import { parsed, parseDate, compareTime, type Timestamp } from '../src/utils/Timestamp' 3 | 4 | describe('[TIMESTAMP] compareTime', () => { 5 | it('Compare 2 times are the same', async () => { 6 | const ts1 = parsed('2020-01-01 01:00') as Timestamp 7 | const ts2 = parsed('2020-01-01 01:00') as Timestamp 8 | const tests = compareTime(ts1, ts2) 9 | expect(tests).toBe(true) 10 | }) 11 | 12 | it('Compare 2 times are NOT the same', async () => { 13 | const ts1 = parsed('2020-01-01 01:00') as Timestamp 14 | const ts2 = parsed('2020-12-31 02:00') as Timestamp 15 | const tests = compareTime(ts1, ts2) 16 | expect(tests).toBe(false) 17 | }) 18 | 19 | it('Compare 2 times are the same with Date', async () => { 20 | const ts1 = parsed('2020-01-01 01:00') as Timestamp 21 | const ts2 = parseDate(new Date(2020, 0, 1, 1, 0, 0)) as Timestamp 22 | const tests = compareTime(ts1, ts2) 23 | expect(tests).toBe(true) 24 | }) 25 | 26 | it('Compare 2 times are NOT the same with Date', async () => { 27 | const ts1 = parsed('2020-01-01 01:00') as Timestamp 28 | const ts2 = parseDate(new Date(2020, 11, 31, 2, 0, 0)) as Timestamp 29 | const tests = compareTime(ts1, ts2) 30 | expect(tests).toBe(false) 31 | }) 32 | }) 33 | -------------------------------------------------------------------------------- /packages/ui/test/compareTimestamps.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import { 3 | parseTimestamp, 4 | parseDate, 5 | compareTimestamps, 6 | type Timestamp, 7 | } from '../src/utils/Timestamp' 8 | 9 | describe('[TIMESTAMP] compareTimestamps', () => { 10 | it('Compare 2 timestamps are the same', async () => { 11 | const ts1 = parseTimestamp('2020-01-01') as Timestamp 12 | const ts2 = parseTimestamp('2020-01-01') as Timestamp 13 | const tests = compareTimestamps(ts1, ts2) 14 | expect(tests).toBe(true) 15 | }) 16 | 17 | it('Compare 2 timestamps are NOT the same', async () => { 18 | const ts1 = parseTimestamp('2020-01-01') as Timestamp 19 | const ts2 = parseTimestamp('2020-12-31') as Timestamp 20 | const tests = compareTimestamps(ts1, ts2) 21 | expect(tests).toBe(false) 22 | }) 23 | 24 | it('Compare 2 timestamps are the same with Date', async () => { 25 | const ts1 = parseTimestamp('2020-01-01') as Timestamp 26 | const ts2 = parseDate(new Date(2020, 0, 1)) as Timestamp 27 | const tests = compareTimestamps(ts1, ts2) 28 | expect(tests).toBe(true) 29 | }) 30 | 31 | it('Compare 2 timestamps are NOT the same with Date', async () => { 32 | const ts1 = parseTimestamp('2020-01-01') as Timestamp 33 | const ts2 = parseDate(new Date(2020, 11, 31)) as Timestamp 34 | const tests = compareTimestamps(ts1, ts2) 35 | expect(tests).toBe(false) 36 | }) 37 | }) 38 | -------------------------------------------------------------------------------- /packages/ui/test/createDayList.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import { parseTimestamp, parseDate, createDayList, type Timestamp } from '../src/utils/Timestamp' 3 | 4 | describe('[TIMESTAMP] createDayList', () => { 5 | it('createDayList', async () => { 6 | const start = parseTimestamp('2020-01-01') as Timestamp 7 | const end = parseTimestamp('2020-01-31') as Timestamp 8 | const now = parseDate(new Date()) as Timestamp 9 | const tests = createDayList(start, end, now, [0, 1, 2, 3, 4, 5, 6]) 10 | expect(tests).toHaveLength(31) 11 | }) 12 | 13 | it('createDayList inverted', async () => { 14 | const start = parseTimestamp('2020-01-01') as Timestamp 15 | const end = parseTimestamp('2020-01-31') as Timestamp 16 | const now = parseDate(new Date()) as Timestamp 17 | const tests = createDayList(end, start, now) 18 | expect(tests).toHaveLength(0) 19 | }) 20 | 21 | it('createDayList with restricted weekday skips', async () => { 22 | const start = parseTimestamp('2020-01-01') as Timestamp 23 | const end = parseTimestamp('2020-01-31') as Timestamp 24 | const now = parseDate(new Date()) as Timestamp 25 | const tests = createDayList(start, end, now, [1, 2, 3, 4, 5]) 26 | expect(tests).toHaveLength(23) 27 | }) 28 | }) 29 | -------------------------------------------------------------------------------- /packages/ui/test/createIntervalList.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import { 3 | parseTimestamp, 4 | parseDate, 5 | createIntervalList, 6 | type Timestamp, 7 | } from '../src/utils/Timestamp' 8 | 9 | describe('[TIMESTAMP] createIntervalList', () => { 10 | it('createIntervalList 60 12', async () => { 11 | const start = parseTimestamp('2020-01-01') as Timestamp 12 | const tests = createIntervalList(start, 0, 60, 12, parseDate(new Date()) as Timestamp) 13 | expect(tests).toHaveLength(12) 14 | }) 15 | 16 | it('createIntervalList 15 48', async () => { 17 | const start = parseTimestamp('2020-01-01 03:00') as Timestamp 18 | const tests = createIntervalList(start, 8, 15, 48, parseDate(new Date()) as Timestamp) 19 | expect(tests).toHaveLength(48) 20 | }) 21 | }) 22 | -------------------------------------------------------------------------------- /packages/ui/test/createNativeLocaleFormatter.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import { createNativeLocaleFormatter, parseTimestamp, type Timestamp } from '../src/utils/Timestamp' 3 | 4 | describe('[TIMESTAMP] createNativeLocaleFormatter', () => { 5 | it('monthFormatter', async () => { 6 | function monthFormatter() { 7 | const longOptions = { timeZone: 'UTC', month: 'long' } as const 8 | const shortOptions = { timeZone: 'UTC', month: 'short' } as const 9 | 10 | return createNativeLocaleFormatter('en-US', (_tms, short) => 11 | short ? shortOptions : longOptions, 12 | ) 13 | } 14 | 15 | const ts = parseTimestamp('2020-01-01') as Timestamp 16 | let tests = monthFormatter()(ts, true) 17 | expect(tests).toBe('Jan') 18 | tests = monthFormatter()(ts, false) 19 | expect(tests).toBe('January') 20 | }) 21 | 22 | it('weekdayFormatter', async () => { 23 | function weekdayFormatter() { 24 | const longOptions = { timeZone: 'UTC', weekday: 'long' } as const 25 | const shortOptions = { timeZone: 'UTC', weekday: 'short' } as const 26 | 27 | return createNativeLocaleFormatter('en-US', (_tms, short) => 28 | short ? shortOptions : longOptions, 29 | ) 30 | } 31 | 32 | const ts = parseTimestamp('2020-01-01') as Timestamp 33 | let tests = weekdayFormatter()(ts, true) 34 | expect(tests).toBe('Wed') 35 | tests = weekdayFormatter()(ts, false) 36 | expect(tests).toBe('Wednesday') 37 | }) 38 | 39 | it('dayFormatter', async () => { 40 | function dayFormatter() { 41 | const options = { timeZone: 'UTC', day: 'numeric' } as const 42 | 43 | return createNativeLocaleFormatter('en-US', () => options) 44 | } 45 | 46 | const ts = parseTimestamp('2020-01-01') as Timestamp 47 | const tests = dayFormatter()(ts, false) 48 | expect(tests).toBe('1') 49 | }) 50 | }) 51 | -------------------------------------------------------------------------------- /packages/ui/test/daysBetween.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import { parsed, daysBetween, type Timestamp } from '../src/utils/Timestamp' 3 | 4 | describe('[TIMESTAMP] daysBetween', () => { 5 | it('daysBetween 2020-01-01 and 2020-12-31 (Leap Year)', async () => { 6 | const start = parsed('2020-01-01') as Timestamp 7 | const end = parsed('2020-12-31') as Timestamp 8 | const tests = daysBetween(start, end) 9 | expect(tests).toBe(365) 10 | }) 11 | 12 | it('daysBetween 2019-01-01 and 2019-12-31 (NOT Leap Year)', async () => { 13 | const start = parsed('2019-01-01') as Timestamp 14 | const end = parsed('2019-12-31') as Timestamp 15 | const tests = daysBetween(start, end) 16 | expect(tests).toBe(364) 17 | }) 18 | 19 | it('daysBetween 2020-01-01 and 2020-03-31 (Leap Year)', async () => { 20 | const start = parsed('2020-01-01') as Timestamp 21 | const end = parsed('2020-03-31') as Timestamp 22 | const tests = daysBetween(start, end) 23 | expect(tests).toBe(90) 24 | }) 25 | 26 | it('daysBetween 2019-01-01 and 2019-03-31 (NOT Leap Year)', async () => { 27 | const start = parsed('2019-01-01') as Timestamp 28 | const end = parsed('2019-03-31') as Timestamp 29 | const tests = daysBetween(start, end) 30 | expect(tests).toBe(89) 31 | }) 32 | }) 33 | -------------------------------------------------------------------------------- /packages/ui/test/daysInMonth.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import { daysInMonth } from '../src/utils/Timestamp' 3 | 4 | describe('[TIMESTAMP] daysInMonth', () => { 5 | it('Jan 2020 has 31 days', async () => { 6 | const tests = daysInMonth(2020, 1) 7 | expect(tests).toBe(31) 8 | }) 9 | 10 | it('daysInMonth Feb 2020 has 29 days (leap year)', async () => { 11 | const tests = daysInMonth(2020, 2) 12 | expect(tests).toBe(29) 13 | }) 14 | 15 | it('daysInMonth Feb 2019 has 28 days (not leap year)', async () => { 16 | const tests = daysInMonth(2019, 2) 17 | expect(tests).toBe(28) 18 | }) 19 | 20 | it('daysInMonth Jun 2020 has 30 days', async () => { 21 | const tests = daysInMonth(2020, 6) 22 | expect(tests).toBe(30) 23 | }) 24 | }) 25 | -------------------------------------------------------------------------------- /packages/ui/test/getDateTime.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import * as timestamp from '../src/utils/Timestamp' 3 | 4 | describe('[TIMESTAMP] getDateTime', () => { 5 | it('getDateTime 2020-01-01 03:21', () => { 6 | const ts = timestamp.parsed('2020-01-01 03:21') 7 | const tests = timestamp.getDateTime(ts) 8 | expect(tests).toBe('2020-01-01 03:21') 9 | }) 10 | 11 | it('getDateTime 2020-01-01 (no time)', () => { 12 | const ts = timestamp.parsed('2020-01-01') 13 | const tests = timestamp.getDateTime(ts) 14 | expect(tests).toBe('2020-01-01 00:00') 15 | }) 16 | }) 17 | -------------------------------------------------------------------------------- /packages/ui/test/getDayIdentifier.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import * as timestamp from '../src/utils/Timestamp' 3 | 4 | describe('[TIMESTAMP] getDayIdentifier', () => { 5 | it('getDayIdentifier 2020-01-01', () => { 6 | const ts = timestamp.parsed('2020-01-01') 7 | const tests = timestamp.getDayIdentifier(ts) 8 | expect(tests).toBe(202001010000) 9 | }) 10 | 11 | it('getDayIdentifier 2020-01-31', () => { 12 | const ts = timestamp.parsed('2020-01-31') 13 | const tests = timestamp.getDayIdentifier(ts) 14 | expect(tests).toBe(202001310000) 15 | }) 16 | 17 | it('getDayIdentifier 2022-08-08', () => { 18 | const ts = timestamp.parsed('2022-08-08') 19 | const tests = timestamp.getDayIdentifier(ts) 20 | expect(tests).toBe(202208080000) 21 | }) 22 | }) 23 | -------------------------------------------------------------------------------- /packages/ui/test/getEndOfMonth.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import * as timestamp from '../src/utils/Timestamp' 3 | 4 | describe('[TIMESTAMP] getEndOfMonth', () => { 5 | it('getEndOfMonth 2020-01-01', () => { 6 | const ts = timestamp.parsed('2020-01-01') 7 | const tests = timestamp.getEndOfMonth(ts) 8 | expect(tests.day).toBe(31) 9 | }) 10 | 11 | it('getEndOfMonth 2020-02-01 (Leap Year)', () => { 12 | const ts = timestamp.parsed('2020-02-01') 13 | const tests = timestamp.getEndOfMonth(ts) 14 | expect(tests.day).toBe(29) 15 | }) 16 | 17 | it('getEndOfMonth 2019-02-01 (NOT Leap Year)', () => { 18 | const ts = timestamp.parsed('2019-02-01') 19 | const tests = timestamp.getEndOfMonth(ts) 20 | expect(tests.day).toBe(28) 21 | }) 22 | }) 23 | -------------------------------------------------------------------------------- /packages/ui/test/getEndOfWeek.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import * as timestamp from '../src/utils/Timestamp' 3 | 4 | describe('[TIMESTAMP] getEndOfWeek', () => { 5 | it('getEndOfWeek 2020-01-01', () => { 6 | const ts = timestamp.parseTimestamp('2020-01-01') 7 | const tests = timestamp.getEndOfWeek(ts, [0, 1, 2, 3, 4, 5, 6]) 8 | expect(tests.day).toBe(4) 9 | }) 10 | 11 | it('getEndOfWeek 2020-01-31', () => { 12 | const ts = timestamp.parseTimestamp('2020-01-31') 13 | const tests = timestamp.getEndOfWeek(ts, [0, 1, 2, 3, 4, 5, 6]) 14 | expect(tests.day).toBe(1) 15 | }) 16 | 17 | it('getEndOfWeek 2022-08-08', () => { 18 | const ts = timestamp.parseTimestamp('2022-08-08') 19 | const tests = timestamp.getEndOfWeek(ts, [0, 1, 2, 3, 4, 5, 6]) 20 | expect(tests.day).toBe(13) 21 | }) 22 | 23 | it('getEndOfWeek 2022-08-08 with now', () => { 24 | const ts = timestamp.parseTimestamp('2022-08-08') 25 | const now = timestamp.parseDate(new Date()) 26 | const tests = timestamp.getEndOfWeek(ts, [0, 1, 2, 3, 4, 5, 6], now) 27 | expect(tests.day).toBe(13) 28 | }) 29 | 30 | it('getEndOfWeek 2022-08-08, restricted weekdays and now', () => { 31 | const ts = timestamp.parseTimestamp('2022-08-08') 32 | const now = timestamp.parseDate(new Date()) 33 | const tests = timestamp.getEndOfWeek(ts, [1, 2, 3, 4, 5], now) 34 | expect(tests.day).toBe(12) 35 | }) 36 | 37 | it('getEndOfWeek 2022-08-31, restricted weekdays, on last day of month, with now', () => { 38 | const ts = timestamp.parseTimestamp('2022-08-31') 39 | const now = timestamp.parseDate(new Date()) 40 | const tests = timestamp.getEndOfWeek(ts, [4, 5], now) 41 | expect(tests.day).toBe(26) 42 | }) 43 | }) 44 | -------------------------------------------------------------------------------- /packages/ui/test/getStartOfMonth.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import * as timestamp from '../src/utils/Timestamp' 3 | 4 | describe('[TIMESTAMP] getStartOfMonth', () => { 5 | it('getStartOfMonth 2020-01-01', () => { 6 | const ts = timestamp.parsed('2020-01-01') 7 | const tests = timestamp.getStartOfMonth(ts) 8 | expect(tests.day).toBe(1) 9 | }) 10 | 11 | it('getStartOfMonth 2020-01-31', () => { 12 | const ts = timestamp.parsed('2020-01-31') 13 | const tests = timestamp.getStartOfMonth(ts) 14 | expect(tests.day).toBe(1) 15 | }) 16 | 17 | it('getStartOfMonth 2022-08-08', () => { 18 | const ts = timestamp.parsed('2022-08-08') 19 | const tests = timestamp.getStartOfMonth(ts) 20 | expect(tests.day).toBe(1) 21 | }) 22 | }) 23 | -------------------------------------------------------------------------------- /packages/ui/test/getStartOfWeek.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import * as timestamp from '../src/utils/Timestamp' 3 | 4 | describe('[TIMESTAMP] getStartOfWeek', () => { 5 | it('getStartOfWeek 2020-01-01', async () => { 6 | const ts = timestamp.parseTimestamp('2020-01-01') 7 | const tests = timestamp.getStartOfWeek(ts, [0, 1, 2, 3, 4, 5, 6]) 8 | expect(tests.day).toBe(29) 9 | }) 10 | 11 | it('getStartOfWeek 2020-01-31', async () => { 12 | const ts = timestamp.parseTimestamp('2020-01-31') 13 | const tests = timestamp.getStartOfWeek(ts, [0, 1, 2, 3, 4, 5, 6]) 14 | expect(tests.day).toBe(26) 15 | }) 16 | 17 | it('getStartOfWeek 2022-08-08', async () => { 18 | const ts = timestamp.parseTimestamp('2022-08-08') 19 | const tests = timestamp.getStartOfWeek(ts, [0, 1, 2, 3, 4, 5, 6]) 20 | expect(tests.day).toBe(7) 21 | }) 22 | 23 | it('getStartOfWeek 2022-08-08 with now', async () => { 24 | const ts = timestamp.parseTimestamp('2022-08-08') 25 | const tests = timestamp.getStartOfWeek( 26 | ts, 27 | [0, 1, 2, 3, 4, 5, 6], 28 | timestamp.parseDate(new Date()), 29 | ) 30 | expect(tests.day).toBe(7) 31 | }) 32 | 33 | it('getStartOfWeek 2022-08-08, restricted weekdays and now', async () => { 34 | const ts = timestamp.parseTimestamp('2022-08-08') 35 | const tests = timestamp.getStartOfWeek(ts, [1, 2, 3, 4, 5], timestamp.parseDate(new Date())) 36 | expect(tests.day).toBe(8) 37 | }) 38 | 39 | it('getStartOfWeek 2022-08-01, restricted weekdays, on 1st with now', async () => { 40 | const ts = timestamp.parseTimestamp('2022-08-01') 41 | const tests = timestamp.getStartOfWeek(ts, [2, 3, 4, 5], timestamp.parseDate(new Date())) 42 | expect(tests.day).toBe(2) 43 | }) 44 | }) 45 | -------------------------------------------------------------------------------- /packages/ui/test/getWeekdayNames.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import * as timestamp from '../src/utils/Timestamp' 3 | 4 | describe('[TIMESTAMP] getWeekdayNames', () => { 5 | it('getWeekdayNames (long en-US)', async () => { 6 | const names = timestamp.getWeekdayNames('long', 'en-US') 7 | expect(names).toEqual([ 8 | 'Sunday', 9 | 'Monday', 10 | 'Tuesday', 11 | 'Wednesday', 12 | 'Thursday', 13 | 'Friday', 14 | 'Saturday', 15 | ]) 16 | }) 17 | 18 | it('getWeekdayNames (short en-US)', async () => { 19 | const names = timestamp.getWeekdayNames('short', 'en-US') 20 | expect(names).toEqual(['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']) 21 | }) 22 | 23 | it('getWeekdayNames (narrow en-US)', async () => { 24 | const names = timestamp.getWeekdayNames('narrow', 'en-US') 25 | expect(names).toEqual(['S', 'M', 'T', 'W', 'T', 'F', 'S']) 26 | }) 27 | 28 | //--- 29 | 30 | it('getWeekdayNames (long se)', async () => { 31 | const names = timestamp.getWeekdayNames('long', 'se') 32 | expect(names).toEqual([ 33 | 'sotnabeaivi', 34 | 'vuossárga', 35 | 'maŋŋebárga', 36 | 'gaskavahkku', 37 | 'duorasdat', 38 | 'bearjadat', 39 | 'lávvardat', 40 | ]) 41 | }) 42 | 43 | it('getWeekdayNames (short se)', async () => { 44 | const names = timestamp.getWeekdayNames('short', 'se') 45 | expect(names).toEqual(['sotn', 'vuos', 'maŋ', 'gask', 'duor', 'bear', 'láv']) 46 | }) 47 | 48 | it('getWeekdayNames (narrow se)', async () => { 49 | const names = timestamp.getWeekdayNames('narrow', 'se') 50 | expect(names).toEqual(['S', 'V', 'M', 'G', 'D', 'B', 'L']) 51 | }) 52 | }) 53 | -------------------------------------------------------------------------------- /packages/ui/test/getWorkWeek.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import * as timestamp from '../src/utils/Timestamp' 3 | 4 | describe('[TIMESTAMP] getWorkWeek', () => { 5 | it('getWorkWeek 2021-01-01', async () => { 6 | const ts = timestamp.parsed('2021-01-01') 7 | const tests = timestamp.getWorkWeek(ts) 8 | expect(tests).toStrictEqual(53) 9 | }) 10 | 11 | it('getWorkWeek 2021-01-04 (the 4th is always in week 1)', async () => { 12 | const ts = timestamp.parsed('2021-01-04') 13 | const tests = timestamp.getWorkWeek(ts) 14 | expect(tests).toStrictEqual(1) 15 | }) 16 | 17 | it('getWorkWeek when year is 0', async () => { 18 | const ts = timestamp.parsed('2021-01-04') 19 | ts.year = 0 20 | const tests = timestamp.getWorkWeek(ts) 21 | const today = timestamp.parseTimestamp(timestamp.today()) 22 | expect(tests).toStrictEqual(today.workweek) 23 | }) 24 | 25 | it('getWorkWeek 2021-12-31', async () => { 26 | const ts = timestamp.parsed('2021-12-32') 27 | const tests = timestamp.getWorkWeek(ts) 28 | expect(tests).toStrictEqual(52) 29 | }) 30 | }) 31 | -------------------------------------------------------------------------------- /packages/ui/test/isBetweenDates.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import * as timestamp from '../src/utils/Timestamp' 3 | 4 | describe('[TIMESTAMP] isBetweenDates', () => { 5 | it('isBetweenDates 2002-01-01 and 2020-12-31', async () => { 6 | const start = timestamp.parsed('2020-01-01') 7 | const end = timestamp.parsed('2020-12-31') 8 | const date = timestamp.parsed('2020-01-01') 9 | const tests = timestamp.isBetweenDates(date, start, end) 10 | expect(tests).toBe(true) 11 | }) 12 | 13 | it('isBetweenDates (false)', async () => { 14 | const start = timestamp.parsed('2020-01-01') 15 | const end = timestamp.parsed('2020-12-31') 16 | const date = timestamp.parsed('2019-01-01') 17 | const tests = timestamp.isBetweenDates(date, start, end) 18 | expect(tests).toBe(false) 19 | }) 20 | 21 | it('isBetweenDates with time', async () => { 22 | const start = timestamp.parsed('2020-01-01 13:00') 23 | const end = timestamp.parsed('2020-01-01 13:05') 24 | const date = timestamp.parsed('2020-01-01 13:01') 25 | const tests = timestamp.isBetweenDates(date, start, end, true) 26 | expect(tests).toBe(true) 27 | }) 28 | 29 | it('isBetweenDates with time (false)', async () => { 30 | const start = timestamp.parsed('2020-01-01 13:00') 31 | const end = timestamp.parsed('2020-01-01 13:05') 32 | const date = timestamp.parsed('2020-01-01 13:06') 33 | const tests = timestamp.isBetweenDates(date, start, end, true) 34 | expect(tests).toBe(false) 35 | }) 36 | }) 37 | -------------------------------------------------------------------------------- /packages/ui/test/isLeapYear.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import * as timestamp from '../src/utils/Timestamp' 3 | 4 | describe('[TIMESTAMP] isLeapYear', () => { 5 | it('2020 is a Leap Year', async () => { 6 | const tests = timestamp.isLeapYear(2020) 7 | expect(tests).toBe(true) 8 | }) 9 | 10 | it('2019 is NOT a Leap Year', async () => { 11 | const tests = timestamp.isLeapYear(2019) 12 | expect(tests).toBe(false) 13 | }) 14 | 15 | it('2000 is a Leap Year', async () => { 16 | const tests = timestamp.isLeapYear(2000) 17 | expect(tests).toBe(true) 18 | }) 19 | 20 | it('2100 is NOT a Leap Year', async () => { 21 | const tests = timestamp.isLeapYear(2100) 22 | expect(tests).toBe(false) 23 | }) 24 | }) 25 | -------------------------------------------------------------------------------- /packages/ui/test/isOverlappingDates.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import * as timestamp from '../src/utils/Timestamp' 3 | 4 | describe('[TIMESTAMP] isOverlappingDates', () => { 5 | it('isOverlappingDates 2002-01-01/2020-01-10 and 2019-12-29/2020-01-04', async () => { 6 | const start = timestamp.parsed('2020-01-01') 7 | const end = timestamp.parsed('2020-01-10') 8 | const first = timestamp.parsed('2019-12-29') // start of week 9 | const last = timestamp.parsed('2020-01-04') // end of week 10 | const tests = timestamp.isOverlappingDates(start, end, first, last) 11 | expect(tests).toBe(true) 12 | }) 13 | 14 | it('isOverlappingDates 2002-01-01/2020-01-10 and 2020-12-29/2020-01-04', async () => { 15 | const start = timestamp.parsed('2020-01-01') 16 | const end = timestamp.parsed('2020-01-10') 17 | const first = timestamp.parsed('2020-01-29') // start of week 18 | const last = timestamp.parsed('2020-01-30') // end of week 19 | const tests = timestamp.isOverlappingDates(start, end, first, last) 20 | expect(tests).toBe(false) 21 | }) 22 | }) 23 | -------------------------------------------------------------------------------- /packages/ui/test/makeDateTime.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import * as timestamp from '../src/utils/Timestamp' 3 | 4 | describe('[TIMESTAMP] makeDateTime', () => { 5 | it('makeDateTime', async () => { 6 | const ts = timestamp.parsed('2019-12-31 23:59') 7 | const tests = timestamp.makeDateTime(ts) 8 | expect(tests).toStrictEqual(new Date('2019-12-31T23:59:00.000Z')) 9 | expect(tests.getFullYear()).toBe(2019) 10 | expect(tests.getMonth()).toBe(11) 11 | expect(tests.getDate()).toBe(31) 12 | }) 13 | 14 | it('makeDateTime and parseDate', async () => { 15 | const a = new Date(2021, 11, 28, 10, 0) 16 | const b = timestamp.parseDate(a) 17 | const c = timestamp.makeDateTime(b) 18 | expect(timestamp.compareDateTime(c, c)).toBe(true) 19 | }) 20 | }) 21 | -------------------------------------------------------------------------------- /packages/ui/test/maxTimestamp.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import * as timestamp from '../src/utils/Timestamp' 3 | 4 | describe('[TIMESTAMP] maxTimestamp', () => { 5 | it('Find the maximum timestamp (without time)', async () => { 6 | const timestamps = [timestamp.parsed('2021-11-07'), timestamp.parsed('2021-01-01')] 7 | const tests = timestamp.maxTimestamp(timestamps) 8 | expect(tests.date).toEqual('2021-11-07') 9 | }) 10 | 11 | it('Find the maximum timestamp (with time)', async () => { 12 | const timestamps = [timestamp.parsed('2021-11-07 01:13'), timestamp.parsed('2021-11-07 02:15')] 13 | const tests = timestamp.maxTimestamp(timestamps, true) 14 | expect(timestamp.compareDateTime(tests, timestamps[1])).toBe(true) 15 | }) 16 | 17 | it('Find the maximum timestamp with 2 equal timestamps', async () => { 18 | const timestamps = [timestamp.parsed('2021-11-07'), timestamp.parsed('2021-11-07')] 19 | const tests = timestamp.maxTimestamp(timestamps) 20 | expect(tests.date).toEqual('2021-11-07') 21 | }) 22 | }) 23 | -------------------------------------------------------------------------------- /packages/ui/test/minTimestamp.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import * as timestamp from '../src/utils/Timestamp' 3 | 4 | describe('[TIMESTAMP] minTimestamp', () => { 5 | it('Find the minimum timestamp (without time)', async () => { 6 | const timestamps = [timestamp.parsed('2021-11-07'), timestamp.parsed('2021-01-01')] 7 | const tests = timestamp.minTimestamp(timestamps) 8 | expect(tests.date).toEqual('2021-01-01') 9 | }) 10 | 11 | it('Find the minimum timestamp (with time)', async () => { 12 | const timestamps = [timestamp.parsed('2021-11-07 01:13'), timestamp.parsed('2021-11-07 02:15')] 13 | const tests = timestamp.minTimestamp(timestamps, true) 14 | expect(timestamp.compareDateTime(tests, timestamps[0])).toBe(true) 15 | }) 16 | 17 | it('Find the minimum timestamp with 2 equal timestamps', async () => { 18 | const timestamps = [timestamp.parsed('2021-11-07'), timestamp.parsed('2021-11-07')] 19 | const tests = timestamp.minTimestamp(timestamps) 20 | expect(tests.date).toEqual('2021-11-07') 21 | }) 22 | }) 23 | -------------------------------------------------------------------------------- /packages/ui/test/nextDay.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import { parsed, nextDay, type Timestamp } from '../src/utils/Timestamp' 3 | 4 | describe('[TIMESTAMP] nextDay', () => { 5 | it('nextDay rolls over to Jan 1, 2020 when given Dec 31, 2019', () => { 6 | const ts = parsed('2019-12-31') as Timestamp 7 | const result = nextDay(ts) 8 | expect(result.year).toBe(2020) 9 | expect(result.month).toBe(1) 10 | expect(result.day).toBe(1) 11 | }) 12 | 13 | it('nextDay rolls over to Feb 1, 2020 when given Jan 31, 2020', () => { 14 | const ts = parsed('2020-01-31') as Timestamp 15 | const result = nextDay(ts) 16 | expect(result.year).toBe(2020) 17 | expect(result.month).toBe(2) 18 | expect(result.day).toBe(1) 19 | }) 20 | }) 21 | -------------------------------------------------------------------------------- /packages/ui/test/padNumber.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import * as timestamp from '../src/utils/Timestamp' 3 | 4 | describe('[TIMESTAMP] padNumber', () => { 5 | it('padNumber 1, len 2', async () => { 6 | const tests = timestamp.padNumber(1, 2) 7 | expect(tests).toBe('01') 8 | }) 9 | 10 | it('padNumber 10, len 2', async () => { 11 | const tests = timestamp.padNumber(10, 2) 12 | expect(tests).toBe('10') 13 | }) 14 | 15 | it('padNumber 1, len 4', async () => { 16 | const tests = timestamp.padNumber(1, 4) 17 | expect(tests).toBe('0001') 18 | }) 19 | 20 | it('padNumber 10, len 4', async () => { 21 | const tests = timestamp.padNumber(10, 4) 22 | expect(tests).toBe('0010') 23 | }) 24 | }) 25 | -------------------------------------------------------------------------------- /packages/ui/test/parseDate.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import * as timestamp from '../src/utils/Timestamp' 3 | 4 | describe('[TIMESTAMP] parseDate', () => { 5 | it('parseDate no time', async () => { 6 | const tests = timestamp.parseDate(new Date(2020, 0, 1)) 7 | expect(tests.hasDay).toBe(true) 8 | expect(tests.hasTime).toBe(true) 9 | expect(tests.year).toBe(2020) 10 | expect(tests.month).toBe(1) 11 | expect(tests.day).toBe(1) 12 | }) 13 | 14 | it('parseTimestamp with time', async () => { 15 | const tests = timestamp.parseDate(new Date(2020, 0, 1, 3, 0)) 16 | expect(tests.hasDay).toBe(true) 17 | expect(tests.hasTime).toBe(true) 18 | expect(tests.year).toBe(2020) 19 | expect(tests.month).toBe(1) 20 | expect(tests.day).toBe(1) 21 | expect(tests.hour).toBe(3) 22 | expect(tests.minute).toBe(0) 23 | }) 24 | }) 25 | -------------------------------------------------------------------------------- /packages/ui/test/parseTime.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import * as timestamp from '../src/utils/Timestamp' 3 | 4 | describe('[TIMESTAMP] parseTime', () => { 5 | it('parses time', async () => { 6 | const tests = timestamp.parseTime(141) 7 | expect(tests).toBe(141) 8 | }) 9 | 10 | it('parses time as a number', async () => { 11 | const tests = timestamp.parseTime(144) 12 | expect(tests).toBe(144) 13 | }) 14 | 15 | it('parses time as a string', async () => { 16 | const tests = timestamp.parseTime('2:24') 17 | expect(tests).toBe(144) 18 | }) 19 | 20 | it('parses time as an object', async () => { 21 | const tests = timestamp.parseTime({ hour: 2, minute: 24 }) 22 | expect(tests).toBe(144) 23 | }) 24 | 25 | it('parses time invalid string', async () => { 26 | const tests = timestamp.parseTime('elephant') 27 | expect(tests).toBe(false) 28 | }) 29 | 30 | it('parses time invalid object', async () => { 31 | const tests = timestamp.parseTime({ hour: 'elephant', minute: 'zebra' }) 32 | expect(tests).toBe(false) 33 | }) 34 | 35 | it('parses time invalid type (Date)', async () => { 36 | const tests = timestamp.parseTime(new Date()) 37 | expect(tests).toBe(false) 38 | }) 39 | 40 | it('parses time invalid type (Array)', async () => { 41 | const tests = timestamp.parseTime(['2:24']) 42 | expect(tests).toBe(false) 43 | }) 44 | }) 45 | -------------------------------------------------------------------------------- /packages/ui/test/parsed.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import * as timestamp from '../src/utils/Timestamp' 3 | 4 | describe('[TIMESTAMP] parsed', () => { 5 | it('parses date', async () => { 6 | const tests = timestamp.parsed('2020-01-01') 7 | expect(tests.year).toBe(2020) 8 | expect(tests.month).toBe(1) 9 | expect(tests.day).toBe(1) 10 | expect(tests.hasTime).toBe(true) 11 | }) 12 | 13 | it('parses date and time', async () => { 14 | const tests = timestamp.parsed('2020-01-01 03:01') 15 | expect(tests.year).toBe(2020) 16 | expect(tests.month).toBe(1) 17 | expect(tests.day).toBe(1) 18 | expect(tests.hasTime).toBe(true) 19 | expect(tests.hour).toBe(3) 20 | expect(tests.minute).toBe(1) 21 | }) 22 | 23 | it('parses date and time (short)', async () => { 24 | const tests = timestamp.parsed('2020-1-1 3:01') 25 | expect(tests.year).toBe(2020) 26 | expect(tests.month).toBe(1) 27 | expect(tests.day).toBe(1) 28 | expect(tests.hasTime).toBe(true) 29 | expect(tests.hour).toBe(3) 30 | expect(tests.minute).toBe(1) 31 | }) 32 | 33 | it('parses invalid', async () => { 34 | const tests = timestamp.parsed('1234') 35 | expect(tests).toBe(null) 36 | }) 37 | }) 38 | -------------------------------------------------------------------------------- /packages/ui/test/prevDay.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import { parsed, prevDay, type Timestamp } from '../src/utils/Timestamp' 3 | 4 | describe('[TIMESTAMP] prevDay', () => { 5 | it('prevDay rolls over to Dec 31, 2019 when given Jan 1, 2020', () => { 6 | const ts = parsed('2020-01-01') as Timestamp 7 | const result = prevDay(ts) 8 | expect(result.year).toBe(2019) 9 | expect(result.month).toBe(12) 10 | expect(result.day).toBe(31) 11 | }) 12 | 13 | it('prevDay rolls over to Jan 31, 2020 when given Feb 1, 2020', () => { 14 | const ts = parsed('2020-02-01') as Timestamp 15 | const result = prevDay(ts) 16 | expect(result.year).toBe(2020) 17 | expect(result.month).toBe(1) 18 | expect(result.day).toBe(31) 19 | }) 20 | }) 21 | -------------------------------------------------------------------------------- /packages/ui/test/timeIdentifier.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import * as timestamp from '../src/utils/Timestamp' 3 | 4 | describe('[TIMESTAMP] getTimeIdentifier', () => { 5 | it('getTimeIdentifier 2020-01-01 13:05', async () => { 6 | const ts = timestamp.parsed('2020-01-01 13:05') 7 | const tests = timestamp.getTimeIdentifier(ts) 8 | expect(tests).toBe(1305) 9 | }) 10 | 11 | it('getTimeIdentifier 2020-01-31 17:28', async () => { 12 | const ts = timestamp.parsed('2020-01-31 17:28') 13 | const tests = timestamp.getTimeIdentifier(ts) 14 | expect(tests).toBe(1728) 15 | }) 16 | 17 | it('getTimeIdentifier 2022-08-08 24:13', async () => { 18 | const ts = timestamp.parsed('2022-08-08 24:13') 19 | const tests = timestamp.getTimeIdentifier(ts) 20 | expect(tests).toBe(2413) 21 | }) 22 | 23 | it('getTimeIdentifier 2022-08-08 00:13', async () => { 24 | const ts = timestamp.parsed('2022-08-08 00:13') 25 | const tests = timestamp.getTimeIdentifier(ts) 26 | expect(tests).toBe(13) 27 | }) 28 | 29 | it('getTimeIdentifier no time given', async () => { 30 | const ts = timestamp.parsed('2022-08-08') 31 | const tests = timestamp.getTimeIdentifier(ts) 32 | expect(tests).toBe(0) 33 | }) 34 | }) 35 | -------------------------------------------------------------------------------- /packages/ui/test/today.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import * as timestamp from '../src/utils/Timestamp' 3 | 4 | describe('today', () => { 5 | it('today', async () => { 6 | const today = timestamp.today() 7 | const d = new Date(), 8 | month = '' + (d.getMonth() + 1), 9 | day = '' + d.getDate(), 10 | year = d.getFullYear() 11 | 12 | const now = [ 13 | year, 14 | timestamp.padNumber(Number(month), 2), 15 | timestamp.padNumber(Number(day), 2), 16 | ].join('-') 17 | expect(today).toBe(now) 18 | }) 19 | }) 20 | -------------------------------------------------------------------------------- /packages/ui/test/updateDayOfYear.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import { parseTimestamp, updateDayOfYear, type Timestamp } from '../src/utils/Timestamp' 3 | 4 | describe('[TIMESTAMP] updateDayOfYear', () => { 5 | it('updateDayOfYear Jan 1', async () => { 6 | const ts = parseTimestamp('2020-01-01') as Timestamp 7 | const tests = updateDayOfYear(ts) 8 | expect(tests.doy).toBe(1) 9 | }) 10 | 11 | it('updateDayOfYear Dec 31 2020 (Leap Year)', async () => { 12 | const ts = parseTimestamp('2020-12-31') as Timestamp 13 | const tests = updateDayOfYear(ts) 14 | expect(tests.doy).toBe(366) 15 | }) 16 | 17 | it('updateDayOfYear Dec 31 2019 (NOT Leap Year)', async () => { 18 | const ts = parseTimestamp('2019-12-31') as Timestamp 19 | const tests = updateDayOfYear(ts) 20 | expect(tests.doy).toBe(365) 21 | }) 22 | 23 | it('updateDayOfYear invalid (0)', async () => { 24 | const ts = parseTimestamp('2020-01-01') as Timestamp 25 | ts.year = 0 26 | const tests = updateDayOfYear(ts) 27 | expect(tests.doy).toBe(0) 28 | }) 29 | }) 30 | -------------------------------------------------------------------------------- /packages/ui/test/updateDisabled.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import * as timestamp from '../src/utils/Timestamp' 3 | 4 | describe('[TIMESTAMP] updateDisabled', () => { 5 | const disabledDays = ['2020-01-01', '2020-01-02', '2020-01-03'] 6 | it('Jan 2020 has 31 days', async () => { 7 | const ts = timestamp.parsed('2020-01-01') 8 | const tests = timestamp.updateDisabled(ts, undefined, undefined, undefined, disabledDays) 9 | expect(tests.disabled).toBe(true) 10 | }) 11 | }) 12 | 13 | describe('[TIMESTAMP] updateDisabled (range)', () => { 14 | const disabledDays = [['2020-01-01', '2020-01-03']] 15 | it('Jan 2020 has 31 days', async () => { 16 | const ts = timestamp.parsed('2020-01-01') 17 | const tests = timestamp.updateDisabled(ts, undefined, undefined, undefined, disabledDays) 18 | expect(tests.disabled).toBe(true) 19 | }) 20 | }) 21 | -------------------------------------------------------------------------------- /packages/ui/test/updateDisabledBeforeAfter.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import * as timestamp from '../src/utils/Timestamp' 3 | 4 | describe('[TIMESTAMP] updateDisabled', () => { 5 | const disabledBefore = '2020-01-01' 6 | const disabledAfter = '2019-12-31' 7 | const disabledWeekdays = [0, 2, 4, 6] 8 | it('Jan 2020 has 31 days', async () => { 9 | const ts1 = timestamp.parsed('2020-01-01') 10 | const tests1 = timestamp.updateDisabled( 11 | ts1, 12 | disabledBefore, 13 | disabledAfter, 14 | undefined, 15 | undefined, 16 | ) 17 | 18 | const ts2 = timestamp.parsed('2020-01-01') 19 | const tests2 = timestamp.updateDisabled(ts2, undefined, disabledAfter, undefined, undefined) 20 | 21 | const ts3 = timestamp.parsed('2020-01-01') 22 | const tests3 = timestamp.updateDisabled(ts3, undefined, undefined, disabledWeekdays, undefined) 23 | 24 | expect(tests1.disabled).toBe(true) 25 | expect(tests2.disabled).toBe(true) 26 | expect(tests3.disabled).toBe(true) 27 | }) 28 | }) 29 | -------------------------------------------------------------------------------- /packages/ui/test/updateMinutes.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import * as timestamp from '../src/utils/Timestamp' 3 | 4 | describe('[TIMESTAMP] updateMinutes', () => { 5 | it('updateMinutes 2020-01-01 03:00 + 300', async () => { 6 | const ts = timestamp.parseTimestamp('2020-01-01 03:00') 7 | const tests = timestamp.updateMinutes(ts, 300) 8 | expect(tests.hasTime).toBe(true) 9 | expect(tests.hour).toBe(5) 10 | expect(tests.minute).toBe(0) 11 | }) 12 | 13 | it('updateMinutes 2020-01-01 03:00 + 300, with now', async () => { 14 | const ts = timestamp.parseTimestamp('2020-01-01 03:00') 15 | const tests = timestamp.updateMinutes(ts, 300, timestamp.parseDate(new Date())) 16 | expect(tests.hasTime).toBe(true) 17 | expect(tests.hour).toBe(5) 18 | expect(tests.minute).toBe(0) 19 | }) 20 | }) 21 | -------------------------------------------------------------------------------- /packages/ui/test/updateRelative.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import * as timestamp from '../src/utils/Timestamp' 3 | 4 | describe('[TIMESTAMP] updateRelative', () => { 5 | it('updateRelative 1 day', async () => { 6 | const ts = timestamp.parseTimestamp('2020-01-01') 7 | const tests = timestamp.updateRelative(ts, timestamp.parseTimestamp('2020-01-01')) 8 | expect(tests.future).toBe(false) 9 | expect(tests.current).toBe(true) 10 | expect(tests.past).toBe(false) 11 | }) 12 | 13 | it('updateRelative 1 day with time', async () => { 14 | const ts = timestamp.parseTimestamp('2020-01-01 03:00') 15 | const tests = timestamp.updateRelative(ts, timestamp.parseTimestamp('2020-01-01 03:00'), true) 16 | expect(tests.future).toBe(false) 17 | expect(tests.current).toBe(true) 18 | expect(tests.past).toBe(false) 19 | }) 20 | }) 21 | -------------------------------------------------------------------------------- /packages/ui/test/updateWeekday.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import * as timestamp from '../src/utils/Timestamp' 3 | 4 | describe('[TIMESTAMP] updateWeekday', () => { 5 | it('updateWeekday', async () => { 6 | const ts = timestamp.parseTimestamp('2020-01-01') 7 | const tests = timestamp.updateWeekday(ts) 8 | expect(tests.weekday).toBe(3) 9 | }) 10 | }) 11 | -------------------------------------------------------------------------------- /packages/ui/test/updateWorkWeek.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import * as timestamp from '../src/utils/Timestamp' 3 | 4 | describe('[TIMESTAMP] updateWorkWeek', () => { 5 | it('updateWorkWeek Jan 1', async () => { 6 | const ts = timestamp.parseTimestamp('2020-01-01') 7 | const tests = timestamp.updateWorkWeek(ts) 8 | expect(tests.workweek).toBe(1) 9 | }) 10 | 11 | it('updateWorkWeek Dec 31', async () => { 12 | const ts = timestamp.parseTimestamp('2020-12-31') 13 | const tests = timestamp.updateWorkWeek(ts) 14 | expect(tests.workweek).toBe(53) 15 | }) 16 | 17 | it('updateWorkWeek when year is 0', async () => { 18 | const ts = timestamp.parseTimestamp('2020-12-31') 19 | ts.year = 0 20 | const tests = timestamp.updateWorkWeek(ts) 21 | const today = timestamp.parseTimestamp(timestamp.today()) 22 | expect(tests.workweek).toBe(today.workweek) 23 | }) 24 | }) 25 | -------------------------------------------------------------------------------- /packages/ui/test/validateNumber.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import * as timestamp from '../src/utils/Timestamp' 3 | 4 | describe('[TIMESTAMP] validateNumber', () => { 5 | it('validateNumber true', async () => { 6 | const tests = timestamp.validateNumber(100) 7 | expect(tests).toBe(true) 8 | }) 9 | 10 | // takes 2020 11 | it("validateNumber true ('2020-01-01')", async () => { 12 | const tests = timestamp.validateNumber('2020-01-01') 13 | expect(tests).toBe(false) 14 | }) 15 | 16 | it("validateNumber true ('elephant')", async () => { 17 | const tests = timestamp.validateNumber('elephant') 18 | expect(tests).toBe(false) 19 | }) 20 | }) 21 | -------------------------------------------------------------------------------- /packages/ui/test/validateTimestamp.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import * as timestamp from '../src/utils/Timestamp' 3 | 4 | describe('[TIMESTAMP] validateTimestamp', () => { 5 | it('validateTimestamp correct', async () => { 6 | const tests = timestamp.validateTimestamp('2020-01-01') 7 | expect(tests).toBe(true) 8 | }) 9 | 10 | it('validateTimestamp with time correct', async () => { 11 | const tests = timestamp.validateTimestamp('2020-01-01 03:00') 12 | expect(tests).toBe(true) 13 | }) 14 | 15 | it('validateTimestamp incorrect', async () => { 16 | const tests = timestamp.validateTimestamp('2020/01/01') 17 | expect(tests).toBe(false) 18 | }) 19 | }) 20 | -------------------------------------------------------------------------------- /packages/ui/test/weeksBetween.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | import * as timestamp from '../src/utils/Timestamp' 3 | 4 | describe('[TIMESTAMP] weeksBetween', () => { 5 | it('weeksBetween 2020-01-01 and 2020-12-31', async () => { 6 | const start = timestamp.parsed('2020-01-01') 7 | const end = timestamp.parsed('2020-12-31') 8 | const tests = timestamp.weeksBetween(start, end) 9 | expect(tests).toBe(53) 10 | }) 11 | 12 | it('weeksBetween 2019-01-01 and 2019-12-31 (NOT Leap Year)', async () => { 13 | const start = timestamp.parsed('2019-01-01') 14 | const end = timestamp.parsed('2019-12-31') 15 | const tests = timestamp.weeksBetween(start, end) 16 | expect(tests).toBe(53) 17 | }) 18 | 19 | it('weeksBetween 2000-01-01 and 2000-12-31 (Leap Year)', async () => { 20 | const start = timestamp.parsed('2000-01-01') 21 | const end = timestamp.parsed('2000-12-31') 22 | const tests = timestamp.weeksBetween(start, end) 23 | expect(tests).toBe(53) 24 | }) 25 | 26 | it('weeksBetween 2020-01-01 and 2020-03-31 (Leap Year)', async () => { 27 | const start = timestamp.parsed('2020-01-01') 28 | const end = timestamp.parsed('2020-03-31') 29 | const tests = timestamp.weeksBetween(start, end) 30 | expect(tests).toBe(14) 31 | }) 32 | 33 | it('weeksBetween 2019-01-01 and 2019-03-31 (Leap Year)', async () => { 34 | const start = timestamp.parsed('2019-01-01') 35 | const end = timestamp.parsed('2019-03-31') 36 | const tests = timestamp.weeksBetween(start, end) 37 | expect(tests).toBe(14) 38 | }) 39 | }) 40 | -------------------------------------------------------------------------------- /packages/ui/tsconfig.base.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "compilerOptions": { 4 | "allowJs": false, 5 | "allowUmdGlobalAccess": false, 6 | "allowUnreachableCode": false, 7 | "allowUnusedLabels": false, 8 | "alwaysStrict": true, 9 | "checkJs": false, 10 | "declaration": true, 11 | "declarationMap": false, 12 | "exactOptionalPropertyTypes": false, 13 | "forceConsistentCasingInFileNames": true, 14 | "isolatedModules": true, 15 | "newLine": "lf", 16 | "noFallthroughCasesInSwitch": false, 17 | "noImplicitAny": true, 18 | "noImplicitOverride": true, 19 | "noImplicitReturns": true, 20 | "noImplicitThis": true, 21 | "noPropertyAccessFromIndexSignature": false, 22 | "noStrictGenericChecks": false, 23 | "noUncheckedIndexedAccess": false, 24 | "noUncheckedSideEffectImports": true, 25 | "noUnusedLocals": false, 26 | "noUnusedParameters": false, 27 | "removeComments": false, 28 | "resolveJsonModule": true, 29 | "sourceMap": false, 30 | "strict": true, 31 | "strictBindCallApply": true, 32 | "strictBuiltinIteratorReturn": true, 33 | "strictFunctionTypes": true, 34 | "strictNullChecks": true, 35 | "strictPropertyInitialization": true, 36 | "stripInternal": true, 37 | "useUnknownInCatchVariables": true 38 | // "verbatimModuleSyntax": true 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /packages/ui/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "module": "esnext", 5 | "target": "esnext", 6 | "lib": ["esnext", "dom"], 7 | "declaration": true, 8 | "emitDeclarationOnly": true, 9 | "moduleResolution": "bundler", 10 | "esModuleInterop": true, 11 | "allowJs": true, 12 | "outDir": "dist", 13 | "baseUrl": ".", 14 | "paths": { 15 | "components/*": ["src/components/*"], 16 | "directives/*": ["src/directives/*"], 17 | "composables/*": ["src/composables/*"], 18 | "utils/*": ["src/utils/*"] 19 | } 20 | }, 21 | "include": ["src/**/*"], 22 | "exclude": ["node_modules", "dist", "build"] 23 | } 24 | -------------------------------------------------------------------------------- /packages/ui/types/ts-helpers.d.ts: -------------------------------------------------------------------------------- 1 | export type LooseDictionary = { [index in string]: any }; 2 | 3 | export type StringDictionary = Required< 4 | { [index in T]: string } 5 | >; 6 | 7 | // See: https://stackoverflow.com/a/49936686/7931540 8 | export type DeepPartial = { 9 | [P in keyof T]?: T[P] extends Array 10 | ? Array> 11 | : T[P] extends ReadonlyArray 12 | ? ReadonlyArray> 13 | : DeepPartial; 14 | }; 15 | -------------------------------------------------------------------------------- /packages/ui/utility/checkIndex.js: -------------------------------------------------------------------------------- 1 | /* global console */ 2 | import { getExports } from './getExports.js' 3 | 4 | /** 5 | * Tests the getExports function by retrieving named and default exports from '@quasar/quasar-ui-qcalendar'. 6 | * This function demonstrates the usage of getExports and logs the results to the console. 7 | * 8 | * @async 9 | * @function test 10 | * @returns {Promise} A promise that resolves when the exports are retrieved and logged. 11 | */ 12 | async function test() { 13 | const { namedExports, defaultExport } = await getExports('@quasar/quasar-ui-qcalendar') 14 | 15 | console.log('Named Exports:', namedExports) 16 | console.log('Default Export:', defaultExport) 17 | } 18 | 19 | test() 20 | -------------------------------------------------------------------------------- /packages/ui/utility/getExports.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Retrieves named exports and the default export from a given JavaScript module. 3 | * 4 | * @param {string} modulePath - The path to the JavaScript module to import. 5 | * @returns {Promise<{namedExports: string[], defaultExport: any}>} 6 | * - A Promise that resolves to an object containing the named exports and the default export. 7 | * - `namedExports` is an array of strings representing the named exports from the module. 8 | * - `defaultExport` is the default export from the module. 9 | */ 10 | export async function getExports(modulePath) { 11 | const module = await import(modulePath) 12 | const namedExports = Object.keys(module).filter((key) => key !== 'default') 13 | const defaultExport = module.default 14 | 15 | return { 16 | namedExports, 17 | defaultExport, 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - 'packages/*' 3 | -------------------------------------------------------------------------------- /tsconfig.base.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "compilerOptions": { 4 | "allowJs": false, 5 | "allowUmdGlobalAccess": false, 6 | "allowUnreachableCode": false, 7 | "allowUnusedLabels": false, 8 | "alwaysStrict": true, 9 | "checkJs": false, 10 | "declaration": true, 11 | "declarationMap": false, 12 | "exactOptionalPropertyTypes": false, 13 | "forceConsistentCasingInFileNames": true, 14 | "isolatedModules": true, 15 | "newLine": "lf", 16 | "noFallthroughCasesInSwitch": false, 17 | "noImplicitAny": true, 18 | "noImplicitOverride": true, 19 | "noImplicitReturns": true, 20 | "noImplicitThis": true, 21 | "noPropertyAccessFromIndexSignature": false, 22 | "noStrictGenericChecks": false, 23 | "noUncheckedIndexedAccess": false, 24 | "noUncheckedSideEffectImports": true, 25 | "noUnusedLocals": false, 26 | "noUnusedParameters": false, 27 | "removeComments": false, 28 | "resolveJsonModule": true, 29 | "sourceMap": false, 30 | "strict": true, 31 | "strictBindCallApply": true, 32 | "strictBuiltinIteratorReturn": true, 33 | "strictFunctionTypes": true, 34 | "strictNullChecks": true, 35 | "strictPropertyInitialization": true, 36 | "stripInternal": true, 37 | "useUnknownInCatchVariables": true 38 | // "verbatimModuleSyntax": true 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.base.json", 3 | "include": ["packages/**/*", "vitest.config.ts"], 4 | "exclude": ["node_modules", "dist"], 5 | "compilerOptions": { 6 | "esModuleInterop": true, 7 | "allowSyntheticDefaultImports": true, 8 | "lib": ["ES2022"], 9 | "module": "ES2022", 10 | "moduleResolution": "bundler", 11 | "target": "ES2022" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /vitest.config.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path' 2 | import { fileURLToPath } from 'node:url' 3 | import { defineConfig } from 'vitest/config' 4 | 5 | const root = path.dirname(fileURLToPath(import.meta.url)) 6 | 7 | export default defineConfig({ 8 | // resolve: { 9 | // alias: [ 10 | // { 11 | // find: /^@ui\/([^/]*)$/, 12 | // replacement: path.resolve(root, './packages/$1/src/index.ts'), 13 | // }, 14 | // ], 15 | // }, 16 | esbuild: { 17 | target: 'node20', 18 | }, 19 | test: { 20 | coverage: { 21 | include: ['packages/*/src/**/*.ts'], 22 | provider: 'istanbul', 23 | reporter: ['clover', 'json', 'lcov', 'text'], 24 | }, 25 | }, 26 | }) 27 | --------------------------------------------------------------------------------