Showing preview only (3,354K chars total). Download the full file or copy to clipboard to get everything.
Repository: dayflow-js/calendar
Branch: main
Commit: a45483faeab9
Files: 615
Total size: 3.0 MB
Directory structure:
gitextract_0efm8vjk/
├── .editorconfig
├── .github/
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ └── feature_request.md
│ └── workflows/
│ └── deploy.yml
├── .gitignore
├── .nojekyll
├── .npmignore
├── .oxfmtrc.jsonc
├── .oxlintrc.json
├── .vscode/
│ ├── extensions.json
│ └── settings.json
├── .zed/
│ └── settings.json
├── CHANGELOG.md
├── CNAME
├── CONTRIBUTING.md
├── LICENSE
├── README.ja.md
├── README.md
├── README.zh.md
├── examples/
│ ├── defaultCalendarExample/
│ │ └── defaultCalendarExample.tsx
│ ├── main.tsx
│ ├── styles/
│ │ └── tailwind.css
│ └── utils/
│ ├── palette.ts
│ └── sampleData.ts
├── index.html
├── lefthook.yml
├── package.json
├── packages/
│ ├── angular/
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── ng-packagr.json
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── lib/
│ │ │ │ ├── day-flow-calendar.component.ts
│ │ │ │ ├── day-flow-calendar.module.ts
│ │ │ │ └── day-flow-portal.directive.ts
│ │ │ └── public-api.ts
│ │ └── tsconfig.json
│ ├── core/
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── bundle-analysis.html
│ │ ├── jest.config.mjs
│ │ ├── package.json
│ │ ├── postcss.build.mjs
│ │ ├── rollup.config.js
│ │ ├── scripts/
│ │ │ ├── atomic-css-baseline.json
│ │ │ ├── atomic-css-guard-utils.mjs
│ │ │ ├── build-css.mjs
│ │ │ ├── check-dist-styling.mjs
│ │ │ └── check-semantic-css.mjs
│ │ ├── src/
│ │ │ ├── components/
│ │ │ │ ├── calendarEvent/
│ │ │ │ │ ├── CalendarEvent.tsx
│ │ │ │ │ ├── __tests__/
│ │ │ │ │ │ ├── CalendarEvent.contract.test.tsx
│ │ │ │ │ │ └── CalendarEvent.timezone.test.tsx
│ │ │ │ │ ├── components/
│ │ │ │ │ │ ├── AllDayContent.tsx
│ │ │ │ │ │ ├── EventContent.tsx
│ │ │ │ │ │ ├── EventDetailPanel.tsx
│ │ │ │ │ │ ├── MonthAllDayContent.tsx
│ │ │ │ │ │ ├── MonthRegularContent.tsx
│ │ │ │ │ │ ├── RegularEventContent.tsx
│ │ │ │ │ │ ├── YearEventContent.tsx
│ │ │ │ │ │ └── __tests__/
│ │ │ │ │ │ ├── EventContent.test.tsx
│ │ │ │ │ │ └── RegularEventContent.test.tsx
│ │ │ │ │ ├── hooks/
│ │ │ │ │ │ ├── __tests__/
│ │ │ │ │ │ │ └── useEventActions.test.tsx
│ │ │ │ │ │ ├── useClickOutside.ts
│ │ │ │ │ │ ├── useDetailPanelPosition.ts
│ │ │ │ │ │ ├── useEventActions.ts
│ │ │ │ │ │ ├── useEventInteraction.ts
│ │ │ │ │ │ ├── useEventStyles.ts
│ │ │ │ │ │ └── useEventVisibility.ts
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ ├── types.ts
│ │ │ │ │ └── utils.ts
│ │ │ │ ├── common/
│ │ │ │ │ ├── BlossomColorPicker.tsx
│ │ │ │ │ ├── CalendarHeader.tsx
│ │ │ │ │ ├── CalendarPicker.tsx
│ │ │ │ │ ├── CreateCalendarDialog.tsx
│ │ │ │ │ ├── DefaultColorPicker.tsx
│ │ │ │ │ ├── DefaultEventDetailDialog.tsx
│ │ │ │ │ ├── DefaultEventDetailPanel.tsx
│ │ │ │ │ ├── EventDetailPanelWithContent.tsx
│ │ │ │ │ ├── Icons.tsx
│ │ │ │ │ ├── LoadingButton.tsx
│ │ │ │ │ ├── MiniCalendar.tsx
│ │ │ │ │ ├── QuickCreateEventPopup.tsx
│ │ │ │ │ ├── TodayBox.tsx
│ │ │ │ │ ├── ViewHeader.tsx
│ │ │ │ │ ├── ViewSwitcher.tsx
│ │ │ │ │ └── __tests__/
│ │ │ │ │ ├── MiniCalendar.test.tsx
│ │ │ │ │ └── QuickCreateEventPopup.test.tsx
│ │ │ │ ├── contextMenu/
│ │ │ │ │ ├── __tests__/
│ │ │ │ │ │ └── utils.test.ts
│ │ │ │ │ ├── components/
│ │ │ │ │ │ ├── EventContextMenu.tsx
│ │ │ │ │ │ ├── GridContextMenu.tsx
│ │ │ │ │ │ └── __tests__/
│ │ │ │ │ │ └── readOnlyContextMenus.test.tsx
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ └── utils.ts
│ │ │ │ ├── dayView/
│ │ │ │ │ ├── DayContent.tsx
│ │ │ │ │ ├── RightPanel.tsx
│ │ │ │ │ ├── __tests__/
│ │ │ │ │ │ └── util.timezone.test.ts
│ │ │ │ │ └── util.ts
│ │ │ │ ├── eventLayout/
│ │ │ │ │ ├── calculate/
│ │ │ │ │ │ ├── grouping.ts
│ │ │ │ │ │ ├── layout.ts
│ │ │ │ │ │ ├── rebalance.ts
│ │ │ │ │ │ └── structure.ts
│ │ │ │ │ ├── constants.ts
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ ├── types.ts
│ │ │ │ │ └── utils.ts
│ │ │ │ ├── mobileEventDrawer/
│ │ │ │ │ ├── DefaultMobileEventDrawer.tsx
│ │ │ │ │ ├── __tests__/
│ │ │ │ │ │ └── DefaultMobileEventDrawer.test.tsx
│ │ │ │ │ ├── components/
│ │ │ │ │ │ ├── Switch.tsx
│ │ │ │ │ │ ├── TimePickerWheel.tsx
│ │ │ │ │ │ └── __tests__/
│ │ │ │ │ │ └── Switch.test.tsx
│ │ │ │ │ └── index.ts
│ │ │ │ ├── monthView/
│ │ │ │ │ ├── MultiDayEvent.tsx
│ │ │ │ │ ├── WeekComponent.tsx
│ │ │ │ │ ├── WeekDayCell.tsx
│ │ │ │ │ ├── __tests__/
│ │ │ │ │ │ └── WeekComponent.test.tsx
│ │ │ │ │ └── util.tsx
│ │ │ │ ├── search/
│ │ │ │ │ ├── MobileSearchDialog.tsx
│ │ │ │ │ ├── SearchDrawer.tsx
│ │ │ │ │ └── SearchResultsList.tsx
│ │ │ │ ├── weekView/
│ │ │ │ │ ├── AllDayRow.tsx
│ │ │ │ │ ├── CompactHeader.tsx
│ │ │ │ │ ├── TimeGrid.tsx
│ │ │ │ │ ├── __tests__/
│ │ │ │ │ │ └── util.timezone.test.ts
│ │ │ │ │ └── util.ts
│ │ │ │ └── yearView/
│ │ │ │ ├── DefaultYearView.tsx
│ │ │ │ ├── FixedWeekMonthRow.tsx
│ │ │ │ ├── FixedWeekYearView.tsx
│ │ │ │ ├── GridDayPopup.tsx
│ │ │ │ ├── GridYearView.tsx
│ │ │ │ ├── YearDayCell.tsx
│ │ │ │ ├── YearRowComponent.tsx
│ │ │ │ ├── __tests__/
│ │ │ │ │ ├── DefaultYearView.test.tsx
│ │ │ │ │ └── utils.test.ts
│ │ │ │ └── utils.ts
│ │ │ ├── contexts/
│ │ │ │ └── ThemeContext.tsx
│ │ │ ├── core/
│ │ │ │ ├── CalendarApp.ts
│ │ │ │ ├── CalendarStore.ts
│ │ │ │ ├── __tests__/
│ │ │ │ │ ├── CalendarApp.test.ts
│ │ │ │ │ ├── WeekViewConfig.test.ts
│ │ │ │ │ └── calendarRegistry.test.ts
│ │ │ │ ├── calendarRegistry.ts
│ │ │ │ ├── config.ts
│ │ │ │ ├── events/
│ │ │ │ │ └── EventManager.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── navigation/
│ │ │ │ │ └── NavigationController.ts
│ │ │ │ ├── permissions/
│ │ │ │ │ └── CalendarPermissions.ts
│ │ │ │ ├── plugins/
│ │ │ │ │ └── PluginManager.ts
│ │ │ │ └── useCalendarApp.ts
│ │ │ ├── factories/
│ │ │ │ ├── ViewAdapter.tsx
│ │ │ │ ├── createAgendaView.ts
│ │ │ │ ├── createDayView.ts
│ │ │ │ ├── createMonthView.ts
│ │ │ │ ├── createWeekView.ts
│ │ │ │ ├── createYearView.ts
│ │ │ │ └── index.ts
│ │ │ ├── hooks/
│ │ │ │ ├── __tests__/
│ │ │ │ │ └── useCalendarDrop.test.tsx
│ │ │ │ ├── useCalendarDrop.ts
│ │ │ │ ├── useDebouncedValue.ts
│ │ │ │ ├── useWeekViewSwipe.ts
│ │ │ │ └── virtualScroll/
│ │ │ │ ├── index.ts
│ │ │ │ ├── useVirtualMonthScroll.ts
│ │ │ │ └── useVirtualScroll.ts
│ │ │ ├── index.ts
│ │ │ ├── locale/
│ │ │ │ ├── LocaleContext.tsx
│ │ │ │ ├── LocaleProvider.tsx
│ │ │ │ ├── index.ts
│ │ │ │ ├── intl.ts
│ │ │ │ ├── locales/
│ │ │ │ │ ├── en.ts
│ │ │ │ │ └── index.ts
│ │ │ │ ├── translator.ts
│ │ │ │ ├── types.ts
│ │ │ │ ├── useLocale.ts
│ │ │ │ └── utils.ts
│ │ │ ├── plugins/
│ │ │ │ ├── dragBridge.ts
│ │ │ │ ├── eventsPlugin.ts
│ │ │ │ ├── index.ts
│ │ │ │ └── sidebarBridge.ts
│ │ │ ├── renderer/
│ │ │ │ ├── CalendarRenderer.tsx
│ │ │ │ ├── CalendarRoot.tsx
│ │ │ │ ├── ContentSlot.tsx
│ │ │ │ ├── CustomRenderingContext.ts
│ │ │ │ ├── CustomRenderingStore.ts
│ │ │ │ └── hooks/
│ │ │ │ ├── __tests__/
│ │ │ │ │ └── useSearchController.test.ts
│ │ │ │ ├── useAppSubscription.ts
│ │ │ │ ├── useEventDialogController.ts
│ │ │ │ ├── useQuickCreateController.ts
│ │ │ │ ├── useResponsive.ts
│ │ │ │ └── useSearchController.ts
│ │ │ ├── setupTests.ts
│ │ │ ├── styles/
│ │ │ │ ├── __tests__/
│ │ │ │ │ └── dist-css.test.ts
│ │ │ │ ├── classNames.ts
│ │ │ │ ├── core/
│ │ │ │ │ ├── common/
│ │ │ │ │ │ ├── forms-dialogs.css
│ │ │ │ │ │ └── header-controls.css
│ │ │ │ │ ├── events/
│ │ │ │ │ │ └── calendar-event.css
│ │ │ │ │ ├── overlays/
│ │ │ │ │ │ ├── mobile-event-drawer.css
│ │ │ │ │ │ └── quick-create.css
│ │ │ │ │ ├── search/
│ │ │ │ │ │ └── search.css
│ │ │ │ │ └── views/
│ │ │ │ │ └── layout.css
│ │ │ │ ├── core-components.css
│ │ │ │ ├── library-imports.css
│ │ │ │ ├── shared-foundation.css
│ │ │ │ ├── tailwind-components.css
│ │ │ │ └── tailwind.css
│ │ │ ├── types/
│ │ │ │ ├── calendar.ts
│ │ │ │ ├── calendarTypes.ts
│ │ │ │ ├── config.ts
│ │ │ │ ├── core.ts
│ │ │ │ ├── dragIndicator.ts
│ │ │ │ ├── event.ts
│ │ │ │ ├── eventDetail.ts
│ │ │ │ ├── factory.ts
│ │ │ │ ├── hook.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── layout.ts
│ │ │ │ ├── mobileEvent.ts
│ │ │ │ ├── monthView.ts
│ │ │ │ ├── plugin.ts
│ │ │ │ ├── search.ts
│ │ │ │ └── timezone.ts
│ │ │ ├── utils/
│ │ │ │ ├── __tests__/
│ │ │ │ │ ├── allDaySort.test.ts
│ │ │ │ │ ├── crossRegionDrag.test.ts
│ │ │ │ │ ├── eventHelpers.test.ts
│ │ │ │ │ ├── helpers.test.ts
│ │ │ │ │ ├── timeUtils.test.ts
│ │ │ │ │ └── timeZoneUtils.test.ts
│ │ │ │ ├── allDaySort.ts
│ │ │ │ ├── calendarApp/
│ │ │ │ │ ├── configSync.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── normalizedConfig.ts
│ │ │ │ │ └── viewConfigComparison.ts
│ │ │ │ ├── calendarDataUtils.ts
│ │ │ │ ├── clipboardStore.ts
│ │ │ │ ├── colorUtils.ts
│ │ │ │ ├── compareUtils.ts
│ │ │ │ ├── crossRegionDrag.ts
│ │ │ │ ├── dateConstants.ts
│ │ │ │ ├── dateFormat.ts
│ │ │ │ ├── dateRangeUtils.ts
│ │ │ │ ├── dateTimeUtils.ts
│ │ │ │ ├── eventHelpers.ts
│ │ │ │ ├── eventUtils.ts
│ │ │ │ ├── helpers.ts
│ │ │ │ ├── ics/
│ │ │ │ │ ├── __tests__/
│ │ │ │ │ │ └── ics.test.ts
│ │ │ │ │ ├── icsGenerator.ts
│ │ │ │ │ ├── icsParser.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── types.ts
│ │ │ │ │ └── utils.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── logger.ts
│ │ │ │ ├── searchUtils.ts
│ │ │ │ ├── styleUtils.ts
│ │ │ │ ├── subscriptionUtils.ts
│ │ │ │ ├── temporal.ts
│ │ │ │ ├── temporalTypeGuards.ts
│ │ │ │ ├── testDataUtils.ts
│ │ │ │ ├── themeUtils.ts
│ │ │ │ ├── throttle.ts
│ │ │ │ ├── timeUtils.ts
│ │ │ │ ├── timeZoneUtils.ts
│ │ │ │ └── utilityFunctions.ts
│ │ │ └── views/
│ │ │ ├── AgendaView.tsx
│ │ │ ├── DayView.tsx
│ │ │ ├── MonthView.tsx
│ │ │ ├── WeekView.tsx
│ │ │ ├── YearView.tsx
│ │ │ └── utils/
│ │ │ ├── __tests__/
│ │ │ │ └── weekView.test.ts
│ │ │ ├── dragCreate.ts
│ │ │ └── weekView.ts
│ │ ├── tsconfig.build.json
│ │ ├── tsconfig.json
│ │ └── vite.config.ts
│ ├── create-dayflow/
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src/
│ │ │ └── index.ts
│ │ ├── tsconfig.json
│ │ └── tsup.config.ts
│ ├── plugins/
│ │ ├── drag/
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── jest.config.mjs
│ │ │ ├── package.json
│ │ │ ├── rollup.config.js
│ │ │ ├── src/
│ │ │ │ ├── components/
│ │ │ │ │ ├── DefaultDragIndicator.tsx
│ │ │ │ │ ├── DragIndicatorComponent.tsx
│ │ │ │ │ ├── MonthDragIndicator.tsx
│ │ │ │ │ └── __tests__/
│ │ │ │ │ └── MonthDragIndicator.test.tsx
│ │ │ │ ├── hooks/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── useDrag.ts
│ │ │ │ │ ├── useDragCommon.ts
│ │ │ │ │ ├── useDragHandlers.ts
│ │ │ │ │ ├── useDragManager.ts
│ │ │ │ │ ├── useDragState.ts
│ │ │ │ │ ├── useMonthDrag.ts
│ │ │ │ │ ├── useWeekDayDrag.ts
│ │ │ │ │ └── utils/
│ │ │ │ │ ├── __tests__/
│ │ │ │ │ │ ├── dateGridDrag.test.ts
│ │ │ │ │ │ ├── eventEditing.test.ts
│ │ │ │ │ │ ├── indicatorColor.test.ts
│ │ │ │ │ │ └── resolveDragSourceElement.test.ts
│ │ │ │ │ ├── dateGridDrag.ts
│ │ │ │ │ ├── dragInteraction.ts
│ │ │ │ │ ├── eventEditing.ts
│ │ │ │ │ ├── indicatorColor.ts
│ │ │ │ │ ├── resolveDragSourceElement.ts
│ │ │ │ │ └── weekDay/
│ │ │ │ │ ├── __tests__/
│ │ │ │ │ │ ├── completion.test.ts
│ │ │ │ │ │ ├── crossRegion.test.ts
│ │ │ │ │ │ ├── drag.test.ts
│ │ │ │ │ │ ├── layout.test.ts
│ │ │ │ │ │ └── preview.test.ts
│ │ │ │ │ ├── completion.ts
│ │ │ │ │ ├── crossRegion.ts
│ │ │ │ │ ├── drag.ts
│ │ │ │ │ ├── layout.ts
│ │ │ │ │ └── preview.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── plugin.ts
│ │ │ │ ├── styles/
│ │ │ │ │ └── drag.css
│ │ │ │ └── utils/
│ │ │ │ ├── defaultDragConfig.ts
│ │ │ │ └── throttle.ts
│ │ │ ├── tsconfig.build.json
│ │ │ └── tsconfig.json
│ │ ├── keyboard-shortcuts/
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── package.json
│ │ │ ├── rollup.config.js
│ │ │ ├── src/
│ │ │ │ ├── index.ts
│ │ │ │ └── plugin.ts
│ │ │ ├── tsconfig.build.json
│ │ │ └── tsconfig.json
│ │ ├── localization/
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── package.json
│ │ │ ├── rollup.config.js
│ │ │ ├── src/
│ │ │ │ ├── index.ts
│ │ │ │ ├── locales/
│ │ │ │ │ ├── de.ts
│ │ │ │ │ ├── es.ts
│ │ │ │ │ ├── fr.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── ja.ts
│ │ │ │ │ ├── ko.ts
│ │ │ │ │ ├── types.ts
│ │ │ │ │ └── zh.ts
│ │ │ │ └── plugin.ts
│ │ │ ├── tsconfig.build.json
│ │ │ └── tsconfig.json
│ │ └── sidebar/
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── rollup.config.js
│ │ ├── scripts/
│ │ │ └── build-css.mjs
│ │ ├── src/
│ │ │ ├── DefaultCalendarSidebar.tsx
│ │ │ ├── components/
│ │ │ │ ├── CalendarChip.tsx
│ │ │ │ ├── CalendarList.tsx
│ │ │ │ ├── DeleteCalendarDialog.tsx
│ │ │ │ ├── ImportCalendarDialog.tsx
│ │ │ │ ├── MergeCalendarDialog.tsx
│ │ │ │ ├── MergeMenuItem.tsx
│ │ │ │ ├── SidebarHeader.tsx
│ │ │ │ └── SubscribeCalendarDialog.tsx
│ │ │ ├── index.ts
│ │ │ ├── plugin.ts
│ │ │ └── styles/
│ │ │ ├── sidebar.css
│ │ │ ├── tailwind-components.css
│ │ │ └── tailwind.css
│ │ ├── tsconfig.build.json
│ │ └── tsconfig.json
│ ├── react/
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── rollup.config.js
│ │ ├── src/
│ │ │ ├── DayFlowCalendar.tsx
│ │ │ ├── hooks/
│ │ │ │ └── useCalendarApp.ts
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── svelte/
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── index.d.ts
│ │ ├── package.json
│ │ ├── rollup.config.js
│ │ ├── src/
│ │ │ ├── DayFlowCalendar.svelte
│ │ │ ├── index.ts
│ │ │ ├── svelte-shims.d.ts
│ │ │ └── useCalendarApp.ts
│ │ ├── svelte.config.js
│ │ └── tsconfig.json
│ ├── ui/
│ │ ├── context-menu/
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── package.json
│ │ │ ├── rollup.config.js
│ │ │ ├── scripts/
│ │ │ │ └── build-css.mjs
│ │ │ ├── src/
│ │ │ │ ├── ContextMenu.tsx
│ │ │ │ ├── index.ts
│ │ │ │ └── styles/
│ │ │ │ ├── context-menu.css
│ │ │ │ ├── tailwind-components.css
│ │ │ │ └── tailwind.css
│ │ │ ├── tsconfig.build.json
│ │ │ └── tsconfig.json
│ │ └── range-picker/
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── rollup.config.js
│ │ ├── scripts/
│ │ │ └── build-css.mjs
│ │ ├── src/
│ │ │ ├── RangePicker.tsx
│ │ │ ├── components/
│ │ │ │ ├── CalendarGrid.tsx
│ │ │ │ ├── CalendarHeader.tsx
│ │ │ │ ├── RangePickerPanel.tsx
│ │ │ │ └── TimeSelector.tsx
│ │ │ ├── constants.ts
│ │ │ ├── icons.tsx
│ │ │ ├── index.ts
│ │ │ ├── styles/
│ │ │ │ ├── range-picker.css
│ │ │ │ ├── tailwind-components.css
│ │ │ │ └── tailwind.css
│ │ │ ├── types.ts
│ │ │ └── utils/
│ │ │ ├── locale.ts
│ │ │ ├── rangePicker.ts
│ │ │ └── temporal.ts
│ │ ├── tsconfig.build.json
│ │ └── tsconfig.json
│ └── vue/
│ ├── LICENSE
│ ├── README.md
│ ├── package.json
│ ├── rollup.config.js
│ ├── src/
│ │ ├── DayFlowCalendar.ts
│ │ ├── composables/
│ │ │ └── useCalendarApp.ts
│ │ ├── index.ts
│ │ └── vue-shims.d.ts
│ └── tsconfig.json
├── pnpm-workspace.yaml
├── postcss.config.mjs
├── scripts/
│ ├── git-tag.sh
│ ├── publish.sh
│ ├── setup-website.sh
│ └── update-versions.sh
├── tailwind.config.mjs
├── tsconfig.json
├── turbo.json
└── website/
├── .gitignore
├── .prettierrc
├── README.md
├── app/
│ ├── (home)/
│ │ ├── layout.tsx
│ │ └── page.tsx
│ ├── api/
│ │ └── search/
│ │ └── route.ts
│ ├── blog/
│ │ ├── [...slug]/
│ │ │ └── page.tsx
│ │ ├── layout.tsx
│ │ └── page.tsx
│ ├── docs/
│ │ ├── [[...slug]]/
│ │ │ └── page.tsx
│ │ └── layout.tsx
│ ├── docs-ja/
│ │ ├── [[...slug]]/
│ │ │ └── page.tsx
│ │ └── layout.tsx
│ ├── docs-zh/
│ │ ├── [[...slug]]/
│ │ │ └── page.tsx
│ │ └── layout.tsx
│ ├── global.css
│ ├── layout.tsx
│ ├── llms-full.txt/
│ │ └── route.ts
│ ├── llms.txt/
│ │ └── route.ts
│ ├── og/
│ │ └── docs/
│ │ └── [...slug]/
│ │ └── route.tsx
│ ├── robots.ts
│ ├── showcase/
│ │ └── mobile-event-detail/
│ │ └── page.tsx
│ └── sitemap.ts
├── components/
│ ├── AppProvider.tsx
│ ├── CliPreview.tsx
│ ├── ColorPalette.tsx
│ ├── DocsHeader.tsx
│ ├── DocsSearchDialog.tsx
│ ├── FrameworkInstall.tsx
│ ├── FrameworkTabs.tsx
│ ├── LanguageSwitcher.tsx
│ ├── ai/
│ │ └── page-actions.tsx
│ ├── showcase/
│ │ ├── ColorPickerShowcase.tsx
│ │ ├── ContextMenuShowcase.tsx
│ │ ├── CustomDetailDialogShowcase.tsx
│ │ ├── CustomDetailPanelShowcase.tsx
│ │ ├── EventContentShowcase.tsx
│ │ ├── FeatureShowcase.tsx
│ │ ├── InteractiveCalendar.tsx
│ │ ├── LiveDemo.tsx
│ │ ├── MobileEventDetailShowcase.tsx
│ │ ├── MultiCalendarEventShowcase.tsx
│ │ ├── SidebarShowcases.tsx
│ │ ├── livedemo/
│ │ │ ├── CalendarViewer.tsx
│ │ │ ├── ControlPanel.tsx
│ │ │ ├── MiniDotsFeature.tsx
│ │ │ ├── MultiCalFeature.tsx
│ │ │ ├── ThemeColorColumn.tsx
│ │ │ └── types.ts
│ │ └── mobile-event-detail/
│ │ └── MobileEventDetailSimulator.tsx
│ └── ui/
│ ├── alert.tsx
│ ├── badge.tsx
│ ├── button.tsx
│ ├── card.tsx
│ ├── checkbox.tsx
│ ├── label.tsx
│ ├── select.tsx
│ ├── separator.tsx
│ └── tooltip.tsx
├── content/
│ ├── blog/
│ │ ├── theme-customization.mdx
│ │ ├── v1.4.mdx
│ │ ├── v1.7.mdx
│ │ ├── v1.8.mdx
│ │ ├── v2.0.3.mdx
│ │ └── v3.0.mdx
│ ├── docs/
│ │ ├── features/
│ │ │ ├── calendar-header.mdx
│ │ │ ├── content-slots.mdx
│ │ │ ├── dark-mode.mdx
│ │ │ ├── event-dialog.mdx
│ │ │ ├── meta.json
│ │ │ ├── multi-calendar-event.mdx
│ │ │ ├── read-only.mdx
│ │ │ └── switcher-mode.mdx
│ │ ├── guides/
│ │ │ ├── global-css.mdx
│ │ │ ├── meta.json
│ │ │ ├── theme-customization.mdx
│ │ │ └── timezones.mdx
│ │ ├── introduction/
│ │ │ ├── dayflow-calendar.mdx
│ │ │ ├── events.mdx
│ │ │ ├── index.mdx
│ │ │ ├── meta.json
│ │ │ ├── pro-installation.mdx
│ │ │ ├── resource-grid.mdx
│ │ │ ├── resource-timeline.mdx
│ │ │ ├── use-calendar-app.mdx
│ │ │ └── views.mdx
│ │ ├── meta.json
│ │ ├── plugins/
│ │ │ ├── drag.mdx
│ │ │ ├── events.mdx
│ │ │ ├── keyboard-shortcuts.mdx
│ │ │ ├── localization.mdx
│ │ │ ├── meta.json
│ │ │ ├── overview.mdx
│ │ │ ├── print.mdx
│ │ │ └── sidebar.mdx
│ │ └── ui/
│ │ ├── context-menu.mdx
│ │ ├── meta.json
│ │ └── range-picker.mdx
│ ├── docs-ja/
│ │ ├── features/
│ │ │ ├── calendar-header.mdx
│ │ │ ├── content-slots.mdx
│ │ │ ├── dark-mode.mdx
│ │ │ ├── event-dialog.mdx
│ │ │ ├── meta.json
│ │ │ ├── multi-calendar-event.mdx
│ │ │ ├── read-only.mdx
│ │ │ └── switcher-mode.mdx
│ │ ├── guides/
│ │ │ ├── global-css.mdx
│ │ │ ├── meta.json
│ │ │ ├── theme-customization.mdx
│ │ │ └── timezones.mdx
│ │ ├── introduction/
│ │ │ ├── dayflow-calendar.mdx
│ │ │ ├── events.mdx
│ │ │ ├── index.mdx
│ │ │ ├── meta.json
│ │ │ ├── resource-grid.mdx
│ │ │ ├── resource-timeline.mdx
│ │ │ ├── use-calendar-app.mdx
│ │ │ └── views.mdx
│ │ ├── meta.json
│ │ ├── plugins/
│ │ │ ├── drag.mdx
│ │ │ ├── events.mdx
│ │ │ ├── keyboard-shortcuts.mdx
│ │ │ ├── localization.mdx
│ │ │ ├── meta.json
│ │ │ ├── overview.mdx
│ │ │ ├── print.mdx
│ │ │ └── sidebar.mdx
│ │ └── ui/
│ │ ├── context-menu.mdx
│ │ ├── meta.json
│ │ └── range-picker.mdx
│ └── docs-zh/
│ ├── features/
│ │ ├── calendar-header.mdx
│ │ ├── content-slots.mdx
│ │ ├── dark-mode.mdx
│ │ ├── event-dialog.mdx
│ │ ├── meta.json
│ │ ├── multi-calendar-event.mdx
│ │ ├── read-only.mdx
│ │ └── switcher-mode.mdx
│ ├── guides/
│ │ ├── global-css.mdx
│ │ ├── meta.json
│ │ ├── theme-customization.mdx
│ │ └── timezones.mdx
│ ├── introduction/
│ │ ├── dayflow-calendar.mdx
│ │ ├── events.mdx
│ │ ├── index.mdx
│ │ ├── meta.json
│ │ ├── resource-grid.mdx
│ │ ├── resource-timeline.mdx
│ │ ├── use-calendar-app.mdx
│ │ └── views.mdx
│ ├── meta.json
│ ├── plugins/
│ │ ├── drag.mdx
│ │ ├── events.mdx
│ │ ├── keyboard-shortcuts.mdx
│ │ ├── localization.mdx
│ │ ├── meta.json
│ │ ├── overview.mdx
│ │ ├── print.mdx
│ │ └── sidebar.mdx
│ └── ui/
│ ├── context-menu.mdx
│ ├── meta.json
│ └── range-picker.mdx
├── eslint.config.mjs
├── lib/
│ ├── cn.ts
│ ├── i18n.ts
│ ├── layout.shared.tsx
│ ├── site.ts
│ ├── source.tsx
│ └── utils.ts
├── mdx-components.tsx
├── next.config.mjs
├── package.json
├── postcss.config.mjs
├── source.config.ts
├── tsconfig.json
└── utils/
├── palette.ts
└── sampleData.ts
================================================
FILE CONTENTS
================================================
================================================
FILE: .editorconfig
================================================
root = true
[*]
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 2
charset = utf-8
trim_trailing_whitespace = true
max_line_length = 80
================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms
github: [JayceV552]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
polar: # Replace with a single Polar username
buy_me_a_coffee: # Replace with a single Buy Me a Coffee username
thanks_dev: # Replace with a single thanks.dev username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.
================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
================================================
FILE: .github/workflows/deploy.yml
================================================
name: Deploy to GitHub Pages
on:
push:
branches:
- main
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: 'pages'
cancel-in-progress: false
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install deps
run: |
cd website
npm install
- name: Build website
run: |
cd website
npm run build
env:
BASE_PATH: ''
NEXT_PUBLIC_BASE_PATH: ''
NEXT_PUBLIC_SITE_URL: https://calendar.dayflow.studio
- name: Disable Jekyll and verify output
run: |
ls -la website/
if [ -d "website/out" ]; then
touch website/out/.nojekyll
echo "calendar.dayflow.studio" > website/out/CNAME
echo "Created .nojekyll and CNAME in website/out"
else
echo "Error: website/out directory not found!"
exit 1
fi
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: website/out
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
================================================
FILE: .gitignore
================================================
# Dependencies
node_modules
.pnp
.pnp.js
# Testing
coverage
# Next.js
build
dist
website/.next
website/out
# Production
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Misc
.DS_Store
*.pem
# Debug
.vscode/*
!.vscode/settings.json
!.vscode/extensions.json
!.zed/settings.json
.idea
# Local env files
.env*.local
# Vercel
.vercel
# TypeScript
*.tsbuildinfo
next-env.d.ts
# Turbo
.turbo/
/bundle-analysis.html
temp/
*.tgz
================================================
FILE: .nojekyll
================================================
================================================
FILE: .npmignore
================================================
# Source files
src/
website/
examples/
# Development files
.git/
.gitignore
.vscode/
.idea/
# Build artifacts
.next/
node_modules/
# Logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Configuration files (keep only essential ones)
tsconfig.json
tsconfig.build.json
rollup.config.js
# Documentation (except README)
*.md
!README.md
# Test files
tests/
__tests__/
*.test.*
*.spec.*
coverage/
# Environment files
.env*
# OS files
.DS_Store
Thumbs.db
# Temporary files
*.tmp
*.temp
*.tgz
# Source maps (not needed in published package)
*.map
dist/**/*.map
================================================
FILE: .oxfmtrc.jsonc
================================================
// https://oxc.rs/docs/guide/usage/formatter/config-file-reference.html
{
"$schema": "./node_modules/oxfmt/configuration_schema.json",
"printWidth": 80,
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": true,
"quoteProps": "as-needed",
"jsxSingleQuote": true,
"trailingComma": "es5",
"bracketSpacing": true,
"bracketSameLine": false,
"arrowParens": "avoid",
"endOfLine": "lf",
"sortPackageJson": {
"sortScripts": true,
},
"sortImports": {
"ignoreCase": true,
"newlinesBetween": true,
"order": "asc",
},
"sortTailwindcss": {
"stylesheet": "./packages/core/src/styles/tailwind.css",
"attributes": ["class", "className"],
"functions": ["clsx", "cn", "cva", "tw"],
},
"ignorePatterns": [
"pnpm-lock.yaml",
"package-lock.json",
"yarn.lock",
"bun.lock",
"pnpm-workspace.yaml",
".turbo",
".cache",
".output",
"dist",
],
}
================================================
FILE: .oxlintrc.json
================================================
{
"$schema": "./node_modules/oxlint/configuration_schema.json",
"ignorePatterns": ["**/*.mdx"],
"plugins": [
"eslint",
"typescript",
"unicorn",
"oxc",
"import",
"jsdoc",
"node",
"promise",
"jest",
"vitest",
"react",
"react-perf",
"jsx-a11y",
"nextjs",
"vue"
],
"env": {
"browser": true
},
"categories": {
"correctness": "error",
"perf": "error",
"restriction": "error",
"suspicious": "error",
"pedantic": "error",
"style": "off"
},
"rules": {
"complexity": "off",
"no-await-in-loop": "off",
"max-lines-per-function": "off",
"no-inline-comments": "off",
"no-implicit-coercion": "off",
"no-magic-numbers": "off",
"no-console": "off",
"no-ternary": "off",
"no-undefined": "off",
"no-unused-vars": "warn",
"max-lines": "off",
"id-length": "off",
"func-style": "off",
"max-statements": "off",
"no-plusplus": "off",
"arrow-body-style": ["error", "as-needed"],
"max-depth": "off",
"max-params": "off",
"capitalized-comments": "off",
"new-cap": "off",
"no-continue": "off",
"no-barrel-file": "off",
"init-declarations": "off",
// Rely on oxfmt `sortImports` instead
"sort-imports": "off",
"sort-keys": "off",
"no-duplicate-imports": ["error", { "allowSeparateTypeImports": true }],
"import/no-default-export": "off",
"import/exports-last": "off",
"import/no-named-export": "off",
"import/max-dependencies": "off",
"import/no-unresolved": "off",
"import/extensions": "off",
"import/no-namespace": "off",
"import/no-anonymous-default-export": "off",
"import/prefer-default-export": "off",
"import/group-exports": "off",
"import/no-commonjs": "off",
"import/no-duplicates": "error",
"import/unambiguous": "off",
"import/consistent-type-specifier-style": ["error", "prefer-top-level"],
"import/no-dynamic-require": "off",
"import/no-unassigned-import": "off",
"import/no-relative-parent-imports": "error",
"jsdoc/require-param": "off",
"jsdoc/require-returns": "off",
"jsdoc/require-param-type": "off",
"jsdoc/require-returns-type": "off",
"unicorn/explicit-length-check": "off",
"unicorn/no-array-callback-reference": "off",
"unicorn/no-process-exit": "off",
"unicorn/prefer-global-this": "off",
"unicorn/no-null": "off",
"unicorn/prefer-top-level-await": "off",
"unicorn/prefer-string-raw": "off",
"unicorn/filename-case": "off",
"unicorn/no-array-for-each": "off",
"typescript/explicit-module-boundary-types": "off",
"typescript/explicit-function-return-type": "off",
"typescript/no-var-requires": "off",
"typescript/no-unused-vars": "warn",
"typescript/no-non-null-assertion": "off",
"typescript/no-require-imports": "off",
"typescript/require-await": "off",
"node/no-process-env": "off",
"oxc/no-map-spread": "off",
"oxc/no-async-await": "off",
"oxc/no-rest-spread-properties": "off",
"oxc/no-optional-chaining": "off",
"promise/catch-or-return": "off",
"promise/always-return": "off",
"vitest/prefer-called-times": "off",
"react/jsx-max-depth": "off",
"react/jsx-boolean-value": "off",
"react/jsx-filename-extension": "off",
"react/jsx-props-no-spreading": "off",
"react/jsx-no-constructed-context-values": "warn",
"react/no-array-index-key": "off",
"react/no-multi-comp": "off",
"react/no-unknown-property": "off",
"react/react-in-jsx-scope": "off",
"react/only-export-components": "off",
"react_perf/jsx-no-jsx-as-prop": "off",
"react_perf/jsx-no-new-object-as-prop": "off",
"react_perf/jsx-no-new-array-as-prop": "off",
"react_perf/jsx-no-new-function-as-prop": "off",
"react-hooks/exhaustive-deps": "off",
"jsx-a11y/alt-text": "warn",
"jsx-a11y/click-events-have-key-events": "off",
"jsx-a11y/heading-has-content": "warn",
"jsx-a11y/no-autofocus": "off",
"jsx-a11y/no-static-element-interactions": "off",
"nextjs/no-img-element": "warn"
},
"overrides": [
{
"files": ["**/next-env.d.ts"],
"rules": {
"import/no-unassigned-import": "off"
}
}
]
}
================================================
FILE: .vscode/extensions.json
================================================
{
"recommendations": [
"oxc.oxc-vscode",
"bradlc.vscode-tailwindcss",
"fill-labs.dependi",
"svelte.svelte-vscode",
"antfu.pnpm-catalog-lens",
"vue.volar"
]
}
================================================
FILE: .vscode/settings.json
================================================
{
"files.eol": "\n",
// Suppress CSS language-server warnings for Tailwind-specific at-rules
// (@apply, @variant, @theme, @source) that are valid PostCSS/Tailwind
// directives but unknown to the standard VS Code CSS validator.
"css.lint.unknownAtRules": "ignore",
"prettier.enable": false,
// "eslint.enable": false,
"oxc.enable": true,
"editor.tabSize": 2,
"editor.formatOnSave": true,
"editor.formatOnPaste": true,
"editor.defaultFormatter": "oxc.oxc-vscode",
"editor.codeActionsOnSave": {
"source.fixAll.oxc": "explicit"
},
"files.watcherExclude": {
"**/node_modules/**": true,
"**/dist/**": true,
"**/build/**": true,
"**/coverage/**": true
},
"search.exclude": {
"**/node_modules/**": true,
"**/dist/**": true,
"**/build/**": true,
"**/coverage/**": true
},
"[javascript]": {
"editor.defaultFormatter": "oxc.oxc-vscode"
},
"[javascriptreact]": {
"editor.defaultFormatter": "oxc.oxc-vscode"
},
"[typescript]": {
"editor.defaultFormatter": "oxc.oxc-vscode"
},
"[typescriptreact]": {
"editor.defaultFormatter": "oxc.oxc-vscode"
},
"[json]": {
"editor.defaultFormatter": "oxc.oxc-vscode"
},
"[jsonc]": {
"editor.defaultFormatter": "oxc.oxc-vscode"
},
"[css]": {
"editor.defaultFormatter": "oxc.oxc-vscode"
},
"[html]": {
"editor.defaultFormatter": "oxc.oxc-vscode"
},
"[vue]": {
"editor.defaultFormatter": "oxc.oxc-vscode"
},
"[vue-html]": {
"editor.defaultFormatter": "oxc.oxc-vscode"
},
"[markdown]": {
"editor.defaultFormatter": "oxc.oxc-vscode"
},
"[yaml]": {
"editor.defaultFormatter": "oxc.oxc-vscode"
},
"[tailwindcss]": {
"editor.defaultFormatter": "oxc.oxc-vscode"
}
}
================================================
FILE: .zed/settings.json
================================================
{
"formatter": "language_server",
"format_on_save": "on",
"languages": {
"JavaScript": {
"formatter": {
"language_server": {
"name": "oxfmt"
}
},
"code_actions_on_format": {
"source.fixAll.oxc": true,
"source.organizeImports.oxc": true
}
},
"TypeScript": {
"formatter": {
"language_server": {
"name": "oxfmt"
}
},
"code_actions_on_format": {
"source.fixAll.oxc": true,
"source.organizeImports.oxc": true
}
},
"TSX": {
"formatter": {
"language_server": {
"name": "oxfmt"
}
},
"code_actions_on_format": {
"source.fixAll.oxc": true,
"source.organizeImports.oxc": true
}
},
"JSON": {
"formatter": {
"language_server": {
"name": "oxfmt"
}
},
"code_actions_on_format": {
"source.fixAll.oxc": true,
"source.organizeImports.oxc": true
}
},
"JSONC": {
"formatter": {
"language_server": {
"name": "oxfmt"
}
},
"code_actions_on_format": {
"source.fixAll.oxc": true,
"source.organizeImports.oxc": true
}
},
"CSS": {
"formatter": {
"language_server": {
"name": "oxfmt"
}
},
"code_actions_on_format": {
"source.fixAll.oxc": true,
"source.organizeImports.oxc": true
}
},
"HTML": {
"formatter": {
"language_server": {
"name": "oxfmt"
}
},
"code_actions_on_format": {
"source.fixAll.oxc": true,
"source.organizeImports.oxc": true
}
},
"Markdown": {
"formatter": {
"language_server": {
"name": "oxfmt"
}
},
"code_actions_on_format": {
"source.fixAll.oxc": true,
"source.organizeImports.oxc": true
}
},
"YAML": {
"formatter": {
"language_server": {
"name": "oxfmt"
}
},
"code_actions_on_format": {
"source.fixAll.oxc": true,
"source.organizeImports.oxc": true
}
}
},
"lsp": {
"typescript-language-server": {
"settings": {
"typescript": {
"preferences": {
"includePackageJsonAutoImports": "on"
}
}
}
},
"oxlint": {
"initialization_options": {
"settings": {
"disableNestedConfig": false,
"fixKind": "safe_fix",
"run": "onType",
"typeAware": true,
"unusedDisableDirectives": "deny"
}
}
},
"oxfmt": {
"initialization_options": {
"settings": {
"configPath": null,
"flags": {},
"fmt.configPath": null,
"fmt.experimental": true,
"run": "onSave",
"typeAware": false,
"unusedDisableDirectives": false
}
}
}
}
}
================================================
FILE: CHANGELOG.md
================================================
# Changelog
All notable changes to this project will be documented in this file.
## [3.6.0] - 2026-05-03
### New Features & Enhancements
- **Agenda List View**: Added a new `createAgendaView` factory for a scrollable agenda-style list layout. Events are grouped by day with configurable options including `daysToShow`, `showEmptyDays`, and `timeFormat` (12h/24h). Supports both timed and all-day events, multi-day event continuation indicators, and full Content Slot integration.
- **Grid Date Click Callbacks**: Added `gridDateClick` and `gridDateDoubleClick` callbacks to Month and Week views, enabling click and double-click handlers on empty date/time grid cells.
- **Mobile Event Detail as Content Slot**: Migrated the internal `MobileEventDetailComponent` to the Content Slot system, making the mobile event detail panel fully customizable via framework render props.
- **Keyboard Shortcuts Callbacks**: Added lifecycle callbacks to the keyboard-shortcuts plugin (`onKeyDown`, `onKeyUp`, and per-action hooks) for programmatic integration and custom shortcut handling.
- **Sidebar `onReorder` Callback**: Added an `onReorder` callback to the sidebar plugin, fired whenever the user drags calendars to reorder them in the list.
### Fixed
- **Range Picker `startOfWeek` Prop**: Added `startOfWeek` configuration to the range picker component so the calendar grid respects the locale or app-level week start setting.
- **`useEventDetailPanel` API**: Moved `useEventDetailPanel` into `useCalendarApp`, making the event detail panel controls accessible from the same unified app hook across React, Vue, Angular, and Svelte.
- **Framework Adapter Rendering**: Updated core rendering and framework-specific adapters (Vue, Angular, Svelte) to align with the Content Slot architecture introduced in v3.5.0.
### Performance
- **View Rendering for Large Datasets**: Significantly optimized event layout calculations across Month, Week, Day, and Year views for calendars with large numbers of events.
- **Plugin Bundle Size**: Reduced bundle size for the drag, keyboard-shortcuts, localization, sidebar, and UI packages by streamlining rollup configurations.
- **Bundle Shrink & CSS Isolation**: Reduced the core bundle footprint and eliminated residual CSS conflicts by refining the build pipeline and library import boundaries.
## [3.5.0] - 2026-04-20
### New Features & Enhancements
- **Multi-calendar Events**: Added native `calendarIds` support on events. A single event can now belong to multiple calendars, stays visible as long as any linked calendar is visible, and renders with DayFlow's built-in multi-color striped styling.
### Fixed
- **Style Self-Containment**: Completed the style refactor so DayFlow no longer depends on internal atomic CSS classes or host-side `@source` scanning. `styles.css` and `styles.components.css` are now self-contained distribution artifacts.
- **Host Style Isolation**: Tightened `df-*` semantic styling contracts across core, UI packages, plugins, and dist CSS checks to reduce conflicts with UnoCSS, Tailwind, and other host styling systems.
- **Year / Day / Week View Polish**: Refined several view-specific layout details, including year-view event rendering, day/week timezone labels, and overlay/token usage in complex UI surfaces.
### Documentation
- Added multi-calendar event documentation and showcase examples.
- Refreshed the website live demo controls and interactive examples.
- Updated setup and theme customization guidance to match the self-contained styling model and remove outdated `@source`-based integration steps.
## [3.4.0] - 2026-04-06
### New Features & Enhancements
- **Global Calendar Time Zone**: Added `timeZone` to `useCalendarApp` / `CalendarAppConfig` as the primary display and editing timezone for all views. Day, Week, Month, and Year views now share the same calendar timezone semantics.
- **Secondary Timeline Refinement**: Kept `secondaryTimeZone` for Day and Week views as a dedicated secondary timeline display setting, independent from the calendar's primary timezone.
- **Mini Calendar Event Dots**: Added richer mini calendar event dot support, including calendar-color-aware dots with up to four unique indicators per day.
- **Interactive Demo Controls**: Updated the website interactive calendar controls to expose both the global timezone and the Day/Week secondary timezone with clearer guidance.
### Fixed
- **Timezone Consistency Across Views**:
- Unified event projection in Day/Week/Month/Year so view filtering, layout, and visible dates stay aligned with the configured calendar timezone.
- **Canonical Callback Semantics**:
- Editing in a different calendar timezone now behaves: switching timezone only changes display, while `onEventUpdate`, `onEventDrop`, and `onEventResize` return canonical events after the edit is applied.
- Aligned timed event creation flows such as quick create, context-menu paste, sidebar calendar drop, Month view create, and keyboard paste with `app.timeZone`.
### Documentation
- Updated timezone documentation in English, Chinese, and Japanese to describe:
- the new app-level `timeZone`
- Day/Week-only `secondaryTimeZone`
- canonical callback semantics after drag/resize/edit operations
- Refreshed the website interactive calendar help text and tooltips to match the new timezone model.
## [3.3.0] - 2026-03-20
### New Features & Enhancements
- **Grid Year View**: Added a new `grid` mode for `createYearView`, providing a compact month-grid layout with heatmap intensity colors for event density visualization.
- **`@create-dayflow` CLI**: Introduced the `npm create dayflow@latest` scaffolding tool. Interactively configures a new project with framework selection (React, Vue, Angular, Svelte), TypeScript support, and Tailwind CSS integration.
- **`renderSidebarHeader`**: Added a `renderSidebarHeader` render prop to the sidebar plugin, allowing full customization of the sidebar header area (e.g. user avatar, collapse toggle).
### Fixed
- **Style Isolation**: Fixed `tailwind-components.css` overriding host application styles. DayFlow's component CSS no longer emits Tailwind utility classes or leaks bare pseudo-class selectors (`:focus-visible`, `:checked`) to the host app.
- **`bg-primary` Pollution**: Resolved context menu, sidebar merge menu, and calendar list items using the host application's `--color-primary` instead of DayFlow's own color variables. All interactive elements now use `var(--df-color-*)` directly.
- **Month View Scroll**: Clicking on cross-month dates (previous month's trailing dates in the first row, next month's leading dates in the last row) no longer triggers unwanted month navigation.
- **Portal Color Scope**: Added `df-portal` class to all `createPortal` root elements so portaled components (context menus, dialogs, drawers) correctly inherit DayFlow's color token scope.
### Style
- Added `df-` prefix scoping to CSS class names in `tailwind-components.css` and `tailwind.css` to prevent conflicts with host application Tailwind instances.
- Remapped `--color-primary` and related tokens within `.df-calendar-container` and `.df-portal` to always resolve to DayFlow's own `--df-color-*` variables, regardless of host app theme.
### Documentation
- Migrated website from Nextra to Fumadocs.
- Updated installation guides to feature `@create-dayflow` CLI as the primary setup method.
- Updated theme customization guide.
- Added `renderSidebarHeader` API documentation.
## [3.2.0] - 2026-02-28
### New Features & Enhancements
- **Drag & Drop Improvements**:
- Added `onEventDrop` and `onEventResize` callbacks to the drag plugin for better event handling.
- Updated Month and Year View all-day event drag indicators for better visual feedback.
- **View Enhancements**:
- Added `secondaryTimeZone` label support for Day and Week Views.
- Added `timeFormat` configuration for Day and Week Views.
- Updated configuration options for `monthView` and `yearView`.
- **Developer Experience**:
- Introduced `oxlint` for faster linting and improved code quality.
- Added `pre-commit` hooks and `format:check` scripts to ensure code consistency.
- Migrated to `pnpm workspace catalog` for better dependency management.
- Added `.editorconfig` and improved VSCode settings/extensions recommendations.
### Performance
- **Scrolling**: Optimized `MonthView` scrolling performance by memoizing scrollbar checks.
### Fixed
- **Layout**: Resolved `eventLayout` stacking issues and improved mobile `WeekView` layout.
- **Framework Support**: Corrected `ng-packagr` configuration schema path for Angular.
- **Build & Packaging**:
- Fixed CSS export errors and website build issues.
- Removed duplicate `peerDependencies` in `package.json` files.
- Fixed Tailwind CSS path configurations.
- **UI/UX**: Fixed an issue where the "+ more" click in the website had no reaction.
- **Documentation**: Corrected README image paths and updated view documentation.
### Style
- Improved Day/Week View event resize pointer display.
- Cleaned up Tailwind CSS class formatting.
- Resolved various lint warnings reported by `oxlint`.
## [3.1.0] - 2026-02-20
### Plugin Architecture & Decoupling
This release introduces a new plugin-based architecture, further reducing the core bundle size and providing greater flexibility. Core features have been extracted into independent, optional packages.
#### New Plugin Packages (v1.0.0)
- **`@dayflow/plugin-drag`**: Handles all drag-and-drop interactions (move, resize, and create).
- **`@dayflow/plugin-keyboard-shortcuts`**: Provides keyboard navigation and shortcuts support.
- **`@dayflow/plugin-localization`**: Dedicated package for multi-language support and internationalization.
- **`@dayflow/plugin-sidebar`**: Extracts the sidebar UI and logic into a standalone plugin.
### New Features & Enhancements
- **Enhanced Visibility Control**:
- Added `onVisibleRangeChange` callback with a `reason` parameter (scroll vs. navigation).
- Marked `onVisibleMonthChange` as deprecated in favor of the more flexible range change callback.
- **Improved API**: Simplified framework wrappers by removing the `sidebarConfig` attribute (now handled via the sidebar plugin).
- **UI Refresh**: Updated the view switching button styles for a more modern look and feel.
### Fixed
- **Accessibility**: Fixed an event scaling issue when using the keyboard `Tab` key for navigation.
- **Search**: Improved search result location accuracy within the calendar views.
- **Documentation**: Comprehensive updates to plugin documentation and multi-language guides.
### Breaking Changes
- **Feature Extraction**: Drag-and-drop, keyboard shortcuts, and the sidebar are no longer included in `@dayflow/core` by default. You must install and register the corresponding plugins to retain these features.
- **Sidebar Configuration**: The `sidebarConfig` prop has been removed from framework adapters. Configuration is now passed directly to the `@dayflow/plugin-sidebar` during initialization.
## [3.0.0] - 2026-02-15
### Major Architectural Overhaul: Multi-Framework Support
This version marks a complete rewrite of the DayFlow internal architecture, moving from a React-only library to a **framework-agnostic monorepo structure**.
#### New Package Structure
- **`@dayflow/core`**: The new heart of DayFlow. Powered by **Preact**, it handles all state management, layout algorithms, and the core rendering engine (~3KB gzipped).
- **`@dayflow/react`**: High-performance React adapter.
- **`@dayflow/vue`**: Brand new adapter for Vue 3.
- **`@dayflow/svelte`**: Brand new adapter for Svelte 5 (with full SSR support).
- **`@dayflow/angular`**: Brand new adapter for Angular (v14+).
### New Features
- **Framework Agnostic**: Core logic and UI are now decoupled from specific frameworks.
- **Improved Content Injection**: New **Content Slots** system allowing users to inject native framework components (React/Vue/Svelte/Angular) into the Preact-driven calendar.
- **SSR Ready**:
- **Svelte**: Provided dedicated SSR bundles (`dist/index.ssr.js`) to avoid DOM reference errors during server-side rendering.
- **React/Vue**: Enhanced hydration safety.
### Fixed & Improved
- Optimized mobile responsiveness for all framework adapters.
- Improved build process using Rollup and Turborepo for faster and smaller bundles.
### Breaking Changes
- **Package Names**: If you were using the old `dayflow` package, you should now migrate to framework-specific packages (e.g., `@dayflow/react`).
- **Import Paths**:
- Components and hooks are now exported from `@dayflow/[framework]`.
- Core types and utilities are exported from `@dayflow/core`.
- **External Dependencies**: To maintain framework-agnosticism, the built-in color picker (`react-color`) has been removed. Users should now provide their own color picker via Content Slots.
---
================================================
FILE: CNAME
================================================
calendar.dayflow.studio
================================================
FILE: CONTRIBUTING.md
================================================
# Contribution Guide
Thank you for your interest in contributing to **DayFlow**! We welcome contributions from the community. Please follow this guide to set up the project and ensure your contributions align with our standards.
## 🚀 How to Start the Project
If you have forked the repository and want to run the examples locally, follow these steps:
1. **Clone your fork:**
```bash
git clone https://github.com/YOUR_USERNAME/DayFlow.git
cd DayFlow
```
2. **Install dependencies:**
```bash
pnpm install
```
### 3. Start the development server
Navigate to the core package and start the dev server:
```bash
cd packages/core
pnpm run dev
```
The application will typically be available at:
http://localhost:5529
---
## Commit Message Convention
Please follow these prefixes when writing commit messages:
- `feat:` — new features
- `fix:` — bug fixes
- `docs:` — documentation updates
- `style:` — formatting, missing semicolons, etc. (no logic changes)
- `refactor:` — code changes that neither fix a bug nor add a feature
- `test:` — adding or updating tests
- `chore:` — maintenance tasks (build, dependencies, etc.)
Example:
```bash
feat: add drag-and-drop event support
fix: resolve timezone offset issue in calendar view
```
---
## Pull Request Guidelines
To keep the project maintainable and easy to review:
- Keep each pull request focused on **one feature, bug fix, or refactor**
- Avoid mixing unrelated changes in a single PR
- Provide a clear description of:
- What changed
- Why it was needed
- Update documentation if necessary
- Add or update tests when applicable
- Ensure the project builds and runs correctly before submitting
---
## Development Tips
- Keep changes minimal and focused
- Follow existing code style and structure
- When in doubt, open an issue first to discuss your idea
---
## License and Contribution Terms
By submitting a contribution to this project, you represent that:
- The contribution is your original work, or you have the legal right to submit it.
- You grant DayFlow the right to use, modify, distribute, and relicense your contribution as part of both open source and commercial versions of the project.
---
Thanks again for contributing to **DayFlow**! 🚀
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2025 Jayce Li
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.ja.md
================================================
# DayFlow
[English](README.md) | [中文](README.zh.md) | **日本語** | [はじめに & コントリビューション](CONTRIBUTING.md)
ドラッグ&ドロップ、マルチビュー、プラグインアーキテクチャをサポートする、柔軟で機能豊富なReactカレンダーコンポーネントライブラリ。
[](https://www.npmjs.com/package/@dayflow/core)
[](https://github.com/dayflow-js/calendar/pulls)
[](https://github.com/dayflow-js/calendar/blob/main/LICENSE)
[](https://discord.gg/9vdFZKJqBb)
## 機能
### 日次、週次、月次、年次、その他のビュータイプ
#### 日次

#### 週次

#### 月次

#### 年次 (固定週)

#### 年次 (キャンバス)

### モバイルビューのサポート
#### モバイル日次 & 年次

#### モバイル週次 & 月次

### デフォルトパネル(複数のイベント詳細パネルオプションが利用可能)
#### 詳細ポップアップ

#### 詳細ダイアログ

### ダークモードのサポート

### ドラッグ&ドロップとリサイズも簡単
https://github.com/user-attachments/assets/726a5232-35a8-4fe3-8e7b-4de07c455353
https://github.com/user-attachments/assets/957317e5-02d8-4419-a74b-62b7d191e347
## コントリビューション
コントリビューションは大歓迎です!お気軽に Pull Request を送信してください。
## バグ報告
バグを見つけた場合は、[GitHub Issues](https://github.com/dayflow-js/calendar/issues) で問題を報告してください。
## サポート
質問やサポートについては、GitHub で Issue を開くか、Discord に参加してください。
---
================================================
FILE: README.md
================================================
# DayFlow
**English** | [中文](README.zh.md) | [日本語](README.ja.md) | [Getting Started & Contributing](CONTRIBUTING.md)
A flexible and feature-rich calendar component library for **React, Vue, Angular, and Svelte** with drag-and-drop support, multiple views, and plugin architecture.
[](https://www.npmjs.com/package/@dayflow/core)
[](https://github.com/dayflow-js/calendar/pulls)
[](https://github.com/dayflow-js/calendar/blob/main/LICENSE)
[](https://discord.gg/9vdFZKJqBb)
## Features
### Daily, Weekly, Monthly and Yearly View Types
#### Day View

#### Week View

#### Month View

#### Year View(Fixed-Week)

#### Year View(Year-Canvas)

### Mobile View Support
#### Mobile Day & Year View

#### Mobile Week & Month View

### Multiple Event Detail Panel options
#### Detail Popup

#### Detail Dialog

### Dark Mode Support

### Easy to resize and drag
https://github.com/user-attachments/assets/726a5232-35a8-4fe3-8e7b-4de07c455353
https://github.com/user-attachments/assets/957317e5-02d8-4419-a74b-62b7d191e347
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
## Bug Reports
If you find a bug, please file an issue on [GitHub Issues](https://github.com/dayflow-js/calendar/issues).
## Support
For questions and support, please open an issue on GitHub or go to discord.
---
================================================
FILE: README.zh.md
================================================
# DayFlow
[English](README.md) | **中文** | [日本語](README.ja.md) | [快速开始 & 贡献](CONTRIBUTING.md)
一个灵活且功能丰富的 React 日历组件库,支持拖拽、多视图和插件架构。
[](https://www.npmjs.com/package/@dayflow/core)
[](https://github.com/dayflow-js/calendar/pulls)
[](https://github.com/dayflow-js/calendar/blob/main/LICENSE)
[](https://discord.gg/9vdFZKJqBb)
## 功能特性
### 日视图、周视图、月视图、年视图及多种视图类型
#### 日视图

#### 周视图

#### 月视图

#### 年视图 (固定周)

#### 年视图 (画布)

### 移动端视图支持
#### 移动端日视图 & 年视图

#### 移动端周视图 & 月视图

### 默认面板(提供多种事件详情面板选项)
#### 详情弹窗

#### 详情对话框

### 暗色模式支持

### 轻松拖拽与缩放
https://github.com/user-attachments/assets/726a5232-35a8-4fe3-8e7b-4de07c455353
https://github.com/user-attachments/assets/957317e5-02d8-4419-a74b-62b7d191e347
## 贡献
欢迎贡献!请随意提交 Pull Request。
## Bug 反馈
如果您发现 Bug,请在 [GitHub Issues](https://github.com/dayflow-js/calendar/issues) 上提交 issue。
## 支持
如有问题和支持需求,请在 GitHub 上打开 issue 或加入 discord。
---
================================================
FILE: examples/defaultCalendarExample/defaultCalendarExample.tsx
================================================
import {
Event,
CalendarType,
EventChange,
ReadOnlyConfig,
TimeZone,
ViewType,
} from '@dayflow/core';
import { createDragPlugin } from '@dayflow/plugin-drag';
import { createLocalizationPlugin, zh } from '@dayflow/plugin-localization';
import {
useCalendarApp,
DayFlowCalendar,
createMonthView,
createWeekView,
createDayView,
createYearView,
createAgendaView,
UseCalendarAppReturn,
} from '@dayflow/react';
import { getWebsiteCalendars } from '@examples/utils/palette';
import { generateSampleEvents } from '@examples/utils/sampleData';
import { createKeyboardShortcutsPlugin } from '@keyboard-shortcuts/plugin';
import { createSidebarPlugin } from '@sidebar/plugin';
import { Sun, Moon, Globe, Clock } from 'lucide-react';
import React, { useState, useRef, useEffect, useMemo } from 'react';
const TZ_OPTIONS = Object.entries(TimeZone).map(([key, value]) => ({
label: `${key.replaceAll('_', ' ')} (${value})`,
value,
}));
const hasRedo = (app: object): app is object & { redo: () => void } =>
'redo' in app && typeof app.redo === 'function';
type ExampleThemeMode = 'light' | 'dark';
const getInitialThemeMode = (): ExampleThemeMode => {
if (typeof window === 'undefined') {
return 'light';
}
if (document.documentElement.classList.contains('dark')) {
return 'dark';
}
const storedTheme = localStorage.getItem('theme');
if (storedTheme === 'dark' || storedTheme === 'light') {
return storedTheme;
}
return window.matchMedia('(prefers-color-scheme: dark)').matches
? 'dark'
: 'light';
};
const DefaultCalendarExample: React.FC<{
themeMode: ExampleThemeMode;
}> = ({ themeMode }) => {
const [events] = useState<Event[]>(generateSampleEvents());
const calendarRef = useRef<UseCalendarAppReturn | null>(null);
const [readOnly] = useState<boolean | ReadOnlyConfig>(false);
// Global calendar timezone — affects all views' event bucketing and editing
const [appTz, setAppTz] = useState<string>('');
// Secondary timezone — only adds a second timeline label column in Day/Week
const [secondaryTz, setSecondaryTz] = useState<string>('');
const [isMobile, setIsMobile] = useState(false);
useEffect(() => {
const checkMobile = () => setIsMobile(window.innerWidth < 768);
checkMobile();
window.addEventListener('resize', checkMobile);
return () => window.removeEventListener('resize', checkMobile);
}, []);
const plugins = useMemo(
() =>
[
createDragPlugin({
onEventDrop: (updatedEvent, _) => {
console.log('onEventDrop:', updatedEvent);
},
onEventResize: (updatedEvent, _) => {
console.log('onEventResize:', updatedEvent);
},
}),
createSidebarPlugin({
createCalendarMode: 'modal',
// colorPickerMode: 'default',
showEventDots: true,
}),
createLocalizationPlugin({
locales: [zh],
}),
createKeyboardShortcutsPlugin({
callbacks: {
redo: app => {
console.log('Redo triggered via callback!', app);
// You can add custom redo logic here if app.redo() is not enough
if (hasRedo(app)) {
app.redo();
}
},
undo: app => {
console.log('Undo triggered via callback!');
app.undo();
},
delete: (app, event) => {
console.log('Delete triggered via callback!', event);
if (!event) return;
app.deleteEvent(event.id);
app.selectEvent(null);
console.log(`Deleted event without confirmation: ${event.title}`);
},
},
}),
].filter(plugin => !(isMobile && plugin.name === 'sidebar')),
[isMobile]
);
const searchConfig = useMemo(
() => ({
onResultClick: ({
event,
defaultAction,
}: {
event: Event;
defaultAction: () => void;
}) => {
console.log('Search result clicked:', event);
defaultAction();
},
}),
[]
);
const views = useMemo(
() => [
createDayView({
// timeFormat: '12h',
secondaryTimeZone: secondaryTz || undefined,
showEventDots: true,
scrollToCurrentTime: true,
}),
createWeekView({
// timeFormat: '12h',
secondaryTimeZone: secondaryTz || undefined,
// startOfWeek: 2,
// showAllDay: false,
showEventDots: true,
scrollToCurrentTime: true,
}),
createMonthView({
showWeekNumbers: true,
// showMonthIndicator: false,
showEventDots: true,
}),
createYearView({
mode: 'fixed-week',
showTimedEventsInYearView: true,
startOfWeek: 7,
showEventDots: true,
}),
createAgendaView({}),
],
[secondaryTz]
);
const calendars = useMemo(() => getWebsiteCalendars(), []);
const callbacks = useMemo(
() => ({
onEventCreate: async (event: Event) => {
await new Promise(resolve => {
setTimeout(resolve, 500);
});
console.log('create event:', event);
},
onEventClick: (event: Event) => {
console.log('click event:', event);
},
onEventDoubleClick: (event: Event) => {
console.log('double click event:', event);
// You could use the event element as an anchor for a custom popover here
return true;
},
onEventUpdate: async (event: Event) => {
await new Promise(resolve => {
setTimeout(resolve, 1500);
});
console.log('update event:', event);
},
onEventDelete: async (eventId: string) => {
await new Promise(resolve => {
setTimeout(resolve, 1500);
});
console.log('delete event:', eventId);
},
onMoreEventsClick: (date: Date) => {
console.log('more events click date:', date);
calendarRef.current?.selectDate(date);
calendarRef.current?.changeView(ViewType.DAY);
},
onCalendarUpdate: async (cal: CalendarType) => {
await new Promise(resolve => {
setTimeout(resolve, 1500);
});
console.log('update calendar:', cal);
},
onCalendarDelete: async (calendarId: string) => {
await new Promise(resolve => {
setTimeout(resolve, 1500);
});
console.log('delete calendar:', calendarId);
},
onCalendarCreate: async (cal: CalendarType) => {
await new Promise(resolve => {
setTimeout(resolve, 1500);
});
console.log('create calendar: w', cal);
},
onCalendarMerge: async (sourceId: string, targetId: string) => {
await new Promise(resolve => {
setTimeout(resolve, 1500);
});
console.log('merge calendar:', sourceId, targetId);
},
onEventBatchChange: (event: EventChange[]) => {
console.log('batch change events:', event);
},
}),
[]
);
const calendar = useCalendarApp({
timeZone: appTz || undefined,
views,
theme: { mode: themeMode },
events: events,
calendars,
defaultCalendar: 'work',
// useEventDetailDialog: true,
// switcherMode: 'select',
plugins,
// locale: zh,
defaultView: ViewType.MONTH,
// useEventDetailDialog: true,
// switcherMode: 'select' as const,
// readOnly,
callbacks,
});
calendarRef.current = calendar;
return (
<div>
<div className='mb-4 flex flex-wrap items-center gap-3 px-4'>
{/* Global calendar timezone */}
<div className='flex min-w-[18rem] items-center gap-2 rounded-lg border border-gray-200 bg-white px-3 py-1.5 text-gray-700 shadow-sm md:min-w-88 dark:border-slate-700 dark:bg-slate-800 dark:text-gray-200'>
<Globe size={16} className='text-gray-400' />
<div className='flex min-w-0 flex-1 flex-col'>
<span className='text-[10px] leading-none text-gray-400 dark:text-gray-500'>
Calendar Timezone
</span>
<select
value={appTz}
onChange={e => setAppTz(e.target.value)}
className='w-full bg-transparent pr-6 text-sm font-medium outline-none'
>
<option value=''>Device local</option>
{TZ_OPTIONS.map(({ label, value }) => (
<option key={value} value={value}>
{label}
</option>
))}
</select>
</div>
</div>
{/* Secondary timeline for Day/Week */}
<div className='flex min-w-[18rem] items-center gap-2 rounded-lg border border-gray-200 bg-white px-3 py-1.5 text-gray-700 shadow-sm md:min-w-88 dark:border-slate-700 dark:bg-slate-800 dark:text-gray-200'>
<Clock size={16} className='text-gray-400' />
<div className='flex min-w-0 flex-1 flex-col'>
<span className='text-[10px] leading-none text-gray-400 dark:text-gray-500'>
Secondary Timeline (Day/Week)
</span>
<select
value={secondaryTz}
onChange={e => setSecondaryTz(e.target.value)}
className='w-full bg-transparent pr-6 text-sm font-medium outline-none'
>
<option value=''>None</option>
{TZ_OPTIONS.map(({ label, value }) => (
<option key={value} value={value}>
{label}
</option>
))}
</select>
</div>
</div>
</div>
<DayFlowCalendar
calendar={calendar}
search={searchConfig}
// eventContentDay={({ event, isSelected }) => (
// <div
// className='flex h-full flex-col justify-start overflow-hidden border-l-4'
// style={{
// borderTopLeftRadius: '4px',
// borderBottomLeftRadius: '4px',
// borderColor: getLineColor(event.calendarId || 'blue'),
// }}
// >
// <div className='flex items-center gap-1 px-0.5'>
// <span className='shrink-0 text-[10px]'>📅</span>
// <span
// className={`truncate text-xs font-semibold ${isSelected ? 'text-white' : ''}`}
// >
// {event.title}
// </span>
// </div>
// <div className='flex flex-col px-1'>
// <span
// className={`truncate text-[10px] opacity-70 ${isSelected ? 'text-white' : ''}`}
// >
// 📍 {`${event.meta?.location || 'No location'}`}
// </span>
// <span
// className={`text-[10px] opacity-60 ${isSelected ? 'text-white' : ''}`}
// >
// {event.description}
// </span>
// </div>
// </div>
// )}
// eventContentWeek={({ event, isSelected }) => (
// <div
// className='flex h-full flex-col justify-start overflow-hidden border-l-4 border-black/20 pr-0.5 pl-1'
// style={{
// borderTopLeftRadius: '4px',
// borderBottomLeftRadius: '4px',
// borderColor: getLineColor(event.calendarId || 'blue'),
// }}
// >
// <div className='flex items-center gap-1 px-0.5'>
// <EventIcon calendarId={event.calendarId} defaultIcon='🗓' />
// <span
// className={`text-xs font-semibold ${isSelected ? 'text-white' : ''}`}
// >
// {event.title}
// </span>
// </div>
// <div className='flex flex-col'>
// <span
// className={`text-[9px] opacity-70 ${isSelected ? 'text-white' : ''}`}
// >
// 📍 {`${event.meta?.location || 'No location'}`}
// </span>
// <span
// className={`text-[9px] opacity-60 ${isSelected ? 'text-white' : ''}`}
// >
// {event.description}
// </span>
// </div>
// </div>
// )}
// eventContentMonth={({ event }) => (
// <div className='flex items-center gap-1 overflow-hidden px-0.5'>
// <EventIcon calendarId={event.calendarId} defaultIcon='🗃' />
// <span className='truncate text-xs font-medium'>{event.title}</span>
// </div>
// )}
// eventContentYear={({ event }) => (
// <div className='flex items-center gap-1 overflow-hidden px-0.5'>
// <EventIcon calendarId={event.calendarId} defaultIcon='🗃' />
// <span className='truncate text-xs font-medium'>{event.title}</span>
// </div>
// )}
// eventContentAllDayDay={({ event }) => (
// <div className='flex h-full items-center gap-1 overflow-hidden px-0.5'>
// <EventIcon calendarId={event.calendarId} defaultIcon='☀️' />
// <span className='truncate text-xs font-medium'>{event.title}</span>
// </div>
// )}
// eventContentAllDayWeek={({ event }) => (
// <div className='flex h-full items-center gap-1 overflow-hidden px-0.5'>
// <EventIcon calendarId={event.calendarId} defaultIcon='☀️' />
// <span className='truncate text-xs font-medium'>{event.title}</span>
// </div>
// )}
// eventContentAllDayMonth={({ event }) => (
// <div className='flex h-full items-center gap-1 overflow-hidden px-0.5'>
// <EventIcon calendarId={event.calendarId} defaultIcon='☀️' />
// <span className='truncate text-xs font-medium'>{event.title}</span>
// </div>
// )}
// eventContentAllDayYear={({ event }) => (
// <div className='flex h-full items-center gap-1 overflow-hidden px-0.5'>
// <EventIcon calendarId={event.calendarId} defaultIcon='☀️' />
// <span className='truncate text-xs font-medium'>{event.title}</span>
// </div>
// )}
/>
</div>
);
};
const ThemeToggle = ({
isDark,
onToggle,
}: {
isDark: boolean;
onToggle: () => void;
}) => (
<div className='flex shrink-0 items-center gap-4'>
<button
type='button'
onClick={onToggle}
className='flex items-center gap-2 rounded-lg border border-gray-200 bg-white px-4 py-2 text-gray-700 shadow-sm transition-colors hover:bg-gray-50 dark:border-slate-700 dark:bg-slate-800 dark:text-gray-200 dark:hover:bg-slate-700'
>
{isDark ? <Sun size={18} /> : <Moon size={18} />}
<span className='text-sm font-medium'>{isDark ? 'Light' : 'Dark'}</span>
</button>
</div>
);
export function CalendarTypesExample() {
const [themeMode, setThemeMode] =
useState<ExampleThemeMode>(getInitialThemeMode);
useEffect(() => {
const root = document.documentElement;
root.classList.toggle('dark', themeMode === 'dark');
root.classList.toggle('light', themeMode === 'light');
localStorage.theme = themeMode;
}, [themeMode]);
return (
<div className='min-h-screen bg-gray-50 p-2 text-gray-900 transition-colors duration-200 dark:bg-slate-950 dark:text-gray-100'>
<div className=''>
{/* Header */}
<div className='mb-4 flex items-center justify-between gap-4 px-4'>
<div className='space-y-4'>
<h1 className='text-3xl font-bold tracking-tight'>
Calendar Example
</h1>
</div>
<ThemeToggle
isDark={themeMode === 'dark'}
onToggle={() =>
setThemeMode(current => (current === 'dark' ? 'light' : 'dark'))
}
/>
</div>
{/* Calendar Instance */}
<div>
<DefaultCalendarExample themeMode={themeMode} />
</div>
</div>
</div>
);
}
export default CalendarTypesExample;
================================================
FILE: examples/main.tsx
================================================
// import 'preact/debug';
import { createRoot } from 'react-dom/client';
// Local example shell utilities live in examples/styles/tailwind.css.
// DayFlow component styles stay on the library side.
import '@/styles/tailwind-components.css';
import './styles/tailwind.css';
import CalendarExample from './defaultCalendarExample/defaultCalendarExample';
const container = document.querySelector('#root');
if (container) {
const root = createRoot(container);
root.render(<CalendarExample />);
}
================================================
FILE: examples/styles/tailwind.css
================================================
@import 'tailwindcss/preflight' layer(base);
@import 'tailwindcss/theme' layer(theme);
@import 'tailwindcss/utilities';
@source "../**/*.{ts,tsx}";
@variant dark (.dark &);
================================================
FILE: examples/utils/palette.ts
================================================
import { CalendarType, CalendarColors } from '@dayflow/core';
interface PaletteCalendar extends Pick<
CalendarType,
'id' | 'name' | 'icon' | 'readOnly'
> {
color: string;
colors: CalendarColors;
darkColors: CalendarColors;
source?: string;
}
export const CALENDAR_SIDE_PANEL: PaletteCalendar[] = [
{
id: 'team',
name: 'Product Team',
source: 'Google',
readOnly: true,
color: '#2563eb',
colors: {
eventColor: 'rgba(37, 99, 235, 0.12)',
eventSelectedColor: '#2563eb',
lineColor: '#2563eb',
textColor: '#1d4ed8',
},
darkColors: {
eventColor: 'rgba(59, 130, 246, 0.25)',
eventSelectedColor: '#3b82f6',
lineColor: '#60a5fa',
textColor: '#dbeafe',
},
},
{
id: 'personal',
name: 'Personal',
source: 'iCloud',
color: '#0ea5e9',
colors: {
eventColor: 'rgba(14, 165, 233, 0.12)',
eventSelectedColor: '#0ea5e9',
lineColor: '#0ea5e9',
textColor: '#0369a1',
},
darkColors: {
eventColor: 'rgba(14, 165, 233, 0.24)',
eventSelectedColor: '#38bdf8',
lineColor: '#7dd3fc',
textColor: '#e0f2fe',
},
},
{
id: 'learning',
name: 'Learning',
source: 'iCloud',
color: '#8b5cf6',
colors: {
eventColor: 'rgba(139, 92, 246, 0.15)',
eventSelectedColor: '#8b5cf6',
lineColor: '#8b5cf6',
textColor: '#5b21b6',
},
darkColors: {
eventColor: 'rgba(167, 139, 250, 0.28)',
eventSelectedColor: '#a855f7',
lineColor: '#c084fc',
textColor: '#ede9fe',
},
},
{
id: 'travel',
name: 'Travel',
source: 'iCloud',
color: '#f97316',
colors: {
eventColor: 'rgba(249, 115, 22, 0.15)',
eventSelectedColor: '#f97316',
lineColor: '#f97316',
textColor: '#7c2d12',
},
darkColors: {
eventColor: 'rgba(251, 146, 60, 0.3)',
eventSelectedColor: '#fb923c',
lineColor: '#fdba74',
textColor: '#ffedd5',
},
},
{
id: 'wellness',
name: 'Wellness',
source: 'Google',
color: '#10b981',
colors: {
eventColor: 'rgba(16, 185, 129, 0.15)',
eventSelectedColor: '#10b981',
lineColor: '#10b981',
textColor: '#065f46',
},
darkColors: {
eventColor: 'rgba(52, 211, 153, 0.25)',
eventSelectedColor: '#34d399',
lineColor: '#6ee7b7',
textColor: '#ecfdf5',
},
},
{
id: 'marketing',
name: 'Marketing',
source: 'Google',
color: '#ec4899',
colors: {
eventColor: 'rgba(236, 72, 153, 0.15)',
eventSelectedColor: '#ec4899',
lineColor: '#ec4899',
textColor: '#831843',
},
darkColors: {
eventColor: 'rgba(244, 114, 182, 0.28)',
eventSelectedColor: '#f472b6',
lineColor: '#f9a8d4',
textColor: '#fce7f3',
},
},
{
id: 'support',
name: 'Support',
source: 'Google',
color: '#14b8a6',
colors: {
eventColor: 'rgba(20, 184, 166, 0.15)',
eventSelectedColor: '#14b8a6',
lineColor: '#14b8a6',
textColor: '#115e59',
},
darkColors: {
eventColor: 'rgba(45, 212, 191, 0.25)',
eventSelectedColor: '#5eead4',
lineColor: '#99f6e4',
textColor: '#ccfbf1',
},
},
];
export const getWebsiteCalendars = (): CalendarType[] =>
CALENDAR_SIDE_PANEL.map(item => ({
id: item.id,
name: item.name,
icon: item.icon,
source: item.source,
readOnly: item.readOnly,
colors: {
eventColor: `${item.color}30`,
eventSelectedColor: `${item.color}`,
lineColor: item.color,
textColor: item.colors.textColor,
},
isVisible: true,
}));
================================================
FILE: examples/utils/sampleData.ts
================================================
import { Event } from '@dayflow/core';
import { Temporal } from 'temporal-polyfill';
const calendarIds = [
'team',
'personal',
'learning',
'travel',
'wellness',
'marketing',
'support',
];
const titles = [
'Product Sync',
'Design Review',
'Customer Call',
'Weekly Planning',
'Deep Work',
'Code Review',
'Brainstorm',
'Usability Test',
'Team Retro',
'Partner Demo',
'Lunch & Learn',
'Yoga Break',
'Travel Block',
'Hiring Interview',
'Content Planning',
];
const locations = [
'Conference Room A',
'Meeting Room 302',
'Zoom Meeting',
'Main Office, 4th Floor',
'Starbucks Coffee',
'Community Center',
'Innovation Hub',
'Building 5, Lab 2',
];
const eventDetails: Record<string, { description: string; location?: string }> =
{
'Product Sync': {
description: 'Sync up on the latest product roadmap and milestones.',
location: 'Room 101',
},
'Design Review': {
description:
'Review the new UI/UX designs for the upcoming mobile app release.',
location: 'Design Studio',
},
'Customer Call': {
description:
'Discussion with key clients regarding feature requests and feedback.',
location: 'Virtual',
},
'Weekly Planning': {
description: 'Plan tasks and priorities for the upcoming week.',
location: 'Main Hall',
},
'Deep Work': {
description: 'Focus time for intense development and problem solving.',
location: 'Quiet Zone',
},
'Code Review': {
description: 'Review pull requests and ensure code quality standards.',
location: 'Dev Corner',
},
Brainstorm: {
description: 'Ideation session for the next big feature.',
location: 'Whiteboard Room',
},
'Usability Test': {
description: 'Observe users interacting with the latest prototype.',
location: 'User Lab',
},
'Team Retro': {
description: 'Reflect on the past sprint and discuss improvements.',
location: 'Common Area',
},
'Partner Demo': {
description: 'Demonstrate our latest capabilities to potential partners.',
location: 'Executive Suite',
},
'Lunch & Learn': {
description: 'Educational session over lunch about new technologies.',
location: 'Cafeteria',
},
'Yoga Break': {
description: 'Stretch and relax with a quick yoga session.',
location: 'Wellness Room',
},
'Travel Block': {
description: 'Time allocated for travel and logistics.',
location: 'Airport Terminal',
},
'Hiring Interview': {
description: 'Interviewing candidates for the Senior Engineer position.',
location: 'HR Office',
},
'Content Planning': {
description: 'Plan the editorial calendar and upcoming blog posts.',
location: 'Marketing Hub',
},
};
// Simple deterministic random number generator
const createRandom = (seed: number) => {
let s = seed;
return () => {
const x = Math.sin(s++) * 10000;
return x - Math.floor(x);
};
};
const createRandomInt = (random: () => number) => (min: number, max: number) =>
Math.floor(random() * (max - min + 1)) + min;
const DEFAULT_TIME_ZONE = Temporal.Now.timeZoneId();
const createTimedEvent = (
baseDate: Temporal.PlainDate,
index: number,
randomInt: (min: number, max: number) => number
): Event => {
const title = titles[index % titles.length];
const details = eventDetails[title] || {
description: 'General event details.',
location: locations[index % locations.length],
};
// Keep sample events concentrated in local working hours for easier testing.
const startHour = randomInt(8, 15);
const maxDuration = Math.max(1, 17 - startHour);
const duration = Math.max(1, randomInt(1, Math.min(3, maxDuration)));
const startPlain = baseDate.toPlainDateTime({
hour: startHour,
minute: randomInt(0, 1) ? 30 : 0,
});
const start = Temporal.ZonedDateTime.from({
timeZone: DEFAULT_TIME_ZONE,
year: startPlain.year,
month: startPlain.month,
day: startPlain.day,
hour: startPlain.hour,
minute: startPlain.minute,
});
const end = start.add({ hours: duration });
return {
id: `event-${index}`,
title: title,
description: details.description,
start,
end,
calendarId: calendarIds[index % calendarIds.length],
meta: {
location: details.location || locations[index % locations.length],
},
};
};
const createAllDayEvent = (
start: Temporal.PlainDate,
span: number,
index: number,
calendarId: string,
title: string
): Event => {
const details = eventDetails[title] || {
description: 'All day event details.',
location: 'Various',
};
return {
id: `all-day-${index}`,
title,
description: details.description,
start,
end: start.add({ days: span }),
allDay: true,
calendarId,
icon: true,
meta: {
location: details.location || 'Multiple Locations',
},
};
};
const baseAllDayDefinitions: Array<{
offset: number;
span: number;
calendarId: string;
title: string;
}> = [
{ offset: -6, span: 2, calendarId: 'team', title: 'Sprint Offsite' },
{ offset: -2, span: 0, calendarId: 'personal', title: 'Family Day' },
{ offset: 3, span: 1, calendarId: 'travel', title: 'Client Visit' },
{ offset: 7, span: 2, calendarId: 'marketing', title: 'Campaign Launch' },
{ offset: 12, span: 0, calendarId: 'learning', title: 'Conference' },
{ offset: 16, span: 3, calendarId: 'wellness', title: 'Wellness Retreat' },
{ offset: 20, span: 1, calendarId: 'support', title: 'Support Rotation' },
];
export interface Resource {
id: string;
title: string;
avatar?: string;
color?: string;
meta?: Record<string, unknown>;
}
export const generateSampleResources = (): Resource[] => [
{
id: 'team',
title: 'Team Alpha',
avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=Alpha',
color: '#3b82f6',
},
{
id: 'personal',
title: 'John Doe',
avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=John',
color: '#ef4444',
},
{
id: 'learning',
title: 'Training Room',
avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=Room',
color: '#10b981',
},
{
id: 'travel',
title: 'Flight 101',
avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=Flight',
color: '#f59e0b',
},
{
id: 'wellness',
title: 'Gym',
avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=Gym',
color: '#8b5cf6',
},
{
id: 'marketing',
title: 'Marketing Suite',
avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=Marketing',
color: '#ec4899',
},
{
id: 'support',
title: 'Support Desk',
avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=Support',
color: '#64748b',
},
];
/** Multi-calendar sample events that demonstrate calendarIds support. */
export const generateMultiCalendarEvents = (): Event[] => {
const today = Temporal.Now.plainDateISO();
const tz = Temporal.Now.timeZoneId();
const makeZoned = (
date: Temporal.PlainDate,
hour: number,
minute = 0
): Temporal.ZonedDateTime =>
Temporal.ZonedDateTime.from({
timeZone: tz,
year: date.year,
month: date.month,
day: date.day,
hour,
minute,
});
return [
// Two-calendar timed event — today
{
id: 'multi-cal-1',
title: 'Family Dance Workshop',
description: 'Shared across the whole family calendar.',
start: makeZoned(today, 10),
end: makeZoned(today, 11, 30),
calendarIds: ['personal', 'wellness'],
meta: { location: 'Community Center' },
},
// Three-calendar timed event — tomorrow
{
id: 'multi-cal-2',
title: 'All-Hands Sprint Planning',
description: 'Cross-team planning session.',
start: makeZoned(today.add({ days: 1 }), 14),
end: makeZoned(today.add({ days: 1 }), 16),
calendarIds: ['team', 'marketing', 'support'],
meta: { location: 'Main Hall' },
},
// Four-calendar all-day event — spans today + 2 days
{
id: 'multi-cal-3',
title: 'Company Off-site',
description: 'Belongs to every team calendar.',
start: today.add({ days: 3 }),
end: today.add({ days: 5 }),
allDay: true,
icon: true,
calendarIds: ['team', 'personal', 'travel', 'learning'],
},
// Two-calendar timed event — yesterday (tests backward visibility)
{
id: 'multi-cal-4',
title: 'Retrospective + Wellness Check',
description: 'Weekly retro combined with wellness review.',
start: makeZoned(today.subtract({ days: 1 }), 15),
end: makeZoned(today.subtract({ days: 1 }), 16),
calendarIds: ['team', 'wellness'],
meta: { location: 'Zoom' },
},
];
};
export const generateSampleEvents = (): Event[] => {
const today = Temporal.Now.plainDateISO();
const windowStart = today.subtract({ days: 24 });
const events: Event[] = [];
// Initialize deterministic random generator
const random = createRandom(12345);
const randomInt = createRandomInt(random);
for (let offset = 0; offset < 56; offset += 1) {
const date = windowStart.add({ days: offset });
const dayEvents = randomInt(2, 4);
for (let i = 0; i < dayEvents; i += 1) {
events.push(createTimedEvent(date, offset * 10 + i, randomInt));
}
}
baseAllDayDefinitions.forEach((definition, index) => {
const start = today.add({ days: definition.offset });
const span = Math.max(0, definition.span);
events.push(
createAllDayEvent(
start,
span,
index,
definition.calendarId,
definition.title
)
);
});
// Append multi-calendar demo events
events.push(...generateMultiCalendarEvents());
// Annual events for Year View demonstration
const currentYear = today.year;
const annualEvents = [
// Jan: New Year & Kickoff
{
month: 1,
day: 1,
span: 3,
calendarId: 'personal',
title: 'New Year Holiday',
},
{
month: 1,
day: 15,
span: 5,
calendarId: 'team',
title: 'Annual Kickoff Week',
},
{
month: 1,
day: 25,
span: 3,
calendarId: 'learning',
title: 'Goal Setting Workshop',
},
// Feb-Mar: Work Focus
{
month: 2,
day: 5,
span: 4,
calendarId: 'team',
title: 'Q1 Strategy Offsite',
},
{
month: 2,
day: 14,
span: 3,
calendarId: 'personal',
title: "Valentine's Trip",
},
{
month: 2,
day: 26,
span: 4,
calendarId: 'learning',
title: 'Tech Conference',
},
{
month: 3,
day: 10,
span: 4,
calendarId: 'team',
title: 'Design Sprint Week',
},
{
month: 3,
day: 24,
span: 4,
calendarId: 'marketing',
title: 'Product Launch Week',
},
// Apr-May: Conferences & Holidays
{
month: 4,
day: 12,
span: 5,
calendarId: 'travel',
title: 'Spring Team Building',
},
{
month: 4,
day: 25,
span: 3,
calendarId: 'personal',
title: 'Anniversary Trip',
},
{
month: 5,
day: 1,
span: 3,
calendarId: 'personal',
title: 'Labour Day Holiday',
},
{
month: 5,
day: 15,
span: 4,
calendarId: 'learning',
title: 'Developer Summit',
},
{
month: 5,
day: 28,
span: 3,
calendarId: 'marketing',
title: 'Brand Workshop',
},
// Jun-Jul: Travel & Vacation
{
month: 6,
day: 10,
span: 4,
calendarId: 'support',
title: 'Quarterly Review',
},
{
month: 6,
day: 15,
span: 14,
calendarId: 'travel',
title: 'Summer Vacation (Europe)',
},
{
month: 7,
day: 8,
span: 4,
calendarId: 'team',
title: 'Mid-Year Review Week',
},
{
month: 7,
day: 20,
span: 5,
calendarId: 'wellness',
title: 'Hiking Trip',
},
// Aug-Sep: Projects & Learning
{ month: 8, day: 12, span: 6, calendarId: 'team', title: 'Hackathon Week' },
{
month: 8,
day: 25,
span: 3,
calendarId: 'wellness',
title: 'Wellness Retreat',
},
{
month: 9,
day: 5,
span: 3,
calendarId: 'learning',
title: 'Leadership Training',
},
{
month: 9,
day: 18,
span: 4,
calendarId: 'travel',
title: 'Client Roadshow',
},
// Oct-Nov: Q4 Push
{
month: 10,
day: 10,
span: 5,
calendarId: 'team',
title: 'Q4 Planning Week',
},
{
month: 10,
day: 31,
span: 3,
calendarId: 'personal',
title: 'Halloween Weekend',
},
{
month: 11,
day: 15,
span: 5,
calendarId: 'marketing',
title: 'Black Friday Prep',
},
{
month: 11,
day: 24,
span: 3,
calendarId: 'personal',
title: 'Thanksgiving Holiday',
},
// Dec: Holidays
{
month: 12,
day: 10,
span: 3,
calendarId: 'team',
title: 'Year End Party Trip',
},
{
month: 12,
day: 24,
span: 5,
calendarId: 'personal',
title: 'Christmas Holiday',
},
{
month: 12,
day: 29,
span: 4,
calendarId: 'travel',
title: 'New Year Ski Trip',
},
];
annualEvents.forEach((def, index) => {
try {
const start = Temporal.PlainDate.from({
year: currentYear,
month: def.month,
day: def.day,
});
events.push(
createAllDayEvent(
start,
def.span,
2000 + index, // Use a high base index to avoid collisions
def.calendarId,
def.title
)
);
} catch {
// Ignore invalid dates (e.g. leap years edge cases in simple config)
}
});
return events;
};
export const generateMinimalSampleEvents = (): Event[] => {
const today = Temporal.Now.plainDateISO();
const windowStart = today.subtract({ days: 3 });
const events: Event[] = [];
const random = createRandom(54321);
const randomInt = createRandomInt(random);
for (let offset = 0; offset < 7; offset += 1) {
const date = windowStart.add({ days: offset });
const dayEvents = randomInt(1, 2);
for (let i = 0; i < dayEvents; i += 1) {
events.push(createTimedEvent(date, offset * 10 + i, randomInt));
}
}
// Add just a couple of all-day events
events.push(
createAllDayEvent(
today.subtract({ days: 1 }),
2,
999,
'team',
'Minimal Team Event'
)
);
return events;
};
================================================
FILE: index.html
================================================
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Day Flow Example</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/examples/main.tsx"></script>
</body>
</html>
================================================
FILE: lefthook.yml
================================================
pre-commit:
jobs:
- run: pnpm --filter @dayflow/core run check:css
- run: pnpm format
stage_fixed: true
- run: pnpm lint:fix
glob:
- '*.js'
- '*.jsx'
- '*.ts'
- '*.tsx'
- '*.json'
- '*.jsonc'
- '*.css'
- '*.md'
stage_fixed: true
- glob: 'website/**/*'
run: pnpm --dir website run build
================================================
FILE: package.json
================================================
{
"name": "dayflow-monorepo",
"version": "3.1.2",
"private": true,
"description": "Multi-framework calendar component library",
"scripts": {
"build": "turbo run build",
"clean": "turbo run clean && rimraf node_modules pnpm-lock.yaml",
"dev": "turbo run dev",
"format": "oxfmt .",
"format:check": "oxfmt . --check",
"lint": "oxlint .",
"lint:fix": "oxlint . --fix",
"prepare": "lefthook install",
"publish:all": "./scripts/publish.sh all",
"publish:cli": "./scripts/publish.sh cli",
"publish:dry": "./scripts/publish.sh all --dry-run",
"publish:main": "./scripts/publish.sh main",
"tag": "./scripts/git-tag.sh",
"test": "turbo run test",
"typecheck": "turbo run typecheck",
"version:update": "./scripts/update-versions.sh"
},
"devDependencies": {
"@dayflow/plugin-drag": "workspace:*",
"@dayflow/plugin-keyboard-shortcuts": "workspace:*",
"@dayflow/plugin-localization": "workspace:*",
"@dayflow/plugin-sidebar": "workspace:*",
"@dayflow/ui-range-picker": "workspace:*",
"@preact/preset-vite": "catalog:",
"@tailwindcss/postcss": "catalog:",
"@types/react": "catalog:",
"@types/react-dom": "catalog:",
"autoprefixer": "catalog:",
"lefthook": "^2.1.1",
"lucide-react": "catalog:",
"oxfmt": "^0.35.0",
"oxlint": "^1.50.0",
"postcss-import": "catalog:",
"preact": "catalog:",
"react": "catalog:",
"react-dom": "catalog:",
"rimraf": "catalog:",
"tailwindcss": "catalog:",
"temporal-polyfill": "catalog:",
"tsc-alias": "^1.8.16",
"turbo": "^2.8.10",
"typescript": "catalog:"
},
"packageManager": "pnpm@9.15.0"
}
================================================
FILE: packages/angular/LICENSE
================================================
MIT License
Copyright (c) 2025 Jayce Li
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: packages/angular/README.md
================================================
# DayFlow Angular
A flexible and feature-rich Angular calendar component library with drag-and-drop support, multiple views, and plugin architecture.
[](https://www.npmjs.com/package/@dayflow/angular)
[](https://github.com/dayflow-js/dayflow/pulls)
[](https://github.com/dayflow-js/dayflow/blob/main/LICENSE)
[](https://discord.gg/9vdFZKJqBb)
## Features
### Daily, Weekly, Monthly and Yearly View Types
#### Day View

#### Week View

#### Month View

#### Year View(Fixed-Week)

#### Year View(Year-Canvas)

### Mobile View Support
#### Mobile Day & Year View

#### Mobile Week & Month View

### Multiple Event Detail Panel options
#### Detail Popup

#### Detail Dialog

### Dark Mode Support

### Easy to resize and drag
https://github.com/user-attachments/assets/726a5232-35a8-4fe3-8e7b-4de07c455353
https://github.com/user-attachments/assets/957317e5-02d8-4419-a74b-62b7d191e347
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
## Bug Reports
If you find a bug, please file an issue on [GitHub Issues](https://github.com/dayflow-js/dayflow/issues).
## Support
For questions and support, please open an issue on GitHub or go to discord.
================================================
FILE: packages/angular/ng-packagr.json
================================================
{
"$schema": "./node_modules/ng-packagr/ng-package.schema.json",
"lib": {
"entryFile": "src/public-api.ts"
},
"assets": ["README.md", "LICENSE"],
"dest": "dist"
}
================================================
FILE: packages/angular/package.json
================================================
{
"name": "@dayflow/angular",
"version": "3.6.2",
"description": "Angular adapter for DayFlow calendar",
"files": [
"**/*.mjs",
"**/*.d.ts",
"**/*.json",
"README.md",
"LICENSE"
],
"scripts": {
"build": "ng-packagr -p ng-packagr.json",
"clean": "rimraf dist node_modules",
"typecheck": "tsc --noEmit"
},
"devDependencies": {
"@angular/common": "^18.2.0",
"@angular/compiler": "^18.2.0",
"@angular/compiler-cli": "^18.2.0",
"@angular/core": "^18.2.0",
"@angular/platform-browser": "^18.2.0",
"@angular/platform-browser-dynamic": "^18.2.0",
"@dayflow/core": "workspace:*",
"ng-packagr": "^18.2.1",
"rimraf": "catalog:",
"rxjs": "^7.8.1",
"tslib": "catalog:",
"typescript": "~5.5.0",
"zone.js": "~0.14.10"
},
"peerDependencies": {
"@angular/common": ">=14.0.0",
"@angular/core": ">=14.0.0",
"@dayflow/core": "workspace:*"
}
}
================================================
FILE: packages/angular/src/lib/day-flow-calendar.component.ts
================================================
import {
ElementRef,
OnChanges,
OnDestroy,
AfterViewInit,
SimpleChanges,
TemplateRef,
ChangeDetectorRef,
Component,
Input,
ViewChild,
ChangeDetectionStrategy,
} from '@angular/core';
import type {
ICalendarApp,
CalendarAppConfig,
CalendarAppConfigSyncSnapshot,
UseCalendarAppReturn,
CustomRendering,
EventDetailContentProps,
EventDetailDialogProps,
CreateCalendarDialogProps,
TitleBarSlotProps,
EventContentSlotArgs,
ColorPickerProps,
CreateCalendarDialogColorPickerProps,
CalendarHeaderProps,
EventContextMenuSlotArgs,
GridContextMenuSlotArgs,
CalendarSearchProps,
MobileEventProps,
} from '@dayflow/core';
import {
CalendarRenderer,
CalendarApp,
createConfigSyncSnapshot,
createNormalizedCalendarAppConfigGetter,
syncCalendarAppConfig,
} from '@dayflow/core';
@Component({
selector: 'dayflow-calendar',
template: `
<div #container class="df-calendar-wrapper"></div>
<!-- Hidden area to render Angular templates before they are portaled -->
<div style="display: none">
<ng-container *ngFor="let rendering of customRenderings; trackBy: trackById">
<div
*ngIf="getTemplate(rendering.generatorName)"
[dayflowPortal]="rendering.containerEl"
>
<ng-container
*ngTemplateOutlet="
getTemplate(rendering.generatorName)!;
context: { $implicit: rendering.generatorArgs }
"
></ng-container>
</div>
</ng-container>
</div>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class DayFlowCalendarComponent
implements AfterViewInit, OnChanges, OnDestroy
{
@Input() calendar!: ICalendarApp | UseCalendarAppReturn | CalendarAppConfig;
// Templates for custom content injection
@Input() eventContentDay?: TemplateRef<EventContentSlotArgs>;
@Input() eventContentWeek?: TemplateRef<EventContentSlotArgs>;
@Input() eventContentMonth?: TemplateRef<EventContentSlotArgs>;
@Input() eventContentYear?: TemplateRef<EventContentSlotArgs>;
@Input() eventContentAllDayDay?: TemplateRef<EventContentSlotArgs>;
@Input() eventContentAllDayWeek?: TemplateRef<EventContentSlotArgs>;
@Input() eventContentAllDayMonth?: TemplateRef<EventContentSlotArgs>;
@Input() eventContentAllDayYear?: TemplateRef<EventContentSlotArgs>;
@Input() eventDetailContent?: TemplateRef<EventDetailContentProps>;
@Input() eventDetailDialog?: TemplateRef<EventDetailDialogProps>;
@Input() createCalendarDialog?: TemplateRef<CreateCalendarDialogProps>;
@Input() titleBarSlot?: TemplateRef<TitleBarSlotProps>;
@Input() colorPicker?: TemplateRef<ColorPickerProps>;
@Input()
createCalendarDialogColorPicker?: TemplateRef<CreateCalendarDialogColorPickerProps>;
@Input() calendarHeader?: TemplateRef<CalendarHeaderProps>;
@Input() eventContextMenu?: TemplateRef<EventContextMenuSlotArgs>;
@Input() gridContextMenu?: TemplateRef<GridContextMenuSlotArgs>;
@Input() mobileEventDetail?: TemplateRef<MobileEventProps>;
@Input() collapsedSafeAreaLeft?: number;
@Input() search?: CalendarSearchProps;
@ViewChild('container') container!: ElementRef<HTMLElement>;
customRenderings: CustomRendering[] = [];
private renderer?: CalendarRenderer;
private unsubscribe?: () => void;
private internalApp?: CalendarApp;
private getNormalizedInternalConfig?: () => CalendarAppConfig;
private internalConfigSyncSnapshot?: CalendarAppConfigSyncSnapshot;
constructor(private cdr: ChangeDetectorRef) {}
private get app(): ICalendarApp {
if (this.internalApp) {
return this.internalApp;
}
if (this.calendar instanceof CalendarApp) {
return this.calendar;
}
if ((this.calendar as { app?: ICalendarApp; views?: unknown[] }).app) {
return (this.calendar as { app?: ICalendarApp; views?: unknown[] }).app!;
}
// If it's a config object, we create an internal instance
if (DayFlowCalendarComponent.isCalendarConfig(this.calendar)) {
return this.getOrCreateInternalApp();
}
return this.calendar as ICalendarApp;
}
ngAfterViewInit() {
this.initCalendar();
}
ngOnChanges(changes: SimpleChanges) {
if (changes['calendar'] && !changes['calendar'].firstChange) {
if (this.canSyncInternalCalendarConfig(changes['calendar'])) {
this.syncInternalCalendarConfig();
} else {
this.resetInternalCalendarState();
this.destroyCalendar();
this.initCalendar();
}
} else if (this.renderer) {
if (changes['collapsedSafeAreaLeft'] || changes['search']) {
this.renderer.setProps(this.getRendererProps());
}
const slotKeys = [
'eventContentDay',
'eventContentWeek',
'eventContentMonth',
'eventContentYear',
'eventContentAllDayDay',
'eventContentAllDayWeek',
'eventContentAllDayMonth',
'eventContentAllDayYear',
'eventDetailContent',
'eventDetailDialog',
'createCalendarDialog',
'titleBarSlot',
'colorPicker',
'createCalendarDialogColorPicker',
'calendarHeader',
'eventContextMenu',
'gridContextMenu',
'mobileEventDetail',
];
if (slotKeys.some(key => changes[key])) {
const activeOverrides = this.getActiveOverrides();
this.renderer.getCustomRenderingStore().setOverrides(activeOverrides);
this.app.setOverrides(activeOverrides);
}
}
}
ngOnDestroy() {
this.destroyCalendar();
}
private getRendererProps(): Record<string, unknown> {
return {
collapsedSafeAreaLeft: this.collapsedSafeAreaLeft,
search: this.search,
};
}
private initCalendar() {
if (!this.container || !this.calendar) {
return;
}
const activeOverrides = this.getActiveOverrides();
this.renderer = new CalendarRenderer(this.app, activeOverrides);
this.renderer.setProps(this.getRendererProps());
this.renderer.mount(this.container.nativeElement);
this.app.setOverrides(activeOverrides);
this.unsubscribe = this.renderer
.getCustomRenderingStore()
.subscribe(renderings => {
this.customRenderings = [...renderings.values()];
this.cdr.markForCheck();
});
}
private getActiveOverrides(): string[] {
const templateInputs: Record<string, TemplateRef<unknown> | undefined> = {
eventContentDay: this.eventContentDay,
eventContentWeek: this.eventContentWeek,
eventContentMonth: this.eventContentMonth,
eventContentYear: this.eventContentYear,
eventContentAllDayDay: this.eventContentAllDayDay,
eventContentAllDayWeek: this.eventContentAllDayWeek,
eventContentAllDayMonth: this.eventContentAllDayMonth,
eventContentAllDayYear: this.eventContentAllDayYear,
eventDetailContent: this.eventDetailContent,
eventDetailDialog: this.eventDetailDialog,
createCalendarDialog: this.createCalendarDialog,
titleBarSlot: this.titleBarSlot,
colorPicker: this.colorPicker,
createCalendarDialogColorPicker: this.createCalendarDialogColorPicker,
calendarHeader: this.calendarHeader,
eventContextMenu: this.eventContextMenu,
gridContextMenu: this.gridContextMenu,
mobileEventDetail: this.mobileEventDetail,
};
return Object.keys(templateInputs).filter(
key => templateInputs[key] !== null && templateInputs[key] !== undefined
);
}
private destroyCalendar() {
if (this.unsubscribe) {
this.unsubscribe();
}
if (this.renderer) {
this.renderer.unmount();
}
this.unsubscribe = undefined;
this.renderer = undefined;
}
private static isCalendarConfig(value: unknown): value is CalendarAppConfig {
return (
!!value &&
typeof value === 'object' &&
'views' in value &&
!('app' in value)
);
}
private getOrCreateInternalApp(): CalendarApp {
if (!this.internalApp) {
this.getNormalizedInternalConfig =
createNormalizedCalendarAppConfigGetter(
() => this.calendar as CalendarAppConfig
);
const normalizedConfig = this.getNormalizedInternalConfig();
this.internalApp = new CalendarApp(normalizedConfig);
this.internalConfigSyncSnapshot =
createConfigSyncSnapshot(normalizedConfig);
}
return this.internalApp;
}
private canSyncInternalCalendarConfig(
change: SimpleChanges['calendar']
): boolean {
return (
DayFlowCalendarComponent.isCalendarConfig(change.currentValue) &&
DayFlowCalendarComponent.isCalendarConfig(change.previousValue) &&
!!this.internalApp &&
!!this.getNormalizedInternalConfig &&
!!this.internalConfigSyncSnapshot
);
}
private syncInternalCalendarConfig() {
if (
!this.internalApp ||
!this.getNormalizedInternalConfig ||
!this.internalConfigSyncSnapshot
) {
return;
}
this.internalConfigSyncSnapshot = syncCalendarAppConfig(
this.internalApp,
this.internalConfigSyncSnapshot,
this.getNormalizedInternalConfig()
);
}
private resetInternalCalendarState() {
this.internalApp = undefined;
this.getNormalizedInternalConfig = undefined;
this.internalConfigSyncSnapshot = undefined;
}
getTemplate(name: string): TemplateRef<unknown> | null {
// Switch avoids allocating a new Record on every change-detection cycle.
switch (name) {
case 'eventContentDay': {
return this.eventContentDay ?? null;
}
case 'eventContentWeek': {
return this.eventContentWeek ?? null;
}
case 'eventContentMonth': {
return this.eventContentMonth ?? null;
}
case 'eventContentYear': {
return this.eventContentYear ?? null;
}
case 'eventContentAllDayDay': {
return this.eventContentAllDayDay ?? null;
}
case 'eventContentAllDayWeek': {
return this.eventContentAllDayWeek ?? null;
}
case 'eventContentAllDayMonth': {
return this.eventContentAllDayMonth ?? null;
}
case 'eventContentAllDayYear': {
return this.eventContentAllDayYear ?? null;
}
case 'eventDetailContent': {
return this.eventDetailContent ?? null;
}
case 'eventDetailDialog': {
return this.eventDetailDialog ?? null;
}
case 'createCalendarDialog': {
return this.createCalendarDialog ?? null;
}
case 'titleBarSlot': {
return this.titleBarSlot ?? null;
}
case 'colorPicker': {
return this.colorPicker ?? null;
}
case 'createCalendarDialogColorPicker': {
return this.createCalendarDialogColorPicker ?? null;
}
case 'calendarHeader': {
return this.calendarHeader ?? null;
}
case 'eventContextMenu': {
return this.eventContextMenu ?? null;
}
case 'gridContextMenu': {
return this.gridContextMenu ?? null;
}
case 'mobileEventDetail': {
return this.mobileEventDetail ?? null;
}
default: {
return null;
}
}
}
// eslint-disable-next-line class-methods-use-this
trackById(_index: number, item: CustomRendering) {
return item.id;
}
}
================================================
FILE: packages/angular/src/lib/day-flow-calendar.module.ts
================================================
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { DayFlowCalendarComponent } from './day-flow-calendar.component';
import { DayFlowPortalDirective } from './day-flow-portal.directive';
@NgModule({
declarations: [DayFlowCalendarComponent, DayFlowPortalDirective],
imports: [CommonModule],
exports: [DayFlowCalendarComponent, DayFlowPortalDirective],
})
// eslint-disable-next-line @typescript-eslint/no-extraneous-class
export class DayFlowCalendarModule {}
================================================
FILE: packages/angular/src/lib/day-flow-portal.directive.ts
================================================
import {
ElementRef,
OnChanges,
SimpleChanges,
OnDestroy,
Directive,
Input,
} from '@angular/core';
@Directive({
selector: '[dayflowPortal]',
})
export class DayFlowPortalDirective implements OnChanges, OnDestroy {
@Input('dayflowPortal') targetEl!: HTMLElement;
constructor(private el: ElementRef) {}
ngOnChanges(changes: SimpleChanges) {
if (changes['targetEl'] && this.targetEl) {
this.targetEl.append(this.el.nativeElement);
}
}
ngOnDestroy() {
if (this.el.nativeElement.parentNode === this.targetEl) {
this.el.nativeElement.remove();
}
}
}
================================================
FILE: packages/angular/src/public-api.ts
================================================
/*
* Public API Surface of @dayflow/angular
*/
export * from './lib/day-flow-calendar.component';
export * from './lib/day-flow-calendar.module';
export * from './lib/day-flow-portal.directive';
export * from '@dayflow/core';
================================================
FILE: packages/angular/tsconfig.json
================================================
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist/out-tsc",
"types": [],
"noUnusedLocals": false,
"noUnusedParameters": false,
"baseUrl": ".",
"paths": {
"@dayflow/core": ["../../packages/core/dist/index.d.ts"]
}
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
================================================
FILE: packages/core/LICENSE
================================================
MIT License
Copyright (c) 2025 Jayce Li
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: packages/core/README.md
================================================
# DayFlow Core
The core engine of DayFlow, a flexible and feature-rich calendar library with drag-and-drop support, multiple views, and plugin architecture.
[](https://www.npmjs.com/package/@dayflow/core)
[](https://github.com/dayflow-js/dayflow/pulls)
[](https://github.com/dayflow-js/dayflow/blob/main/LICENSE)
[](https://discord.gg/9vdFZKJqBb)
## Features
### Daily, Weekly, Monthly and Yearly View Types
#### Day View

#### Week View

#### Month View

#### Year View(Fixed-Week)

#### Year View(Year-Canvas)

### Mobile View Support
#### Mobile Day & Year View

#### Mobile Week & Month View

### Multiple Event Detail Panel options
#### Detail Popup

#### Detail Dialog

### Dark Mode Support

### Easy to resize and drag
https://github.com/user-attachments/assets/726a5232-35a8-4fe3-8e7b-4de07c455353
https://github.com/user-attachments/assets/957317e5-02d8-4419-a74b-62b7d191e347
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
## Bug Reports
If you find a bug, please file an issue on [GitHub Issues](https://github.com/dayflow-js/dayflow/issues).
## Support
For questions and support, please open an issue on GitHub or go to discord.
================================================
FILE: packages/core/bundle-analysis.html
================================================
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Rollup Visualizer</title>
<style>
:root {
--font-family:
-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji',
'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
--background-color: #2b2d42;
--text-color: #edf2f4;
}
html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
html {
background-color: var(--background-color);
color: var(--text-color);
font-family: var(--font-family);
}
body {
padding: 0;
margin: 0;
}
html,
body {
height: 100%;
width: 100%;
overflow: hidden;
}
body {
display: flex;
flex-direction: column;
}
svg {
vertical-align: middle;
width: 100%;
height: 100%;
max-height: 100vh;
}
main {
flex-grow: 1;
height: 100vh;
padding: 20px;
}
.tooltip {
position: absolute;
z-index: 1070;
border: 2px solid;
border-radius: 5px;
padding: 5px;
font-size: 0.875rem;
background-color: var(--background-color);
color: var(--text-color);
}
.tooltip-hidden {
visibility: hidden;
opacity: 0;
}
.sidebar {
position: fixed;
top: 0;
left: 0;
right: 0;
display: flex;
flex-direction: row;
font-size: 0.7rem;
align-items: center;
margin: 0 50px;
height: 20px;
}
.size-selectors {
display: flex;
flex-direction: row;
align-items: center;
}
.size-selector {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
margin-right: 1rem;
}
.size-selector input {
margin: 0 0.3rem 0 0;
}
.filters {
flex: 1;
display: flex;
flex-direction: row;
align-items: center;
}
.module-filters {
display: flex;
flex-grow: 1;
}
.module-filter {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
flex: 1;
}
.module-filter input {
flex: 1;
height: 1rem;
padding: 0.01rem;
font-size: 0.7rem;
margin-left: 0.3rem;
}
.module-filter + .module-filter {
margin-left: 0.5rem;
}
.node {
cursor: pointer;
}
</style>
</head>
<body>
<main></main>
<script>
/*<!--*/
var drawChart = (function (exports) {
'use strict';
var n,
l$1,
u$2,
i$1,
r$1,
o$1,
e$1,
f$2,
c$1,
s$1,
a$1,
h$1,
p$1 = {},
v$1 = [],
y$1 =
/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,
w$1 = Array.isArray;
function d$1(n, l) {
for (var u in l) n[u] = l[u];
return n;
}
function g(n) {
n && n.parentNode && n.parentNode.removeChild(n);
}
function _$1(l, u, t) {
var i,
r,
o,
e = {};
for (o in u)
'key' == o ? (i = u[o]) : 'ref' == o ? (r = u[o]) : (e[o] = u[o]);
if (
(arguments.length > 2 &&
(e.children = arguments.length > 3 ? n.call(arguments, 2) : t),
'function' == typeof l && null != l.defaultProps)
)
for (o in l.defaultProps)
void 0 === e[o] && (e[o] = l.defaultProps[o]);
return m$1(l, e, i, r, null);
}
function m$1(n, t, i, r, o) {
var e = {
type: n,
props: t,
key: i,
ref: r,
__k: null,
__: null,
__b: 0,
__e: null,
__c: null,
constructor: void 0,
__v: null == o ? ++u$2 : o,
__i: -1,
__u: 0,
};
return (null == o && null != l$1.vnode && l$1.vnode(e), e);
}
function k$1(n) {
return n.children;
}
function x$1(n, l) {
((this.props = n), (this.context = l));
}
function S(n, l) {
if (null == l) return n.__ ? S(n.__, n.__i + 1) : null;
for (var u; l < n.__k.length; l++)
if (null != (u = n.__k[l]) && null != u.__e) return u.__e;
return 'function' == typeof n.type ? S(n) : null;
}
function C$1(n) {
var l, u;
if (null != (n = n.__) && null != n.__c) {
for (n.__e = n.__c.base = null, l = 0; l < n.__k.length; l++)
if (null != (u = n.__k[l]) && null != u.__e) {
n.__e = n.__c.base = u.__e;
break;
}
return C$1(n);
}
}
function M(n) {
((!n.__d && (n.__d = true) && i$1.push(n) && !$.__r++) ||
r$1 != l$1.debounceRendering) &&
((r$1 = l$1.debounceRendering) || o$1)($);
}
function $() {
for (var n, u, t, r, o, f, c, s = 1; i$1.length; )
(i$1.length > s && i$1.sort(e$1),
(n = i$1.shift()),
(s = i$1.length),
n.__d &&
((t = void 0),
(o = (r = (u = n).__v).__e),
(f = []),
(c = []),
u.__P &&
(((t = d$1({}, r)).__v = r.__v + 1),
l$1.vnode && l$1.vnode(t),
O(
u.__P,
t,
r,
u.__n,
u.__P.namespaceURI,
32 & r.__u ? [o] : null,
f,
null == o ? S(r) : o,
!!(32 & r.__u),
c
),
(t.__v = r.__v),
(t.__.__k[t.__i] = t),
z$1(f, t, c),
t.__e != o && C$1(t))));
$.__r = 0;
}
function I(n, l, u, t, i, r, o, e, f, c, s) {
var a,
h,
y,
w,
d,
g,
_ = (t && t.__k) || v$1,
m = l.length;
for (f = P(u, l, _, f, m), a = 0; a < m; a++)
null != (y = u.__k[a]) &&
((h = -1 == y.__i ? p$1 : _[y.__i] || p$1),
(y.__i = a),
(g = O(n, y, h, i, r, o, e, f, c, s)),
(w = y.__e),
y.ref &&
h.ref != y.ref &&
(h.ref && q$1(h.ref, null, y), s.push(y.ref, y.__c || w, y)),
null == d && null != w && (d = w),
4 & y.__u || h.__k === y.__k
? (f = A$1(y, f, n))
: 'function' == typeof y.type && void 0 !== g
? (f = g)
: w && (f = w.nextSibling),
(y.__u &= -7));
return ((u.__e = d), f);
}
function P(n, l, u, t, i) {
var r,
o,
e,
f,
c,
s = u.length,
a = s,
h = 0;
for (n.__k = new Array(i), r = 0; r < i; r++)
null != (o = l[r]) &&
'boolean' != typeof o &&
'function' != typeof o
? ((f = r + h),
((o = n.__k[r] =
'string' == typeof o ||
'number' == typeof o ||
'bigint' == typeof o ||
o.constructor == String
? m$1(null, o, null, null, null)
: w$1(o)
? m$1(k$1, { children: o }, null, null, null)
: null == o.constructor && o.__b > 0
? m$1(
o.type,
o.props,
o.key,
o.ref ? o.ref : null,
o.__v
)
: o).__ = n),
(o.__b = n.__b + 1),
(e = null),
-1 != (c = o.__i = L(o, u, f, a)) &&
(a--, (e = u[c]) && (e.__u |= 2)),
null == e || null == e.__v
? (-1 == c && (i > s ? h-- : i < s && h++),
'function' != typeof o.type && (o.__u |= 4))
: c != f &&
(c == f - 1
? h--
: c == f + 1
? h++
: (c > f ? h-- : h++, (o.__u |= 4))))
: (n.__k[r] = null);
if (a)
for (r = 0; r < s; r++)
null != (e = u[r]) &&
0 == (2 & e.__u) &&
(e.__e == t && (t = S(e)), B$1(e, e));
return t;
}
function A$1(n, l, u) {
var t, i;
if ('function' == typeof n.type) {
for (t = n.__k, i = 0; t && i < t.length; i++)
t[i] && ((t[i].__ = n), (l = A$1(t[i], l, u)));
return l;
}
n.__e != l &&
(l && n.type && !u.contains(l) && (l = S(n)),
u.insertBefore(n.__e, l || null),
(l = n.__e));
do {
l = l && l.nextSibling;
} while (null != l && 8 == l.nodeType);
return l;
}
function L(n, l, u, t) {
var i,
r,
o = n.key,
e = n.type,
f = l[u];
if (
(null === f && null == n.key) ||
(f && o == f.key && e == f.type && 0 == (2 & f.__u))
)
return u;
if (t > (null != f && 0 == (2 & f.__u) ? 1 : 0))
for (i = u - 1, r = u + 1; i >= 0 || r < l.length; ) {
if (i >= 0) {
if ((f = l[i]) && 0 == (2 & f.__u) && o == f.key && e == f.type)
return i;
i--;
}
if (r < l.length) {
if ((f = l[r]) && 0 == (2 & f.__u) && o == f.key && e == f.type)
return r;
r++;
}
}
return -1;
}
function T$1(n, l, u) {
'-' == l[0]
? n.setProperty(l, null == u ? '' : u)
: (n[l] =
null == u
? ''
: 'number' != typeof u || y$1.test(l)
? u
: u + 'px');
}
function j$1(n, l, u, t, i) {
var r, o;
n: if ('style' == l)
if ('string' == typeof u) n.style.cssText = u;
else {
if (('string' == typeof t && (n.style.cssText = t = ''), t))
for (l in t) (u && l in u) || T$1(n.style, l, '');
if (u) for (l in u) (t && u[l] == t[l]) || T$1(n.style, l, u[l]);
}
else if ('o' == l[0] && 'n' == l[1])
((r = l != (l = l.replace(f$2, '$1'))),
(o = l.toLowerCase()),
(l =
o in n || 'onFocusOut' == l || 'onFocusIn' == l
? o.slice(2)
: l.slice(2)),
n.l || (n.l = {}),
(n.l[l + r] = u),
u
? t
? (u.u = t.u)
: ((u.u = c$1), n.addEventListener(l, r ? a$1 : s$1, r))
: n.removeEventListener(l, r ? a$1 : s$1, r));
else {
if ('http://www.w3.org/2000/svg' == i)
l = l.replace(/xlink(H|:h)/, 'h').replace(/sName$/, 's');
else if (
'width' != l &&
'height' != l &&
'href' != l &&
'list' != l &&
'form' != l &&
'tabIndex' != l &&
'download' != l &&
'rowSpan' != l &&
'colSpan' != l &&
'role' != l &&
'popover' != l &&
l in n
)
try {
n[l] = null == u ? '' : u;
break n;
} catch (n) {}
'function' == typeof u ||
(null == u || (false === u && '-' != l[4])
? n.removeAttribute(l)
: n.setAttribute(l, 'popover' == l && 1 == u ? '' : u));
}
}
function F(n) {
return function (u) {
if (this.l) {
var t = this.l[u.type + n];
if (null == u.t) u.t = c$1++;
else if (u.t < t.u) return;
return t(l$1.event ? l$1.event(u) : u);
}
};
}
function O(n, u, t, i, r, o, e, f, c, s) {
var a,
h,
p,
v,
y,
_,
m,
b,
S,
C,
M,
$,
P,
A,
H,
L,
T,
j = u.type;
if (null != u.constructor) return null;
(128 & t.__u && ((c = !!(32 & t.__u)), (o = [(f = u.__e = t.__e)])),
(a = l$1.__b) && a(u));
n: if ('function' == typeof j)
try {
if (
((b = u.props),
(S = 'prototype' in j && j.prototype.render),
(C = (a = j.contextType) && i[a.__c]),
(M = a ? (C ? C.props.value : a.__) : i),
t.__c
? (m = (h = u.__c = t.__c).__ = h.__E)
: (S
? (u.__c = h = new j(b, M))
: ((u.__c = h = new x$1(b, M)),
(h.constructor = j),
(h.render = D$1)),
C && C.sub(h),
(h.props = b),
h.state || (h.state = {}),
(h.context = M),
(h.__n = i),
(p = h.__d = !0),
(h.__h = []),
(h._sb = [])),
S && null == h.__s && (h.__s = h.state),
S &&
null != j.getDerivedStateFromProps &&
(h.__s == h.state && (h.__s = d$1({}, h.__s)),
d$1(h.__s, j.getDerivedStateFromProps(b, h.__s))),
(v = h.props),
(y = h.state),
(h.__v = u),
p)
)
(S &&
null == j.getDerivedStateFromProps &&
null != h.componentWillMount &&
h.componentWillMount(),
S &&
null != h.componentDidMount &&
h.__h.push(h.componentDidMount));
else {
if (
(S &&
null == j.getDerivedStateFromProps &&
b !== v &&
null != h.componentWillReceiveProps &&
h.componentWillReceiveProps(b, M),
(!h.__e &&
null != h.shouldComponentUpdate &&
!1 === h.shouldComponentUpdate(b, h.__s, M)) ||
u.__v == t.__v)
) {
for (
u.__v != t.__v &&
((h.props = b), (h.state = h.__s), (h.__d = !1)),
u.__e = t.__e,
u.__k = t.__k,
u.__k.some(function (n) {
n && (n.__ = u);
}),
$ = 0;
$ < h._sb.length;
$++
)
h.__h.push(h._sb[$]);
((h._sb = []), h.__h.length && e.push(h));
break n;
}
(null != h.componentWillUpdate &&
h.componentWillUpdate(b, h.__s, M),
S &&
null != h.componentDidUpdate &&
h.__h.push(function () {
h.componentDidUpdate(v, y, _);
}));
}
if (
((h.context = M),
(h.props = b),
(h.__P = n),
(h.__e = !1),
(P = l$1.__r),
(A = 0),
S)
) {
for (
h.state = h.__s,
h.__d = !1,
P && P(u),
a = h.render(h.props, h.state, h.context),
H = 0;
H < h._sb.length;
H++
)
h.__h.push(h._sb[H]);
h._sb = [];
} else
do {
((h.__d = !1),
P && P(u),
(a = h.render(h.props, h.state, h.context)),
(h.state = h.__s));
} while (h.__d && ++A < 25);
((h.state = h.__s),
null != h.getChildContext &&
(i = d$1(d$1({}, i), h.getChildContext())),
S &&
!p &&
null != h.getSnapshotBeforeUpdate &&
(_ = h.getSnapshotBeforeUpdate(v, y)),
(L = a),
null != a &&
a.type === k$1 &&
null == a.key &&
(L = N(a.props.children)),
(f = I(n, w$1(L) ? L : [L], u, t, i, r, o, e, f, c, s)),
(h.base = u.__e),
(u.__u &= -161),
h.__h.length && e.push(h),
m && (h.__E = h.__ = null));
} catch (n) {
if (((u.__v = null), c || null != o))
if (n.then) {
for (
u.__u |= c ? 160 : 128;
f && 8 == f.nodeType && f.nextSibling;
)
f = f.nextSibling;
((o[o.indexOf(f)] = null), (u.__e = f));
} else for (T = o.length; T--; ) g(o[T]);
else ((u.__e = t.__e), (u.__k = t.__k));
l$1.__e(n, u, t);
}
else
null == o && u.__v == t.__v
? ((u.__k = t.__k), (u.__e = t.__e))
: (f = u.__e = V(t.__e, u, t, i, r, o, e, c, s));
return ((a = l$1.diffed) && a(u), 128 & u.__u ? void 0 : f);
}
function z$1(n, u, t) {
for (var i = 0; i < t.length; i++) q$1(t[i], t[++i], t[++i]);
(l$1.__c && l$1.__c(u, n),
n.some(function (u) {
try {
((n = u.__h),
(u.__h = []),
n.some(function (n) {
n.call(u);
}));
} catch (n) {
l$1.__e(n, u.__v);
}
}));
}
function N(n) {
return 'object' != typeof n || null == n || (n.__b && n.__b > 0)
? n
: w$1(n)
? n.map(N)
: d$1({}, n);
}
function V(u, t, i, r, o, e, f, c, s) {
var a,
h,
v,
y,
d,
_,
m,
b = i.props,
k = t.props,
x = t.type;
if (
('svg' == x
? (o = 'http://www.w3.org/2000/svg')
: 'math' == x
? (o = 'http://www.w3.org/1998/Math/MathML')
: o || (o = 'http://www.w3.org/1999/xhtml'),
null != e)
)
for (a = 0; a < e.length; a++)
if (
(d = e[a]) &&
'setAttribute' in d == !!x &&
(x ? d.localName == x : 3 == d.nodeType)
) {
((u = d), (e[a] = null));
break;
}
if (null == u) {
if (null == x) return document.createTextNode(k);
((u = document.createElementNS(o, x, k.is && k)),
c && (l$1.__m && l$1.__m(t, e), (c = false)),
(e = null));
}
if (null == x) b === k || (c && u.data == k) || (u.data = k);
else {
if (
((e = e && n.call(u.childNodes)),
(b = i.props || p$1),
!c && null != e)
)
for (b = {}, a = 0; a < u.attributes.length; a++)
b[(d = u.attributes[a]).name] = d.value;
for (a in b)
if (((d = b[a]), 'children' == a));
else if ('dangerouslySetInnerHTML' == a) v = d;
else if (!(a in k)) {
if (
('value' == a && 'defaultValue' in k) ||
('checked' == a && 'defaultChecked' in k)
)
continue;
j$1(u, a, null, d, o);
}
for (a in k)
((d = k[a]),
'children' == a
? (y = d)
: 'dangerouslySetInnerHTML' == a
? (h = d)
: 'value' == a
? (_ = d)
: 'checked' == a
? (m = d)
: (c && 'function' != typeof d) ||
b[a] === d ||
j$1(u, a, d, b[a], o));
if (h)
(c ||
(v && (h.__html == v.__html || h.__html == u.innerHTML)) ||
(u.innerHTML = h.__html),
(t.__k = []));
else if (
(v && (u.innerHTML = ''),
I(
'template' == t.type ? u.content : u,
w$1(y) ? y : [y],
t,
i,
r,
'foreignObject' == x ? 'http://www.w3.org/1999/xhtml' : o,
e,
f,
e ? e[0] : i.__k && S(i, 0),
c,
s
),
null != e)
)
for (a = e.length; a--; ) g(e[a]);
c ||
((a = 'value'),
'progress' == x && null == _
? u.removeAttribute('value')
: null != _ &&
(_ !== u[a] ||
('progress' == x && !_) ||
('option' == x && _ != b[a])) &&
j$1(u, a, _, b[a], o),
(a = 'checked'),
null != m && m != u[a] && j$1(u, a, m, b[a], o));
}
return u;
}
function q$1(n, u, t) {
try {
if ('function' == typeof n) {
var i = 'function' == typeof n.__u;
(i && n.__u(), (i && null == u) || (n.__u = n(u)));
} else n.current = u;
} catch (n) {
l$1.__e(n, t);
}
}
function B$1(n, u, t) {
var i, r;
if (
(l$1.unmount && l$1.unmount(n),
(i = n.ref) &&
((i.current && i.current != n.__e) || q$1(i, null, u)),
null != (i = n.__c))
) {
if (i.componentWillUnmount)
try {
i.componentWillUnmount();
} catch (n) {
l$1.__e(n, u);
}
i.base = i.__P = null;
}
if ((i = n.__k))
for (r = 0; r < i.length; r++)
i[r] && B$1(i[r], u, t || 'function' != typeof n.type);
(t || g(n.__e), (n.__c = n.__ = n.__e = void 0));
}
function D$1(n, l, u) {
return this.constructor(n, u);
}
function E(u, t, i) {
var r, o, e, f;
(t == document && (t = document.documentElement),
l$1.__ && l$1.__(u, t),
(o = (r = 'function' == 'undefined') ? null : t.__k),
(e = []),
(f = []),
O(
t,
(u = t.__k = _$1(k$1, null, [u])),
o || p$1,
p$1,
t.namespaceURI,
o ? null : t.firstChild ? n.call(t.childNodes) : null,
e,
o ? o.__e : t.firstChild,
r,
f
),
z$1(e, u, f));
}
function K(n) {
function l(n) {
var u, t;
return (
this.getChildContext ||
((u = new Set()),
((t = {})[l.__c] = this),
(this.getChildContext = function () {
return t;
}),
(this.componentWillUnmount = function () {
u = null;
}),
(this.shouldComponentUpdate = function (n) {
this.props.value != n.value &&
u.forEach(function (n) {
((n.__e = true), M(n));
});
}),
(this.sub = function (n) {
u.add(n);
var l = n.componentWillUnmount;
n.componentWillUnmount = function () {
(u && u.delete(n), l && l.call(n));
};
})),
n.children
);
}
return (
(l.__c = '__cC' + h$1++),
(l.__ = n),
(l.Provider =
l.__l =
(l.Consumer = function (n, l) {
return n.children(l);
}).contextType =
l),
l
);
}
((n = v$1.slice),
(l$1 = {
__e: function (n, l, u, t) {
for (var i, r, o; (l = l.__); )
if ((i = l.__c) && !i.__)
try {
if (
((r = i.constructor) &&
null != r.getDerivedStateFromError &&
(i.setState(r.getDerivedStateFromError(n)),
(o = i.__d)),
null != i.componentDidCatch &&
(i.componentDidCatch(n, t || {}), (o = i.__d)),
o)
)
return (i.__E = i);
} catch (l) {
n = l;
}
throw n;
},
}),
(u$2 = 0),
(x$1.prototype.setState = function (n, l) {
var u;
((u =
null != this.__s && this.__s != this.state
? this.__s
: (this.__s = d$1({}, this.state))),
'function' == typeof n && (n = n(d$1({}, u), this.props)),
n && d$1(u, n),
null != n && this.__v && (l && this._sb.push(l), M(this)));
}),
(x$1.prototype.forceUpdate = function (n) {
this.__v && ((this.__e = true), n && this.__h.push(n), M(this));
}),
(x$1.prototype.render = k$1),
(i$1 = []),
(o$1 =
'function' == typeof Promise
? Promise.prototype.then.bind(Promise.resolve())
: setTimeout),
(e$1 = function (n, l) {
return n.__v.__b - l.__v.__b;
}),
($.__r = 0),
(f$2 = /(PointerCapture)$|Capture$/i),
(c$1 = 0),
(s$1 = F(false)),
(a$1 = F(true)),
(h$1 = 0));
var f$1 = 0;
function u$1(e, t, n, o, i, u) {
t || (t = {});
var a,
c,
p = t;
if ('ref' in p)
for (c in ((p = {}), t)) 'ref' == c ? (a = t[c]) : (p[c] = t[c]);
var l = {
type: e,
props: p,
key: n,
ref: a,
__k: null,
__: null,
__b: 0,
__e: null,
__c: null,
constructor: void 0,
__v: --f$1,
__i: -1,
__u: 0,
__source: i,
__self: u,
};
if ('function' == typeof e && (a = e.defaultProps))
for (c in a) void 0 === p[c] && (p[c] = a[c]);
return (l$1.vnode && l$1.vnode(l), l);
}
function count$1(node) {
var sum = 0,
children = node.children,
i = children && children.length;
if (!i) sum = 1;
else while (--i >= 0) sum += children[i].value;
node.value = sum;
}
function node_count() {
return this.eachAfter(count$1);
}
function node_each(callback, that) {
let index = -1;
for (const node of this) {
callback.call(that, node, ++index, this);
}
return this;
}
function node_eachBefore(callback, that) {
var node = this,
nodes = [node],
children,
i,
index = -1;
while ((node = nodes.pop())) {
callback.call(that, node, ++index, this);
if ((children = node.children)) {
for (i = children.length - 1; i >= 0; --i) {
nodes.push(children[i]);
}
}
}
return this;
}
function node_eachAfter(callback, that) {
var node = this,
nodes = [node],
next = [],
children,
i,
n,
index = -1;
while ((node = nodes.pop())) {
next.push(node);
if ((children = node.children)) {
for (i = 0, n = children.length; i < n; ++i) {
nodes.push(children[i]);
}
}
}
while ((node = next.pop())) {
callback.call(that, node, ++index, this);
}
return this;
}
function node_find(callback, that) {
let index = -1;
for (const node of this) {
if (callback.call(that, node, ++index, this)) {
return node;
}
}
}
function node_sum(value) {
return this.eachAfter(function (node) {
var sum = +value(node.data) || 0,
children = node.children,
i = children && children.length;
while (--i >= 0) sum += children[i].value;
node.value = sum;
});
}
function node_sort(compare) {
return this.eachBefore(function (node) {
if (node.children) {
node.children.sort(compare);
}
});
}
function node_path(end) {
var start = this,
ancestor = leastCommonAncestor(start, end),
nodes = [start];
while (start !== ancestor) {
start = start.parent;
nodes.push(start);
}
var k = nodes.length;
while (end !== ancestor) {
nodes.splice(k, 0, end);
end = end.parent;
}
return nodes;
}
function leastCommonAncestor(a, b) {
if (a === b) return a;
var aNodes = a.ancestors(),
bNodes = b.ancestors(),
c = null;
a = aNodes.pop();
b = bNodes.pop();
while (a === b) {
c = a;
a = aNodes.pop();
b = bNodes.pop();
}
return c;
}
function node_ancestors() {
var node = this,
nodes = [node];
while ((node = node.parent)) {
nodes.push(node);
}
return nodes;
}
function node_descendants() {
return Array.from(this);
}
function node_leaves() {
var leaves = [];
this.eachBefore(function (node) {
if (!node.children) {
leaves.push(node);
}
});
return leaves;
}
function node_links() {
var root = this,
links = [];
root.each(function (node) {
if (node !== root) {
// Don’t include the root’s parent, if any.
links.push({ source: node.parent, target: node });
}
});
return links;
}
function* node_iterator() {
var node = this,
current,
next = [node],
children,
i,
n;
do {
((current = next.reverse()), (next = []));
while ((node = current.pop())) {
yield node;
if ((children = node.children)) {
for (i = 0, n = children.length; i < n; ++i) {
next.push(children[i]);
}
}
}
} while (next.length);
}
function hierarchy(data, children) {
if (data instanceof Map) {
data = [undefined, data];
if (children === undefined) children = mapChildren;
} else if (children === undefined) {
children = objectChildren;
}
var root = new Node$1(data),
node,
nodes = [root],
child,
childs,
i,
n;
while ((node = nodes.pop())) {
if (
(childs = children(node.data)) &&
(n = (childs = Array.from(childs)).length)
) {
node.children = childs;
for (i = n - 1; i >= 0; --i) {
nodes.push((child = childs[i] = new Node$1(childs[i])));
child.parent = node;
child.depth = node.depth + 1;
}
}
}
return root.eachBefore(computeHeight);
}
function node_copy() {
return hierarchy(this).eachBefore(copyData);
}
function objectChildren(d) {
return d.children;
}
function mapChildren(d) {
return Array.isArray(d) ? d[1] : null;
}
function copyData(node) {
if (node.data.value !== undefined) node.value = node.data.value;
node.data = node.data.data;
}
function computeHeight(node) {
var height = 0;
do node.height = height;
while ((node = node.parent) && node.height < ++height);
}
function Node$1(data) {
this.data = data;
this.depth = this.height = 0;
this.parent = null;
}
Node$1.prototype = hierarchy.prototype = {
constructor: Node$1,
count: node_count,
each: node_each,
eachAfter: node_eachAfter,
eachBefore: node_eachBefore,
find: node_find,
sum: node_sum,
sort: node_sort,
path: node_path,
ancestors: node_ancestors,
descendants: node_descendants,
leaves: node_leaves,
links: node_links,
copy: node_copy,
[Symbol.iterator]: node_iterator,
};
function required(f) {
if (typeof f !== 'function') throw new Error();
return f;
}
function constantZero() {
return 0;
}
function constant$1(x) {
return function () {
return x;
};
}
function roundNode(node) {
node.x0 = Math.round(node.x0);
node.y0 = Math.round(node.y0);
node.x1 = Math.round(node.x1);
node.y1 = Math.round(node.y1);
}
function treemapDice(parent, x0, y0, x1, y1) {
var nodes = parent.children,
node,
i = -1,
n = nodes.length,
k = parent.value && (x1 - x0) / parent.value;
while (++i < n) {
((node = nodes[i]), (node.y0 = y0), (node.y1 = y1));
((node.x0 = x0), (node.x1 = x0 += node.value * k));
}
}
function treemapSlice(parent, x0, y0, x1, y1) {
var nodes = parent.children,
node,
i = -1,
n = nodes.length,
k = parent.value && (y1 - y0) / parent.value;
while (++i < n) {
((node = nodes[i]), (node.x0 = x0), (node.x1 = x1));
((node.y0 = y0), (node.y1 = y0 += node.value * k));
}
}
var phi = (1 + Math.sqrt(5)) / 2;
function squarifyRatio(ratio, parent, x0, y0, x1, y1) {
var rows = [],
nodes = parent.children,
row,
nodeValue,
i0 = 0,
i1 = 0,
n = nodes.length,
dx,
dy,
value = parent.value,
sumValue,
minValue,
maxValue,
newRatio,
minRatio,
alpha,
beta;
while (i0 < n) {
((dx = x1 - x0), (dy = y1 - y0));
// Find the next non-empty node.
do sumValue = nodes[i1++].value;
while (!sumValue && i1 < n);
minValue = maxValue = sumValue;
alpha = Math.max(dy / dx, dx / dy) / (value * ratio);
beta = sumValue * sumValue * alpha;
minRatio = Math.max(maxValue / beta, beta / minValue);
// Keep adding nodes while the aspect ratio maintains or improves.
for (; i1 < n; ++i1) {
sumValue += nodeValue = nodes[i1].value;
if (nodeValue < minValue) minValue = nodeValue;
if (nodeValue > maxValue) maxValue = nodeValue;
beta = sumValue * sumValue * alpha;
newRatio = Math.max(maxValue / beta, beta / minValue);
if (newRatio > minRatio) {
sumValue -= nodeValue;
break;
}
minRatio = newRatio;
}
// Position and record the row orientation.
rows.push(
(row = {
value: sumValue,
dice: dx < dy,
children: nodes.slice(i0, i1),
})
);
if (row.dice)
treemapDice(
row,
x0,
y0,
x1,
value ? (y0 += (dy * sumValue) / value) : y1
);
else
treemapSlice(
row,
x0,
y0,
value ? (x0 += (dx * sumValue) / value) : x1,
y1
);
((value -= sumValue), (i0 = i1));
}
return rows;
}
var squarify = (function custom(ratio) {
function squarify(parent, x0, y0, x1, y1) {
squarifyRatio(ratio, parent, x0, y0, x1, y1);
}
squarify.ratio = function (x) {
return custom((x = +x) > 1 ? x : 1);
};
return squarify;
})(phi);
function treemap() {
var tile = squarify,
round = false,
dx = 1,
dy = 1,
paddingStack = [0],
paddingInner = constantZero,
paddingTop = constantZero,
paddingRight = constantZero,
paddingBottom = constantZero,
paddingLeft = constantZero;
function treemap(root) {
root.x0 = root.y0 = 0;
root.x1 = dx;
root.y1 = dy;
root.eachBefore(positionNode);
paddingStack = [0];
if (round) root.eachBefore(roundNode);
return root;
}
function positionNode(node) {
var p = paddingStack[node.depth],
x0 = node.x0 + p,
y0 = node.y0 + p,
x1 = node.x1 - p,
y1 = node.y1 - p;
if (x1 < x0) x0 = x1 = (x0 + x1) / 2;
if (y1 < y0) y0 = y1 = (y0 + y1) / 2;
node.x0 = x0;
node.y0 = y0;
node.x1 = x1;
node.y1 = y1;
if (node.children) {
p = paddingStack[node.depth + 1] = paddingInner(node) / 2;
x0 += paddingLeft(node) - p;
y0 += paddingTop(node) - p;
x1 -= paddingRight(node) - p;
y1 -= paddingBottom(node) - p;
if (x1 < x0) x0 = x1 = (x0 + x1) / 2;
if (y1 < y0) y0 = y1 = (y0 + y1) / 2;
tile(node, x0, y0, x1, y1);
}
}
treemap.round = function (x) {
return arguments.length ? ((round = !!x), treemap) : round;
};
treemap.size = function (x) {
return arguments.length
? ((dx = +x[0]), (dy = +x[1]), treemap)
: [dx, dy];
};
treemap.tile = function (x) {
return arguments.length ? ((tile = required(x)), treemap) : tile;
};
treemap.padding = function (x) {
return arguments.length
? treemap.paddingInner(x).paddingOuter(x)
: treemap.paddingInner();
};
treemap.paddingInner = function (x) {
return arguments.length
? ((paddingInner = typeof x === 'function' ? x : constant$1(+x)),
treemap)
: paddingInner;
};
treemap.paddingOuter = function (x) {
return arguments.length
? treemap
.paddingTop(x)
.paddingRight(x)
.paddingBottom(x)
.paddingLeft(x)
: treemap.paddingTop();
};
treemap.paddingTop = function (x) {
return arguments.length
? ((paddingTop = typeof x === 'function' ? x : constant$1(+x)),
treemap)
: paddingTop;
};
treemap.paddingRight = function (x) {
return arguments.length
? ((paddingRight = typeof x === 'function' ? x : constant$1(+x)),
treemap)
: paddingRight;
};
treemap.paddingBottom = function (x) {
return arguments.length
? ((paddingBottom = typeof x === 'function' ? x : constant$1(+x)),
treemap)
: paddingBottom;
};
treemap.paddingLeft = function (x) {
return arguments.length
? ((paddingLeft = typeof x === 'function' ? x : constant$1(+x)),
treemap)
: paddingLeft;
};
return treemap;
}
var treemapResquarify = (function custom(ratio) {
function resquarify(parent, x0, y0, x1, y1) {
if ((rows = parent._squarify) && rows.ratio === ratio) {
var rows,
row,
nodes,
i,
j = -1,
n,
m = rows.length,
value = parent.value;
while (++j < m) {
((row = rows[j]), (nodes = row.children));
for (i = row.value = 0, n = nodes.length; i < n; ++i)
row.value += nodes[i].value;
if (row.dice)
treemapDice(
row,
x0,
y0,
x1,
value ? (y0 += ((y1 - y0) * row.value) / value) : y1
);
else
treemapSlice(
row,
x0,
y0,
value ? (x0 += ((x1 - x0) * row.value) / value) : x1,
y1
);
value -= row.value;
}
} else {
parent._squarify = rows = squarifyRatio(
ratio,
parent,
x0,
y0,
x1,
y1
);
rows.ratio = ratio;
}
}
resquarify.ratio = function (x) {
return custom((x = +x) > 1 ? x : 1);
};
return resquarify;
})(phi);
const isModuleTree = mod => 'children' in mod;
let count = 0;
class Id {
constructor(id) {
this._id = id;
const url = new URL(window.location.href);
url.hash = id;
this._href = url.toString();
}
get id() {
return this._id;
}
get href() {
return this._href;
}
toString() {
return `url(${this.href})`;
}
}
function generateUniqueId(name) {
count += 1;
const id = ['O', name, count].filter(Boolean).join('-');
return new Id(id);
}
const LABELS = {
renderedLength: 'Rendered',
gzipLength: 'Gzip',
brotliLength: 'Brotli',
};
const getAvailableSizeOptions = options => {
const availableSizeProperties = ['renderedLength'];
if (options.gzip) {
availableSizeProperties.push('gzipLength');
}
if (options.brotli) {
availableSizeProperties.push('brotliLength');
}
return availableSizeProperties;
};
var t,
r,
u,
i,
o = 0,
f = [],
c = l$1,
e = c.__b,
a = c.__r,
v = c.diffed,
l = c.__c,
m = c.unmount,
s = c.__;
function p(n, t) {
(c.__h && c.__h(r, n, o || t), (o = 0));
var u = r.__H || (r.__H = { __: [], __h: [] });
return (n >= u.__.length && u.__.push({}), u.__[n]);
}
function d(n) {
return ((o = 1), h(D, n));
}
function h(n, u, i) {
var o = p(t++, 2);
if (
((o.t = n),
!o.__c &&
((o.__ = [
D(void 0, u),
function (n) {
var t = o.__N ? o.__N[0] : o.__[0],
r = o.t(t, n);
t !== r && ((o.__N = [r, o.__[1]]), o.__c.setState({}));
},
]),
(o.__c = r),
!r.__f))
) {
var f = function (n, t, r) {
if (!o.__c.__H) return true;
var u = o.__c.__H.__.filter(function (n) {
return !!n.__c;
});
if (
u.every(function (n) {
return !n.__N;
})
)
return !c || c.call(this, n, t, r);
var i = o.__c.props !== n;
return (
u.forEach(function (n) {
if (n.__N) {
var t = n.__[0];
((n.__ = n.__N),
(n.__N = void 0),
t !== n.__[0] && (i = true));
}
}),
(c && c.call(this, n, t, r)) || i
);
};
r.__f = true;
var c = r.shouldComponentUpdate,
e = r.componentWillUpdate;
((r.componentWillUpdate = function (n, t, r) {
if (this.__e) {
var u = c;
((c = void 0), f(n, t, r), (c = u));
}
e && e.call(this, n, t, r);
}),
(r.shouldComponentUpdate = f));
}
return o.__N || o.__;
}
function y(n, u) {
var i = p(t++, 3);
!c.__s && C(i.__H, u) && ((i.__ = n), (i.u = u), r.__H.__h.push(i));
}
function _(n, u) {
var i = p(t++, 4);
!c.__s && C(i.__H, u) && ((i.__ = n), (i.u = u), r.__h.push(i));
}
function A(n) {
return (
(o = 5),
T(function () {
return { current: n };
}, [])
);
}
function T(n, r) {
var u = p(t++, 7);
return (
C(u.__H, r) && ((u.__ = n()), (u.__H = r), (u.__h = n)),
u.__
);
}
function q(n, t) {
return (
(o = 8),
T(function () {
return n;
}, t)
);
}
function x(n) {
var u = r.context[n.__c],
i = p(t++, 9);
return (
(i.c = n),
u
? (null == i.__ && ((i.__ = true), u.sub(r)), u.props.value)
: n.__
);
}
function j() {
for (var n; (n = f.shift()); )
if (n.__P && n.__H)
try {
(n.__H.__h.forEach(z), n.__H.__h.forEach(B), (n.__H.__h = []));
} catch (t) {
((n.__H.__h = []), c.__e(t, n.__v));
}
}
((c.__b = function (n) {
((r = null), e && e(n));
}),
(c.__ = function (n, t) {
(n && t.__k && t.__k.__m && (n.__m = t.__k.__m), s && s(n, t));
}),
(c.__r = function (n) {
(a && a(n), (t = 0));
var i = (r = n.__c).__H;
(i &&
(u === r
? ((i.__h = []),
(r.__h = []),
i.__.forEach(function (n) {
(n.__N && (n.__ = n.__N), (n.u = n.__N = void 0));
}))
: (i.__h.forEach(z), i.__h.forEach(B), (i.__h = []), (t = 0))),
(u = r));
}),
(c.diffed = function (n) {
v && v(n);
var t = n.__c;
(t &&
t.__H &&
(t.__H.__h.length &&
((1 !== f.push(t) && i === c.requestAnimationFrame) ||
((i = c.requestAnimationFrame) || w)(j)),
t.__H.__.forEach(function (n) {
(n.u && (n.__H = n.u), (n.u = void 0));
})),
(u = r = null));
}),
(c.__c = function (n, t) {
(t.some(function (n) {
try {
(n.__h.forEach(z),
(n.__h = n.__h.filter(function (n) {
return !n.__ || B(n);
})));
} catch (r) {
(t.some(function (n) {
n.__h && (n.__h = []);
}),
(t = []),
c.__e(r, n.__v));
}
}),
l && l(n, t));
}),
(c.unmount = function (n) {
m && m(n);
var t,
r = n.__c;
r &&
r.__H &&
(r.__H.__.forEach(function (n) {
try {
z(n);
} catch (n) {
t = n;
}
}),
(r.__H = void 0),
t && c.__e(t, r.__v));
}));
var k = 'function' == typeof requestAnimationFrame;
function w(n) {
var t,
r = function () {
(clearTimeout(u), k && cancelAnimationFrame(t), setTimeout(n));
},
u = setTimeout(r, 35);
k && (t = requestAnimationFrame(r));
}
function z(n) {
var t = r,
u = n.__c;
('function' == typeof u && ((n.__c = void 0), u()), (r = t));
}
function B(n) {
var t = r;
((n.__c = n.__()), (r = t));
}
function C(n, t) {
return (
!n ||
n.length !== t.length ||
t.some(function (t, r) {
return t !== n[r];
})
);
}
function D(n, t) {
return 'function' == typeof t ? t(n) : t;
}
const PLACEHOLDER = '*/**/file.js';
const SideBar = ({
availableSizeProperties,
sizeProperty,
setSizeProperty,
onExcludeChange,
onIncludeChange,
}) => {
const [includeValue, setIncludeValue] = d('');
const [excludeValue, setExcludeValue] = d('');
const handleSizePropertyChange = sizeProp => () => {
if (sizeProp !== sizeProperty) {
setSizeProperty(sizeProp);
}
};
const handleIncludeChange = event => {
const value = event.currentTarget.value;
setIncludeValue(value);
onIncludeChange(value);
};
const handleExcludeChange = event => {
const value = event.currentTarget.value;
setExcludeValue(value);
onExcludeChange(value);
};
return u$1('aside', {
className: 'sidebar',
children: [
u$1('div', {
className: 'size-selectors',
children:
availableSizeProperties.length > 1 &&
availableSizeProperties.map(sizeProp => {
const id = `selector-${sizeProp}`;
return u$1(
'div',
{
className: 'size-selector',
children: [
u$1('input', {
type: 'radio',
id: id,
checked: sizeProp === sizeProperty,
onChange: handleSizePropertyChange(sizeProp),
}),
u$1('label', {
htmlFor: id,
children: LABELS[sizeProp],
}),
],
},
sizeProp
);
}),
}),
u$1('div', {
className: 'module-filters',
children: [
u$1('div', {
className: 'module-filter',
children: [
u$1('label', {
htmlFor: 'module-filter-exclude',
children: 'Exclude',
}),
u$1('input', {
type: 'text',
id: 'module-filter-exclude',
value: excludeValue,
onInput: handleExcludeChange,
placeholder: PLACEHOLDER,
}),
],
}),
u$1('div', {
className: 'module-filter',
children: [
u$1('label', {
htmlFor: 'module-filter-include',
children: 'Include',
}),
u$1('input', {
type: 'text',
id: 'module-filter-include',
value: includeValue,
onInput: handleIncludeChange,
placeholder: PLACEHOLDER,
}),
],
}),
],
}),
],
});
};
function getDefaultExportFromCjs(x) {
return x &&
x.__esModule &&
Object.prototype.hasOwnProperty.call(x, 'default')
? x['default']
: x;
}
var utils = {};
var constants$1;
var hasRequiredConstants;
function requireConstants() {
if (hasRequiredConstants) return constants$1;
hasRequiredConstants = 1;
const WIN_SLASH = '\\\\/';
const WIN_NO_SLASH = `[^${WIN_SLASH}]`;
/**
* Posix glob regex
*/
const DOT_LITERAL = '\\.';
const PLUS_LITERAL = '\\+';
const QMARK_LITERAL = '\\?';
const SLASH_LITERAL = '\\/';
const ONE_CHAR = '(?=.)';
const QMARK = '[^/]';
const END_ANCHOR = `(?:${SLASH_LITERAL}|$)`;
const START_ANCHOR = `(?:^|${SLASH_LITERAL})`;
const DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`;
const NO_DOT = `(?!${DOT_LITERAL})`;
const NO_DOTS = `(?!${START_ANCHOR}${DOTS_SLASH})`;
const NO_DOT_SLASH = `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`;
const NO_DOTS_SLASH = `(?!${DOTS_SLASH})`;
const QMARK_NO_DOT = `[^.${SLASH_LITERAL}]`;
const STAR = `${QMARK}*?`;
const SEP = '/';
const POSIX_CHARS = {
DOT_LITERAL,
PLUS_LITERAL,
QMARK_LITERAL,
SLASH_LITERAL,
ONE_CHAR,
QMARK,
END_ANCHOR,
DOTS_SLASH,
NO_DOT,
NO_DOTS,
NO_DOT_SLASH,
NO_DOTS_SLASH,
QMARK_NO_DOT,
STAR,
START_ANCHOR,
SEP,
};
/**
* Windows glob regex
*/
const WINDOWS_CHARS = {
...POSIX_CHARS,
SLASH_LITERAL: `[${WIN_SLASH}]`,
QMARK: WIN_NO_SLASH,
STAR: `${WIN_NO_SLASH}*?`,
DOTS_SLASH: `${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$)`,
NO_DOT: `(?!${DOT_LITERAL})`,
NO_DOTS: `(?!(?:^|[${WIN_SLASH}])${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`,
NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}(?:[${WIN_SLASH}]|$))`,
NO_DOTS_SLASH: `(?!${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`,
QMARK_NO_DOT: `[^.${WIN_SLASH}]`,
START_ANCHOR: `(?:^|[${WIN_SLASH}])`,
END_ANCHOR: `(?:[${WIN_SLASH}]|$)`,
SEP: '\\',
};
/**
* POSIX Bracket Regex
*/
const POSIX_REGEX_SOURCE = {
alnum: 'a-zA-Z0-9',
alpha: 'a-zA-Z',
ascii: '\\x00-\\x7F',
blank: ' \\t',
cntrl: '\\x00-\\x1F\\x7F',
digit: '0-9',
graph: '\\x21-\\x7E',
lower: 'a-z',
print: '\\x20-\\x7E ',
punct: '\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~',
space: ' \\t\\r\\n\\v\\f',
upper: 'A-Z',
word: 'A-Za-z0-9_',
xdigit: 'A-Fa-f0-9',
};
constants$1 = {
MAX_LENGTH: 1024 * 64,
POSIX_REGEX_SOURCE,
// regular expressions
REGEX_BACKSLASH: /\\(?![*+?^${}(|)[\]])/g,
REGEX_NON_SPECIAL_CHARS: /^[^@![\].,$*+?^{}()|\\/]+/,
REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\]]/,
REGEX_SPECIAL_CHARS_BACKREF: /(\\?)((\W)(\3*))/g,
REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\]])/g,
REGEX_REMOVE_BACKSLASH: /(?:\[.*?[^\\]\]|\\(?=.))/g,
// Replace globs with equivalent patterns to reduce parsing time.
REPLACEMENTS: {
'***': '*',
'**/**': '**',
'**/**/**': '**',
},
// Digits
CHAR_0: 48 /* 0 */,
CHAR_9: 57 /* 9 */,
// Alphabet chars.
CHAR_UPPERCASE_A: 65 /* A */,
CHAR_LOWERCASE_A: 97 /* a */,
CHAR_UPPERCASE_Z: 90 /* Z */,
CHAR_LOWERCASE_Z: 122 /* z */,
CHAR_LEFT_PARENTHESES: 40 /* ( */,
CHAR_RIGHT_PARENTHESES: 41 /* ) */,
CHAR_ASTERISK: 42 /* * */,
// Non-alphabetic chars.
CHAR_AMPERSAND: 38 /* & */,
CHAR_AT: 64 /* @ */,
CHAR_BACKWARD_SLASH: 92 /* \ */,
CHAR_CARRIAGE_RETURN: 13 /* \r */,
CHAR_CIRCUMFLEX_ACCENT: 94 /* ^ */,
CHAR_COLON: 58 /* : */,
CHAR_COMMA: 44 /* , */,
CHAR_DOT: 46 /* . */,
CHAR_DOUBLE_QUOTE: 34 /* " */,
CHAR_EQUAL: 61 /* = */,
CHAR_EXCLAMATION_MARK: 33 /* ! */,
CHAR_FORM_FEED: 12 /* \f */,
CHAR_FORWARD_SLASH: 47 /* / */,
CHAR_GRAVE_ACCENT: 96 /* ` */,
CHAR_HASH: 35 /* # */,
CHAR_HYPHEN_MINUS: 45 /* - */,
CHAR_LEFT_ANGLE_BRACKET: 60 /* < */,
CHAR_LEFT_CURLY_BRACE: 123 /* { */,
CHAR_LEFT_SQUARE_BRACKET: 91 /* [ */,
CHAR_LINE_FEED: 10 /* \n */,
CHAR_NO_BREAK_SPACE: 160 /* \u00A0 */,
CHAR_PERCENT: 37 /* % */,
CHAR_PLUS: 43 /* + */,
CHAR_QUESTION_MARK: 63 /* ? */,
CHAR_RIGHT_ANGLE_BRACKET: 62 /* > */,
CHAR_RIGHT_CURLY_BRACE: 125 /* } */,
CHAR_RIGHT_SQUARE_BRACKET: 93 /* ] */,
CHAR_SEMICOLON: 59 /* ; */,
CHAR_SINGLE_QUOTE: 39 /* ' */,
CHAR_SPACE: 32 /* */,
CHAR_TAB: 9 /* \t */,
CHAR_UNDERSCORE: 95 /* _ */,
CHAR_VERTICAL_LINE: 124 /* | */,
CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279 /* \uFEFF */,
/**
* Create EXTGLOB_CHARS
*/
extglobChars(chars) {
return {
'!': {
type: 'negate',
open: '(?:(?!(?:',
close: `))${chars.STAR})`,
},
'?': { type: 'qmark', open: '(?:', close: ')?' },
'+': { type: 'plus', open: '(?:', close: ')+' },
'*': { type: 'star', open: '(?:', close: ')*' },
'@': { type: 'at', open: '(?:', close: ')' },
};
},
/**
* Create GLOB_CHARS
*/
globChars(win32) {
return win32 === true ? WINDOWS_CHARS : POSIX_CHARS;
},
};
return constants$1;
}
/*global navigator*/
var hasRequiredUtils;
function requireUtils() {
if (hasRequiredUtils) return utils;
hasRequiredUtils = 1;
(function (exports) {
const {
REGEX_BACKSLASH,
REGEX_REMOVE_BACKSLASH,
REGEX_SPECIAL_CHARS,
REGEX_SPECIAL_CHARS_GLOBAL,
} = /*@__PURE__*/ requireConstants();
exports.isObject = val =>
val !== null && typeof val === 'object' && !Array.isArray(val);
exports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str);
exports.isRegexChar = str =>
str.length === 1 && exports.hasRegexChars(str);
exports.escapeRegex = str =>
str.replace(REGEX_SPECIAL_CHARS_GLOBAL, '\\$1');
exports.toPosixSlashes = str => str.replace(REGEX_BACKSLASH, '/');
exports.isWindows = () => {
if (typeof navigator !== 'undefined' && navigator.platform) {
const platform = navigator.platform.toLowerCase();
return platform === 'win32' || platform === 'windows';
}
if (typeof process !== 'undefined' && process.platform) {
return process.platform === 'win32';
}
return false;
};
exports.removeBackslashes = str => {
return str.replace(REGEX_REMOVE_BACKSLASH, match => {
return match === '\\' ? '' : match;
});
};
exports.escapeLast = (input, char, lastIdx) => {
const idx = input.lastIndexOf(char, lastIdx);
if (idx === -1) return input;
if (input[idx - 1] === '\\')
return exports.escapeLast(input, char, idx - 1);
return `${input.slice(0, idx)}\\${input.slice(idx)}`;
};
exports.removePrefix = (input, state = {}) => {
let output = input;
if (output.startsWith('./')) {
output = output.slice(2);
state.prefix = './';
}
return output;
};
exports.wrapOutput = (input, state = {}, options = {}) => {
const prepend = options.contains ? '' : '^';
const append = options.contains ? '' : '$';
let output = `${prepend}(?:${input})${append}`;
if (state.negated === true) {
output = `(?:^(?!${output}).*$)`;
}
return output;
};
exports.basename = (path, { windows } = {}) => {
const segs = path.split(windows ? /[\\/]/ : '/');
const last = segs[segs.length - 1];
if (last === '') {
return segs[segs.length - 2];
}
return last;
};
})(utils);
return utils;
}
var scan_1;
var hasRequiredScan;
function requireScan() {
if (hasRequiredScan) return scan_1;
hasRequiredScan = 1;
const utils = /*@__PURE__*/ requireUtils();
const {
CHAR_ASTERISK /* * */,
CHAR_AT /* @ */,
CHAR_BACKWARD_SLASH /* \ */,
CHAR_COMMA /* , */,
CHAR_DOT /* . */,
CHAR_EXCLAMATION_MARK /* ! */,
CHAR_FORWARD_SLASH /* / */,
CHAR_LEFT_CURLY_BRACE /* { */,
CHAR_LEFT_PARENTHESES /* ( */,
CHAR_LEFT_SQUARE_BRACKET /* [ */,
CHAR_PLUS /* + */,
CHAR_QUESTION_MARK /* ? */,
CHAR_RIGHT_CURLY_BRACE /* } */,
CHAR_RIGHT_PARENTHESES /* ) */,
CHAR_RIGHT_SQUARE_BRACKET /* ] */,
} = /*@__PURE__*/ requireConstants();
const isPathSeparator = code => {
return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH;
};
const depth = token => {
if (token.isPrefix !== true) {
token.depth = token.isGlobstar ? Infinity : 1;
}
};
/**
* Quickly scans a glob pattern and returns an object with a handful of
* useful properties, like `isGlob`, `path` (the leading non-glob, if it exists),
* `glob` (the actual pattern), `negated` (true if the path starts with `!` but not
* with `!(`) and `negatedExtglob` (true if the path starts with `!(`).
*
* ```js
* const pm = require('picomatch');
* console.log(pm.scan('foo/bar/*.js'));
* { isGlob: true, input: 'foo/bar/*.js', base: 'foo/bar', glob: '*.js' }
* ```
* @param {String} `str`
* @param {Object} `options`
* @return {Object} Returns an object with tokens and regex source string.
* @api public
*/
const scan = (input, options) => {
const opts = options || {};
const length = input.length - 1;
const scanToEnd = opts.parts === true || opts.scanToEnd === true;
const slashes = [];
const tokens = [];
const parts = [];
let str = input;
let index = -1;
let start = 0;
let lastIndex = 0;
let isBrace = false;
let isBracket = false;
let isGlob = false;
let isExtglob = false;
let isGlobstar = false;
let braceEscaped = false;
let backslashes = false;
let negated = false;
let negatedExtglob = false;
let finished = false;
let braces = 0;
let prev;
let code;
let token = { value: '', depth: 0, isGlob: false };
const eos = () => index >= length;
const peek = () => str.charCodeAt(index + 1);
const advance = () => {
prev = code;
return str.charCodeAt(++index);
};
while (index < length) {
code = advance();
let next;
if (code === CHAR_BACKWARD_SLASH) {
backslashes = token.backslashes = true;
code = advance();
if (code === CHAR_LEFT_CURLY_BRACE) {
braceEscaped = true;
}
continue;
}
if (braceEscaped === true || code === CHAR_LEFT_CURLY_BRACE) {
braces++;
while (eos() !== true && (code = advance())) {
if (code === CHAR_BACKWARD_SLASH) {
backslashes = token.backslashes = true;
advance();
continue;
}
if (code === CHAR_LEFT_CURLY_BRACE) {
braces++;
continue;
}
if (
braceEscaped !== true &&
code === CHAR_DOT &&
(code = advance()) === CHAR_DOT
) {
isBrace = token.isBrace = true;
isGlob = token.isGlob = true;
finished = true;
if (scanToEnd === true) {
continue;
}
break;
}
if (braceEscaped !== true && code === CHAR_COMMA) {
isBrace = token.isBrace = true;
isGlob = token.isGlob = true;
finished = true;
if (scanToEnd === true) {
continue;
}
break;
}
if (code === CHAR_RIGHT_CURLY_BRACE) {
braces--;
if (braces === 0) {
braceEscaped = false;
isBrace = token.isBrace = true;
finished = true;
break;
}
}
}
if (scanToEnd === true) {
continue;
}
break;
}
if (code === CHAR_FORWARD_SLASH) {
slashes.push(index);
tokens.push(token);
token = { value: '', depth: 0, isGlob: false };
if (finished === true) continue;
if (prev === CHAR_DOT && index === start + 1) {
start += 2;
continue;
}
lastIndex = index + 1;
continue;
}
if (opts.noext !== true) {
const isExtglobChar =
code === CHAR_PLUS ||
code === CHAR_AT ||
code === CHAR_ASTERISK ||
code === CHAR_QUESTION_MARK ||
code === CHAR_EXCLAMATION_MARK;
if (
isExtglobChar === true &&
peek() === CHAR_LEFT_PARENTHESES
) {
isGlob = token.isGlob = true;
isExtglob = token.isExtglob = true;
finished = true;
if (code === CHAR_EXCLAMATION_MARK && index === start) {
negatedExtglob = true;
}
if (scanToEnd === true) {
while (eos() !== true && (code = advance())) {
if (code === CHAR_BACKWARD_SLASH) {
backslashes = token.backslashes = true;
code = advance();
continue;
}
if (code === CHAR_RIGHT_PARENTHESES) {
isGlob = token.isGlob = true;
finished = true;
break;
}
}
continue;
}
break;
}
}
if (code === CHAR_ASTERISK) {
if (prev === CHAR_ASTERISK)
isGlobstar = token.isGlobstar = true;
isGlob = token.isGlob = true;
finished = true;
if (scanToEnd === true) {
continue;
}
break;
}
if (code === CHAR_QUESTION_MARK) {
isGlob = token.isGlob = true;
finished = true;
if (scanToEnd === true) {
continue;
}
break;
}
if (code === CHAR_LEFT_SQUARE_BRACKET) {
while (eos() !== true && (next = advance())) {
if (next === CHAR_BACKWARD_SLASH) {
backslashes = token.backslashes = true;
advance();
continue;
}
if (next === CHAR_RIGHT_SQUARE_BRACKET) {
isBracket = token.isBracket = true;
isGlob = token.isGlob = true;
finished = true;
break;
}
}
if (scanToEnd === true) {
continue;
}
break;
}
if (
opts.nonegate !== true &&
code === CHAR_EXCLAMATION_MARK &&
index === start
) {
negated = token.negated = true;
start++;
continue;
}
if (opts.noparen !== true && code === CHAR_LEFT_PARENTHESES) {
isGlob = token.isGlob = true;
if (scanToEnd === true) {
while (eos() !== true && (code = advance())) {
if (code === CHAR_LEFT_PARENTHESES) {
backslashes = token.backslashes = true;
code = advance();
continue;
}
if (code === CHAR_RIGHT_PARENTHESES) {
finished = true;
break;
}
}
continue;
}
break;
}
if (isGlob === true) {
finished = true;
if (scanToEnd === true) {
continue;
}
break;
}
}
if (opts.noext === true) {
isExtglob = false;
isGlob = false;
}
let base = str;
let prefix = '';
let glob = '';
if (start > 0) {
prefix = str.slice(0, start);
str = str.slice(start);
lastIndex -= start;
}
if (base && isGlob === true && lastIndex > 0) {
base = str.slice(0, lastIndex);
glob = str.slice(lastIndex);
} else if (isGlob === true) {
base = '';
glob = str;
} else {
base = str;
}
if (base && base !== '' && base !== '/' && base !== str) {
if (isPathSeparator(base.charCodeAt(base.length - 1))) {
base = base.slice(0, -1);
}
}
if (opts.unescape === true) {
if (glob) glob = utils.removeBackslashes(glob);
if (base && backslashes === true) {
base = utils.removeBackslashes(base);
}
}
const state = {
prefix,
input,
start,
base,
glob,
isBrace,
isBracket,
isGlob,
isExtglob,
isGlobstar,
negated,
negatedExtglob,
};
if (opts.tokens === true) {
state.maxDepth = 0;
if (!isPathSeparator(code)) {
tokens.push(token);
}
state.tokens = tokens;
}
if (opts.parts === true || opts.tokens === true) {
let prevIndex;
for (let idx = 0; idx < slashes.length; idx++) {
const n = prevIndex ? prevIndex + 1 : start;
const i = slashes[idx];
const value = input.slice(n, i);
if (opts.tokens) {
if (idx === 0 && start !== 0) {
tokens[idx].isPrefix = true;
tokens[idx].value = prefix;
} else {
tokens[idx].value = value;
}
depth(tokens[idx]);
state.maxDepth += tokens[idx].depth;
}
if (idx !== 0 || value !== '') {
parts.push(value);
}
prevIndex = i;
}
if (prevIndex && prevIndex + 1 < input.length) {
const value = input.slice(prevIndex + 1);
parts.push(value);
if (opts.tokens) {
tokens[tokens.length - 1].value = value;
depth(tokens[tokens.length - 1]);
state.maxDepth += tokens[tokens.length - 1].depth;
}
}
state.slashes = slashes;
state.parts = parts;
}
return state;
};
scan_1 = scan;
return scan_1;
}
var parse_1;
var hasRequiredParse;
function requireParse() {
if (hasRequiredParse) return parse_1;
hasRequiredParse = 1;
const constants = /*@__PURE__*/ requireConstants();
const utils = /*@__PURE__*/ requireUtils();
/**
* Constants
*/
const {
MAX_LENGTH,
POSIX_REGEX_SOURCE,
REGEX_NON_SPECIAL_CHARS,
REGEX_SPECIAL_CHARS_BACKREF,
REPLACEMENTS,
} = constants;
/**
* Helpers
*/
const expandRange = (args, options) => {
if (typeof options.expandRange === 'function') {
return options.expandRange(...args, options);
}
args.sort();
const value = `[${args.join('-')}]`;
try {
/* eslint-disable-next-line no-new */
new RegExp(value);
} catch (ex) {
return args.map(v => utils.escapeRegex(v)).join('..');
}
return value;
};
/**
* Create the message for a syntax error
*/
const syntaxError = (type, char) => {
return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`;
};
/**
* Parse the given input string.
* @param {String} input
* @param {Object} options
* @return {Object}
*/
const parse = (input, options) => {
if (typeof input !== 'string') {
throw new TypeError('Expected a string');
}
input = REPLACEMENTS[input] || input;
const opts = { ...options };
const max =
typeof opts.maxLength === 'number'
? Math.min(MAX_LENGTH, opts.maxLength)
: MAX_LENGTH;
let len = input.length;
if (len > max) {
throw new SyntaxError(
`Input length: ${len}, exceeds maximum allowed length: ${max}`
);
}
const bos = { type: 'bos', value: '', output: opts.prepend || '' };
const tokens = [bos];
const capture = opts.capture ? '' : '?:';
// create constants based on platform, for windows or posix
const PLATFORM_CHARS = constants.globChars(opts.windows);
const EXTGLOB_CHARS = constants.extglobChars(PLATFORM_CHARS);
const {
DOT_LITERAL,
PLUS_LITERAL,
SLASH_LITERAL,
ONE_CHAR,
DOTS_SLASH,
NO_DOT,
NO_DOT_SLASH,
NO_DOTS_SLASH,
QMARK,
QMARK_NO_DOT,
STAR,
START_ANCHOR,
} = PLATFORM_CHARS;
const globstar = opts => {
return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`;
};
const nodot = opts.dot ? '' : NO_DOT;
const qmarkNoDot = opts.dot ? QMARK : QMARK_NO_DOT;
let star = opts.bash === true ? globstar(opts) : STAR;
if (opts.capture) {
star = `(${star})`;
}
// minimatch options support
if (typeof opts.noext === 'boolean') {
opts.noextglob = opts.noext;
}
const state = {
input,
index: -1,
start: 0,
dot: opts.dot === true,
consumed: '',
output: '',
prefix: '',
backtrack: false,
negated: false,
brackets: 0,
braces: 0,
parens: 0,
quotes: 0,
globstar: false,
tokens,
};
input = utils.removePrefix(input, state);
len = input.length;
const extglobs = [];
const braces = [];
const stack = [];
let prev = bos;
let value;
/**
* Tokenizing helpers
*/
const eos = () => state.index === len - 1;
const peek = (state.peek = (n = 1) => input[state.index + n]);
const advance = (state.advance = () => input[++state.index] || '');
const remaining = () => input.slice(state.index + 1);
const consume = (value = '', num = 0) => {
state.consumed += value;
state.index += num;
};
const append = token => {
state.output += token.output != null ? token.output : token.value;
consume(token.value);
};
const negate = () => {
let count = 1;
while (peek() === '!' && (peek(2) !== '(' || peek(3) === '?')) {
advance();
state.start++;
count++;
}
if (count % 2 === 0) {
return false;
}
state.negated = true;
state.start++;
return true;
};
const increment = type => {
state[type]++;
stack.push(type);
};
const decrement = type => {
state[type]--;
stack.pop();
};
/**
* Push tokens onto the tokens array. This helper speeds up
* tokenizing by 1) helping us avoid backtracking as much as possible,
* and 2) helping us avoid creating extra tokens when consecutive
* characters are plain text. This improves performance and simplifies
* lookbehinds.
*/
const push = tok => {
if (prev.type === 'globstar') {
const isBrace =
state.braces > 0 &&
(tok.type === 'comma' || tok.type === 'brace');
const isExtglob =
tok.extglob === true ||
(extglobs.length &&
(tok.type === 'pipe' || tok.type === 'paren'));
if (
tok.type !== 'slash' &&
tok.type !== 'paren' &&
!isBrace &&
!isExtglob
) {
state.output = state.output.slice(0, -prev.output.length);
prev.type = 'star';
prev.value = '*';
prev.output = star;
state.output += prev.output;
}
}
if (extglobs.length && tok.type !== 'paren') {
extglobs[extglobs.length - 1].inner += tok.value;
}
if (tok.value || tok.output) append(tok);
if (prev && prev.type === 'text' && tok.type === 'text') {
prev.output = (prev.output || prev.value) + tok.value;
prev.value += tok.value;
return;
}
tok.prev = prev;
tokens.push(tok);
prev = tok;
};
const extglobOpen = (type, value) => {
const token = {
...EXTGLOB_CHARS[value],
conditions: 1,
inner: '',
};
token.prev = prev;
token.parens = state.parens;
token.output = state.output;
const output = (opts.capture ? '(' : '') + token.open;
increment('parens');
push({ type, value, output: state.output ? '' : ONE_CHAR });
push({ type: 'paren', extglob: true, value: advance(), output });
extglobs.push(token);
};
const extglobClose = token => {
let output = token.close + (opts.capture ? ')' : '');
let rest;
if (token.type === 'negate') {
let extglobStar = star;
if (
token.inner &&
token.inner.length > 1 &&
token.inner.includes('/')
) {
extglobStar = globstar(opts);
}
if (
extglobStar !== star ||
eos() ||
/^\)+$/.test(remaining())
) {
output = token.close = `)$))${extglobStar}`;
}
if (
token.inner.includes('*') &&
(rest = remaining()) &&
/^\.[^\\/.]+$/.test(rest)
) {
// Any non-magical string (`.ts`) or even nested expression (`.{ts,tsx}`) can follow after the closing parenthesis.
// In this case, we need to parse the string and use it in the output of the original pattern.
// Suitable patterns: `/!(*.d).ts`, `/!(*.d).{ts,tsx}`, `**/!(*-dbg).@(js)`.
//
// Disabling the `fastpaths` option due to a problem with parsing strings as `.ts` in the pattern like `**/!(*.d).ts`.
const expression = parse(rest, {
...options,
fastpaths: false,
}).output;
output = token.close = `)${expression})${extglobStar})`;
}
if (token.prev.type === 'bos') {
state.negatedExtglob = true;
}
}
push({ type: 'paren', extglob: true, value, output });
decrement('parens');
};
/**
* Fast paths
*/
if (
opts.fastpaths !== false &&
!/(^[*!]|[/()[\]{}"])/.test(input)
) {
let backslashes = false;
let output = input.replace(
REGEX_SPECIAL_CHARS_BACKREF,
(m, esc, chars, first, rest, index) => {
if (first === '\\') {
backslashes = true;
return m;
}
if (first === '?') {
if (esc) {
return (
esc + first + (rest ? QMARK.repeat(rest.length) : '')
);
}
if (index === 0) {
return (
qmarkNoDot + (rest ? QMARK.repeat(rest.length) : '')
);
}
return QMARK.repeat(chars.length);
}
if (first === '.') {
return DOT_LITERAL.repeat(chars.length);
}
if (first === '*') {
if (esc) {
return esc + first + (rest ? star : '');
}
return star;
}
return esc ? m : `\\${m}`;
}
);
if (backslashes === true) {
if (opts.unescape === true) {
output = output.replace(/\\/g, '');
} else {
output = output.replace(/\\+/g, m => {
return m.length % 2 === 0 ? '\\\\' : m ? '\\' : '';
});
}
}
if (output === input && opts.contains === true) {
state.output = input;
return state;
}
state.output = utils.wrapOutput(output, state, options);
return state;
}
/**
* Tokenize input until we reach end-of-string
*/
while (!eos()) {
value = advance();
if (value === '\u0000') {
continue;
}
/**
* Escaped characters
*/
if (value === '\\') {
const next = peek();
if (next === '/' && opts.bash !== true) {
continue;
}
if (next === '.' || next === ';') {
continue;
}
if (!next) {
value += '\\';
push({ type: 'text', value });
continue;
}
// collapse slashes to reduce potential for exploits
const match = /^\\+/.exec(remaining());
let slashes = 0;
if (match && match[0].length > 2) {
slashes = match[0].length;
state.index += slashes;
if (slashes % 2 !== 0) {
value += '\\';
}
}
if (opts.unescape === true) {
value = advance();
} else {
value += advance();
}
if (state.brackets === 0) {
push({ type: 'text', value });
continue;
}
}
/**
* If we're inside a regex character class, continue
* until we reach the closing bracket.
*/
if (
state.brackets > 0 &&
(value !== ']' || prev.value === '[' || prev.value === '[^')
) {
if (opts.posix !== false && value === ':') {
const inner = prev.value.slice(1);
if (inner.includes('[')) {
prev.posix = true;
if (inner.includes(':')) {
const idx = prev.value.lastIndexOf('[');
const pre = prev.value.slice(0, idx);
const rest = prev.value.slice(idx + 2);
const posix = POSIX_REGEX_SOURCE[rest];
if (posix) {
prev.value = pre + posix;
state.backtrack = true;
advance();
if (!bos.output && tokens.indexOf(prev) === 1) {
bos.output = ONE_CHAR;
}
continue;
}
}
}
}
if (
(value === '[' && peek() !== ':') ||
(value === '-' && peek() === ']')
) {
value = `\\${value}`;
}
if (
value === ']' &&
(prev.value === '[' || prev.value === '[^')
) {
value = `\\${value}`;
}
if (
opts.posix === true &&
value === '!' &&
prev.value === '['
) {
value = '^';
}
prev.value += value;
append({ value });
continue;
}
/**
* If we're inside a quoted string, continue
* until we reach the closing double quote.
*/
if (state.quotes === 1 && value !== '"') {
value = utils.escapeRegex(value);
prev.value += value;
append({ value });
continue;
}
/**
* Double quotes
*/
if (value === '"') {
state.quotes = state.quotes === 1 ? 0 : 1;
if (opts.keepQuotes === true) {
push({ type: 'text', value });
}
continue;
}
/**
* Parentheses
*/
if (value === '(') {
increment('parens');
push({ type: 'paren', value });
continue;
}
if (value === ')') {
if (state.parens === 0 && opts.strictBrackets === true) {
throw new SyntaxError(syntaxError('opening', '('));
}
const extglob = extglobs[extglobs.length - 1];
if (extglob && state.parens === extglob.parens + 1) {
extglobClose(extglobs.pop());
continue;
}
push({
type: 'paren',
value,
output: state.parens ? ')' : '\\)',
});
decrement('parens');
continue;
}
/**
* Square brackets
*/
if (value === '[') {
if (opts.nobracket === true || !remaining().includes(']')) {
if (opts.nobracket !== true && opts.strictBrackets === true) {
throw new SyntaxError(syntaxError('closing', ']'));
}
value = `\\${value}`;
} else {
increment('brackets');
}
push({ type: 'bracket', value });
continue;
}
if (value === ']') {
if (
opts.nobracket === true ||
(prev && prev.type === 'bracket' && prev.value.length === 1)
) {
push({ type: 'text', value, output: `\\${value}` });
continue;
}
if (state.brackets === 0) {
if (opts.strictBrackets === true) {
throw new SyntaxError(syntaxError('opening', '['));
}
push({ type: 'text', value, output: `\\${value}` });
continue;
}
decrement('brackets');
const prevValue = prev.value.slice(1);
if (
prev.posix !== true &&
prevValue[0] === '^' &&
!prevValue.includes('/')
) {
value = `/${value}`;
}
prev.value += value;
append({ value });
// when literal brackets are explicitly disabled
// assume we should match with a regex character class
if (
opts.literalBrackets === false ||
utils.hasRegexChars(prevValue)
) {
continue;
}
const escaped = utils.escapeRegex(prev.value);
state.output = state.output.slice(0, -prev.value.length);
// when literal brackets are explicitly enabled
// assume we should escape the brackets to match literal characters
if (opts.literalBrackets === true) {
state.output += escaped;
prev.value = escaped;
continue;
}
// when the user specifies nothing, try to match both
prev.value = `(${capture}${escaped}|${prev.value})`;
state.output += prev.value;
continue;
}
/**
* Braces
*/
if (value === '{' && opts.nobrace !== true) {
increment('braces');
const open = {
type: 'brace',
value,
output: '(',
outputIndex: state.output.length,
tokensIndex: state.tokens.length,
};
braces.push(open);
push(open);
continue;
}
if (value === '}') {
const brace = braces[braces.length - 1];
if (opts.nobrace === true || !brace) {
push({ type: 'text', value, output: value });
continue;
}
let output = ')';
if (brace.dots === true) {
const arr = tokens.slice();
const range = [];
for (let i = arr.length - 1; i >= 0; i--) {
tokens.pop();
if (arr[i].type === 'brace') {
break;
}
if (arr[i].type !== 'dots') {
range.
gitextract_0efm8vjk/
├── .editorconfig
├── .github/
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ └── feature_request.md
│ └── workflows/
│ └── deploy.yml
├── .gitignore
├── .nojekyll
├── .npmignore
├── .oxfmtrc.jsonc
├── .oxlintrc.json
├── .vscode/
│ ├── extensions.json
│ └── settings.json
├── .zed/
│ └── settings.json
├── CHANGELOG.md
├── CNAME
├── CONTRIBUTING.md
├── LICENSE
├── README.ja.md
├── README.md
├── README.zh.md
├── examples/
│ ├── defaultCalendarExample/
│ │ └── defaultCalendarExample.tsx
│ ├── main.tsx
│ ├── styles/
│ │ └── tailwind.css
│ └── utils/
│ ├── palette.ts
│ └── sampleData.ts
├── index.html
├── lefthook.yml
├── package.json
├── packages/
│ ├── angular/
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── ng-packagr.json
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── lib/
│ │ │ │ ├── day-flow-calendar.component.ts
│ │ │ │ ├── day-flow-calendar.module.ts
│ │ │ │ └── day-flow-portal.directive.ts
│ │ │ └── public-api.ts
│ │ └── tsconfig.json
│ ├── core/
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── bundle-analysis.html
│ │ ├── jest.config.mjs
│ │ ├── package.json
│ │ ├── postcss.build.mjs
│ │ ├── rollup.config.js
│ │ ├── scripts/
│ │ │ ├── atomic-css-baseline.json
│ │ │ ├── atomic-css-guard-utils.mjs
│ │ │ ├── build-css.mjs
│ │ │ ├── check-dist-styling.mjs
│ │ │ └── check-semantic-css.mjs
│ │ ├── src/
│ │ │ ├── components/
│ │ │ │ ├── calendarEvent/
│ │ │ │ │ ├── CalendarEvent.tsx
│ │ │ │ │ ├── __tests__/
│ │ │ │ │ │ ├── CalendarEvent.contract.test.tsx
│ │ │ │ │ │ └── CalendarEvent.timezone.test.tsx
│ │ │ │ │ ├── components/
│ │ │ │ │ │ ├── AllDayContent.tsx
│ │ │ │ │ │ ├── EventContent.tsx
│ │ │ │ │ │ ├── EventDetailPanel.tsx
│ │ │ │ │ │ ├── MonthAllDayContent.tsx
│ │ │ │ │ │ ├── MonthRegularContent.tsx
│ │ │ │ │ │ ├── RegularEventContent.tsx
│ │ │ │ │ │ ├── YearEventContent.tsx
│ │ │ │ │ │ └── __tests__/
│ │ │ │ │ │ ├── EventContent.test.tsx
│ │ │ │ │ │ └── RegularEventContent.test.tsx
│ │ │ │ │ ├── hooks/
│ │ │ │ │ │ ├── __tests__/
│ │ │ │ │ │ │ └── useEventActions.test.tsx
│ │ │ │ │ │ ├── useClickOutside.ts
│ │ │ │ │ │ ├── useDetailPanelPosition.ts
│ │ │ │ │ │ ├── useEventActions.ts
│ │ │ │ │ │ ├── useEventInteraction.ts
│ │ │ │ │ │ ├── useEventStyles.ts
│ │ │ │ │ │ └── useEventVisibility.ts
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ ├── types.ts
│ │ │ │ │ └── utils.ts
│ │ │ │ ├── common/
│ │ │ │ │ ├── BlossomColorPicker.tsx
│ │ │ │ │ ├── CalendarHeader.tsx
│ │ │ │ │ ├── CalendarPicker.tsx
│ │ │ │ │ ├── CreateCalendarDialog.tsx
│ │ │ │ │ ├── DefaultColorPicker.tsx
│ │ │ │ │ ├── DefaultEventDetailDialog.tsx
│ │ │ │ │ ├── DefaultEventDetailPanel.tsx
│ │ │ │ │ ├── EventDetailPanelWithContent.tsx
│ │ │ │ │ ├── Icons.tsx
│ │ │ │ │ ├── LoadingButton.tsx
│ │ │ │ │ ├── MiniCalendar.tsx
│ │ │ │ │ ├── QuickCreateEventPopup.tsx
│ │ │ │ │ ├── TodayBox.tsx
│ │ │ │ │ ├── ViewHeader.tsx
│ │ │ │ │ ├── ViewSwitcher.tsx
│ │ │ │ │ └── __tests__/
│ │ │ │ │ ├── MiniCalendar.test.tsx
│ │ │ │ │ └── QuickCreateEventPopup.test.tsx
│ │ │ │ ├── contextMenu/
│ │ │ │ │ ├── __tests__/
│ │ │ │ │ │ └── utils.test.ts
│ │ │ │ │ ├── components/
│ │ │ │ │ │ ├── EventContextMenu.tsx
│ │ │ │ │ │ ├── GridContextMenu.tsx
│ │ │ │ │ │ └── __tests__/
│ │ │ │ │ │ └── readOnlyContextMenus.test.tsx
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ └── utils.ts
│ │ │ │ ├── dayView/
│ │ │ │ │ ├── DayContent.tsx
│ │ │ │ │ ├── RightPanel.tsx
│ │ │ │ │ ├── __tests__/
│ │ │ │ │ │ └── util.timezone.test.ts
│ │ │ │ │ └── util.ts
│ │ │ │ ├── eventLayout/
│ │ │ │ │ ├── calculate/
│ │ │ │ │ │ ├── grouping.ts
│ │ │ │ │ │ ├── layout.ts
│ │ │ │ │ │ ├── rebalance.ts
│ │ │ │ │ │ └── structure.ts
│ │ │ │ │ ├── constants.ts
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ ├── types.ts
│ │ │ │ │ └── utils.ts
│ │ │ │ ├── mobileEventDrawer/
│ │ │ │ │ ├── DefaultMobileEventDrawer.tsx
│ │ │ │ │ ├── __tests__/
│ │ │ │ │ │ └── DefaultMobileEventDrawer.test.tsx
│ │ │ │ │ ├── components/
│ │ │ │ │ │ ├── Switch.tsx
│ │ │ │ │ │ ├── TimePickerWheel.tsx
│ │ │ │ │ │ └── __tests__/
│ │ │ │ │ │ └── Switch.test.tsx
│ │ │ │ │ └── index.ts
│ │ │ │ ├── monthView/
│ │ │ │ │ ├── MultiDayEvent.tsx
│ │ │ │ │ ├── WeekComponent.tsx
│ │ │ │ │ ├── WeekDayCell.tsx
│ │ │ │ │ ├── __tests__/
│ │ │ │ │ │ └── WeekComponent.test.tsx
│ │ │ │ │ └── util.tsx
│ │ │ │ ├── search/
│ │ │ │ │ ├── MobileSearchDialog.tsx
│ │ │ │ │ ├── SearchDrawer.tsx
│ │ │ │ │ └── SearchResultsList.tsx
│ │ │ │ ├── weekView/
│ │ │ │ │ ├── AllDayRow.tsx
│ │ │ │ │ ├── CompactHeader.tsx
│ │ │ │ │ ├── TimeGrid.tsx
│ │ │ │ │ ├── __tests__/
│ │ │ │ │ │ └── util.timezone.test.ts
│ │ │ │ │ └── util.ts
│ │ │ │ └── yearView/
│ │ │ │ ├── DefaultYearView.tsx
│ │ │ │ ├── FixedWeekMonthRow.tsx
│ │ │ │ ├── FixedWeekYearView.tsx
│ │ │ │ ├── GridDayPopup.tsx
│ │ │ │ ├── GridYearView.tsx
│ │ │ │ ├── YearDayCell.tsx
│ │ │ │ ├── YearRowComponent.tsx
│ │ │ │ ├── __tests__/
│ │ │ │ │ ├── DefaultYearView.test.tsx
│ │ │ │ │ └── utils.test.ts
│ │ │ │ └── utils.ts
│ │ │ ├── contexts/
│ │ │ │ └── ThemeContext.tsx
│ │ │ ├── core/
│ │ │ │ ├── CalendarApp.ts
│ │ │ │ ├── CalendarStore.ts
│ │ │ │ ├── __tests__/
│ │ │ │ │ ├── CalendarApp.test.ts
│ │ │ │ │ ├── WeekViewConfig.test.ts
│ │ │ │ │ └── calendarRegistry.test.ts
│ │ │ │ ├── calendarRegistry.ts
│ │ │ │ ├── config.ts
│ │ │ │ ├── events/
│ │ │ │ │ └── EventManager.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── navigation/
│ │ │ │ │ └── NavigationController.ts
│ │ │ │ ├── permissions/
│ │ │ │ │ └── CalendarPermissions.ts
│ │ │ │ ├── plugins/
│ │ │ │ │ └── PluginManager.ts
│ │ │ │ └── useCalendarApp.ts
│ │ │ ├── factories/
│ │ │ │ ├── ViewAdapter.tsx
│ │ │ │ ├── createAgendaView.ts
│ │ │ │ ├── createDayView.ts
│ │ │ │ ├── createMonthView.ts
│ │ │ │ ├── createWeekView.ts
│ │ │ │ ├── createYearView.ts
│ │ │ │ └── index.ts
│ │ │ ├── hooks/
│ │ │ │ ├── __tests__/
│ │ │ │ │ └── useCalendarDrop.test.tsx
│ │ │ │ ├── useCalendarDrop.ts
│ │ │ │ ├── useDebouncedValue.ts
│ │ │ │ ├── useWeekViewSwipe.ts
│ │ │ │ └── virtualScroll/
│ │ │ │ ├── index.ts
│ │ │ │ ├── useVirtualMonthScroll.ts
│ │ │ │ └── useVirtualScroll.ts
│ │ │ ├── index.ts
│ │ │ ├── locale/
│ │ │ │ ├── LocaleContext.tsx
│ │ │ │ ├── LocaleProvider.tsx
│ │ │ │ ├── index.ts
│ │ │ │ ├── intl.ts
│ │ │ │ ├── locales/
│ │ │ │ │ ├── en.ts
│ │ │ │ │ └── index.ts
│ │ │ │ ├── translator.ts
│ │ │ │ ├── types.ts
│ │ │ │ ├── useLocale.ts
│ │ │ │ └── utils.ts
│ │ │ ├── plugins/
│ │ │ │ ├── dragBridge.ts
│ │ │ │ ├── eventsPlugin.ts
│ │ │ │ ├── index.ts
│ │ │ │ └── sidebarBridge.ts
│ │ │ ├── renderer/
│ │ │ │ ├── CalendarRenderer.tsx
│ │ │ │ ├── CalendarRoot.tsx
│ │ │ │ ├── ContentSlot.tsx
│ │ │ │ ├── CustomRenderingContext.ts
│ │ │ │ ├── CustomRenderingStore.ts
│ │ │ │ └── hooks/
│ │ │ │ ├── __tests__/
│ │ │ │ │ └── useSearchController.test.ts
│ │ │ │ ├── useAppSubscription.ts
│ │ │ │ ├── useEventDialogController.ts
│ │ │ │ ├── useQuickCreateController.ts
│ │ │ │ ├── useResponsive.ts
│ │ │ │ └── useSearchController.ts
│ │ │ ├── setupTests.ts
│ │ │ ├── styles/
│ │ │ │ ├── __tests__/
│ │ │ │ │ └── dist-css.test.ts
│ │ │ │ ├── classNames.ts
│ │ │ │ ├── core/
│ │ │ │ │ ├── common/
│ │ │ │ │ │ ├── forms-dialogs.css
│ │ │ │ │ │ └── header-controls.css
│ │ │ │ │ ├── events/
│ │ │ │ │ │ └── calendar-event.css
│ │ │ │ │ ├── overlays/
│ │ │ │ │ │ ├── mobile-event-drawer.css
│ │ │ │ │ │ └── quick-create.css
│ │ │ │ │ ├── search/
│ │ │ │ │ │ └── search.css
│ │ │ │ │ └── views/
│ │ │ │ │ └── layout.css
│ │ │ │ ├── core-components.css
│ │ │ │ ├── library-imports.css
│ │ │ │ ├── shared-foundation.css
│ │ │ │ ├── tailwind-components.css
│ │ │ │ └── tailwind.css
│ │ │ ├── types/
│ │ │ │ ├── calendar.ts
│ │ │ │ ├── calendarTypes.ts
│ │ │ │ ├── config.ts
│ │ │ │ ├── core.ts
│ │ │ │ ├── dragIndicator.ts
│ │ │ │ ├── event.ts
│ │ │ │ ├── eventDetail.ts
│ │ │ │ ├── factory.ts
│ │ │ │ ├── hook.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── layout.ts
│ │ │ │ ├── mobileEvent.ts
│ │ │ │ ├── monthView.ts
│ │ │ │ ├── plugin.ts
│ │ │ │ ├── search.ts
│ │ │ │ └── timezone.ts
│ │ │ ├── utils/
│ │ │ │ ├── __tests__/
│ │ │ │ │ ├── allDaySort.test.ts
│ │ │ │ │ ├── crossRegionDrag.test.ts
│ │ │ │ │ ├── eventHelpers.test.ts
│ │ │ │ │ ├── helpers.test.ts
│ │ │ │ │ ├── timeUtils.test.ts
│ │ │ │ │ └── timeZoneUtils.test.ts
│ │ │ │ ├── allDaySort.ts
│ │ │ │ ├── calendarApp/
│ │ │ │ │ ├── configSync.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── normalizedConfig.ts
│ │ │ │ │ └── viewConfigComparison.ts
│ │ │ │ ├── calendarDataUtils.ts
│ │ │ │ ├── clipboardStore.ts
│ │ │ │ ├── colorUtils.ts
│ │ │ │ ├── compareUtils.ts
│ │ │ │ ├── crossRegionDrag.ts
│ │ │ │ ├── dateConstants.ts
│ │ │ │ ├── dateFormat.ts
│ │ │ │ ├── dateRangeUtils.ts
│ │ │ │ ├── dateTimeUtils.ts
│ │ │ │ ├── eventHelpers.ts
│ │ │ │ ├── eventUtils.ts
│ │ │ │ ├── helpers.ts
│ │ │ │ ├── ics/
│ │ │ │ │ ├── __tests__/
│ │ │ │ │ │ └── ics.test.ts
│ │ │ │ │ ├── icsGenerator.ts
│ │ │ │ │ ├── icsParser.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── types.ts
│ │ │ │ │ └── utils.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── logger.ts
│ │ │ │ ├── searchUtils.ts
│ │ │ │ ├── styleUtils.ts
│ │ │ │ ├── subscriptionUtils.ts
│ │ │ │ ├── temporal.ts
│ │ │ │ ├── temporalTypeGuards.ts
│ │ │ │ ├── testDataUtils.ts
│ │ │ │ ├── themeUtils.ts
│ │ │ │ ├── throttle.ts
│ │ │ │ ├── timeUtils.ts
│ │ │ │ ├── timeZoneUtils.ts
│ │ │ │ └── utilityFunctions.ts
│ │ │ └── views/
│ │ │ ├── AgendaView.tsx
│ │ │ ├── DayView.tsx
│ │ │ ├── MonthView.tsx
│ │ │ ├── WeekView.tsx
│ │ │ ├── YearView.tsx
│ │ │ └── utils/
│ │ │ ├── __tests__/
│ │ │ │ └── weekView.test.ts
│ │ │ ├── dragCreate.ts
│ │ │ └── weekView.ts
│ │ ├── tsconfig.build.json
│ │ ├── tsconfig.json
│ │ └── vite.config.ts
│ ├── create-dayflow/
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src/
│ │ │ └── index.ts
│ │ ├── tsconfig.json
│ │ └── tsup.config.ts
│ ├── plugins/
│ │ ├── drag/
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── jest.config.mjs
│ │ │ ├── package.json
│ │ │ ├── rollup.config.js
│ │ │ ├── src/
│ │ │ │ ├── components/
│ │ │ │ │ ├── DefaultDragIndicator.tsx
│ │ │ │ │ ├── DragIndicatorComponent.tsx
│ │ │ │ │ ├── MonthDragIndicator.tsx
│ │ │ │ │ └── __tests__/
│ │ │ │ │ └── MonthDragIndicator.test.tsx
│ │ │ │ ├── hooks/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── useDrag.ts
│ │ │ │ │ ├── useDragCommon.ts
│ │ │ │ │ ├── useDragHandlers.ts
│ │ │ │ │ ├── useDragManager.ts
│ │ │ │ │ ├── useDragState.ts
│ │ │ │ │ ├── useMonthDrag.ts
│ │ │ │ │ ├── useWeekDayDrag.ts
│ │ │ │ │ └── utils/
│ │ │ │ │ ├── __tests__/
│ │ │ │ │ │ ├── dateGridDrag.test.ts
│ │ │ │ │ │ ├── eventEditing.test.ts
│ │ │ │ │ │ ├── indicatorColor.test.ts
│ │ │ │ │ │ └── resolveDragSourceElement.test.ts
│ │ │ │ │ ├── dateGridDrag.ts
│ │ │ │ │ ├── dragInteraction.ts
│ │ │ │ │ ├── eventEditing.ts
│ │ │ │ │ ├── indicatorColor.ts
│ │ │ │ │ ├── resolveDragSourceElement.ts
│ │ │ │ │ └── weekDay/
│ │ │ │ │ ├── __tests__/
│ │ │ │ │ │ ├── completion.test.ts
│ │ │ │ │ │ ├── crossRegion.test.ts
│ │ │ │ │ │ ├── drag.test.ts
│ │ │ │ │ │ ├── layout.test.ts
│ │ │ │ │ │ └── preview.test.ts
│ │ │ │ │ ├── completion.ts
│ │ │ │ │ ├── crossRegion.ts
│ │ │ │ │ ├── drag.ts
│ │ │ │ │ ├── layout.ts
│ │ │ │ │ └── preview.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── plugin.ts
│ │ │ │ ├── styles/
│ │ │ │ │ └── drag.css
│ │ │ │ └── utils/
│ │ │ │ ├── defaultDragConfig.ts
│ │ │ │ └── throttle.ts
│ │ │ ├── tsconfig.build.json
│ │ │ └── tsconfig.json
│ │ ├── keyboard-shortcuts/
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── package.json
│ │ │ ├── rollup.config.js
│ │ │ ├── src/
│ │ │ │ ├── index.ts
│ │ │ │ └── plugin.ts
│ │ │ ├── tsconfig.build.json
│ │ │ └── tsconfig.json
│ │ ├── localization/
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── package.json
│ │ │ ├── rollup.config.js
│ │ │ ├── src/
│ │ │ │ ├── index.ts
│ │ │ │ ├── locales/
│ │ │ │ │ ├── de.ts
│ │ │ │ │ ├── es.ts
│ │ │ │ │ ├── fr.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── ja.ts
│ │ │ │ │ ├── ko.ts
│ │ │ │ │ ├── types.ts
│ │ │ │ │ └── zh.ts
│ │ │ │ └── plugin.ts
│ │ │ ├── tsconfig.build.json
│ │ │ └── tsconfig.json
│ │ └── sidebar/
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── rollup.config.js
│ │ ├── scripts/
│ │ │ └── build-css.mjs
│ │ ├── src/
│ │ │ ├── DefaultCalendarSidebar.tsx
│ │ │ ├── components/
│ │ │ │ ├── CalendarChip.tsx
│ │ │ │ ├── CalendarList.tsx
│ │ │ │ ├── DeleteCalendarDialog.tsx
│ │ │ │ ├── ImportCalendarDialog.tsx
│ │ │ │ ├── MergeCalendarDialog.tsx
│ │ │ │ ├── MergeMenuItem.tsx
│ │ │ │ ├── SidebarHeader.tsx
│ │ │ │ └── SubscribeCalendarDialog.tsx
│ │ │ ├── index.ts
│ │ │ ├── plugin.ts
│ │ │ └── styles/
│ │ │ ├── sidebar.css
│ │ │ ├── tailwind-components.css
│ │ │ └── tailwind.css
│ │ ├── tsconfig.build.json
│ │ └── tsconfig.json
│ ├── react/
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── rollup.config.js
│ │ ├── src/
│ │ │ ├── DayFlowCalendar.tsx
│ │ │ ├── hooks/
│ │ │ │ └── useCalendarApp.ts
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── svelte/
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── index.d.ts
│ │ ├── package.json
│ │ ├── rollup.config.js
│ │ ├── src/
│ │ │ ├── DayFlowCalendar.svelte
│ │ │ ├── index.ts
│ │ │ ├── svelte-shims.d.ts
│ │ │ └── useCalendarApp.ts
│ │ ├── svelte.config.js
│ │ └── tsconfig.json
│ ├── ui/
│ │ ├── context-menu/
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── package.json
│ │ │ ├── rollup.config.js
│ │ │ ├── scripts/
│ │ │ │ └── build-css.mjs
│ │ │ ├── src/
│ │ │ │ ├── ContextMenu.tsx
│ │ │ │ ├── index.ts
│ │ │ │ └── styles/
│ │ │ │ ├── context-menu.css
│ │ │ │ ├── tailwind-components.css
│ │ │ │ └── tailwind.css
│ │ │ ├── tsconfig.build.json
│ │ │ └── tsconfig.json
│ │ └── range-picker/
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── rollup.config.js
│ │ ├── scripts/
│ │ │ └── build-css.mjs
│ │ ├── src/
│ │ │ ├── RangePicker.tsx
│ │ │ ├── components/
│ │ │ │ ├── CalendarGrid.tsx
│ │ │ │ ├── CalendarHeader.tsx
│ │ │ │ ├── RangePickerPanel.tsx
│ │ │ │ └── TimeSelector.tsx
│ │ │ ├── constants.ts
│ │ │ ├── icons.tsx
│ │ │ ├── index.ts
│ │ │ ├── styles/
│ │ │ │ ├── range-picker.css
│ │ │ │ ├── tailwind-components.css
│ │ │ │ └── tailwind.css
│ │ │ ├── types.ts
│ │ │ └── utils/
│ │ │ ├── locale.ts
│ │ │ ├── rangePicker.ts
│ │ │ └── temporal.ts
│ │ ├── tsconfig.build.json
│ │ └── tsconfig.json
│ └── vue/
│ ├── LICENSE
│ ├── README.md
│ ├── package.json
│ ├── rollup.config.js
│ ├── src/
│ │ ├── DayFlowCalendar.ts
│ │ ├── composables/
│ │ │ └── useCalendarApp.ts
│ │ ├── index.ts
│ │ └── vue-shims.d.ts
│ └── tsconfig.json
├── pnpm-workspace.yaml
├── postcss.config.mjs
├── scripts/
│ ├── git-tag.sh
│ ├── publish.sh
│ ├── setup-website.sh
│ └── update-versions.sh
├── tailwind.config.mjs
├── tsconfig.json
├── turbo.json
└── website/
├── .gitignore
├── .prettierrc
├── README.md
├── app/
│ ├── (home)/
│ │ ├── layout.tsx
│ │ └── page.tsx
│ ├── api/
│ │ └── search/
│ │ └── route.ts
│ ├── blog/
│ │ ├── [...slug]/
│ │ │ └── page.tsx
│ │ ├── layout.tsx
│ │ └── page.tsx
│ ├── docs/
│ │ ├── [[...slug]]/
│ │ │ └── page.tsx
│ │ └── layout.tsx
│ ├── docs-ja/
│ │ ├── [[...slug]]/
│ │ │ └── page.tsx
│ │ └── layout.tsx
│ ├── docs-zh/
│ │ ├── [[...slug]]/
│ │ │ └── page.tsx
│ │ └── layout.tsx
│ ├── global.css
│ ├── layout.tsx
│ ├── llms-full.txt/
│ │ └── route.ts
│ ├── llms.txt/
│ │ └── route.ts
│ ├── og/
│ │ └── docs/
│ │ └── [...slug]/
│ │ └── route.tsx
│ ├── robots.ts
│ ├── showcase/
│ │ └── mobile-event-detail/
│ │ └── page.tsx
│ └── sitemap.ts
├── components/
│ ├── AppProvider.tsx
│ ├── CliPreview.tsx
│ ├── ColorPalette.tsx
│ ├── DocsHeader.tsx
│ ├── DocsSearchDialog.tsx
│ ├── FrameworkInstall.tsx
│ ├── FrameworkTabs.tsx
│ ├── LanguageSwitcher.tsx
│ ├── ai/
│ │ └── page-actions.tsx
│ ├── showcase/
│ │ ├── ColorPickerShowcase.tsx
│ │ ├── ContextMenuShowcase.tsx
│ │ ├── CustomDetailDialogShowcase.tsx
│ │ ├── CustomDetailPanelShowcase.tsx
│ │ ├── EventContentShowcase.tsx
│ │ ├── FeatureShowcase.tsx
│ │ ├── InteractiveCalendar.tsx
│ │ ├── LiveDemo.tsx
│ │ ├── MobileEventDetailShowcase.tsx
│ │ ├── MultiCalendarEventShowcase.tsx
│ │ ├── SidebarShowcases.tsx
│ │ ├── livedemo/
│ │ │ ├── CalendarViewer.tsx
│ │ │ ├── ControlPanel.tsx
│ │ │ ├── MiniDotsFeature.tsx
│ │ │ ├── MultiCalFeature.tsx
│ │ │ ├── ThemeColorColumn.tsx
│ │ │ └── types.ts
│ │ └── mobile-event-detail/
│ │ └── MobileEventDetailSimulator.tsx
│ └── ui/
│ ├── alert.tsx
│ ├── badge.tsx
│ ├── button.tsx
│ ├── card.tsx
│ ├── checkbox.tsx
│ ├── label.tsx
│ ├── select.tsx
│ ├── separator.tsx
│ └── tooltip.tsx
├── content/
│ ├── blog/
│ │ ├── theme-customization.mdx
│ │ ├── v1.4.mdx
│ │ ├── v1.7.mdx
│ │ ├── v1.8.mdx
│ │ ├── v2.0.3.mdx
│ │ └── v3.0.mdx
│ ├── docs/
│ │ ├── features/
│ │ │ ├── calendar-header.mdx
│ │ │ ├── content-slots.mdx
│ │ │ ├── dark-mode.mdx
│ │ │ ├── event-dialog.mdx
│ │ │ ├── meta.json
│ │ │ ├── multi-calendar-event.mdx
│ │ │ ├── read-only.mdx
│ │ │ └── switcher-mode.mdx
│ │ ├── guides/
│ │ │ ├── global-css.mdx
│ │ │ ├── meta.json
│ │ │ ├── theme-customization.mdx
│ │ │ └── timezones.mdx
│ │ ├── introduction/
│ │ │ ├── dayflow-calendar.mdx
│ │ │ ├── events.mdx
│ │ │ ├── index.mdx
│ │ │ ├── meta.json
│ │ │ ├── pro-installation.mdx
│ │ │ ├── resource-grid.mdx
│ │ │ ├── resource-timeline.mdx
│ │ │ ├── use-calendar-app.mdx
│ │ │ └── views.mdx
│ │ ├── meta.json
│ │ ├── plugins/
│ │ │ ├── drag.mdx
│ │ │ ├── events.mdx
│ │ │ ├── keyboard-shortcuts.mdx
│ │ │ ├── localization.mdx
│ │ │ ├── meta.json
│ │ │ ├── overview.mdx
│ │ │ ├── print.mdx
│ │ │ └── sidebar.mdx
│ │ └── ui/
│ │ ├── context-menu.mdx
│ │ ├── meta.json
│ │ └── range-picker.mdx
│ ├── docs-ja/
│ │ ├── features/
│ │ │ ├── calendar-header.mdx
│ │ │ ├── content-slots.mdx
│ │ │ ├── dark-mode.mdx
│ │ │ ├── event-dialog.mdx
│ │ │ ├── meta.json
│ │ │ ├── multi-calendar-event.mdx
│ │ │ ├── read-only.mdx
│ │ │ └── switcher-mode.mdx
│ │ ├── guides/
│ │ │ ├── global-css.mdx
│ │ │ ├── meta.json
│ │ │ ├── theme-customization.mdx
│ │ │ └── timezones.mdx
│ │ ├── introduction/
│ │ │ ├── dayflow-calendar.mdx
│ │ │ ├── events.mdx
│ │ │ ├── index.mdx
│ │ │ ├── meta.json
│ │ │ ├── resource-grid.mdx
│ │ │ ├── resource-timeline.mdx
│ │ │ ├── use-calendar-app.mdx
│ │ │ └── views.mdx
│ │ ├── meta.json
│ │ ├── plugins/
│ │ │ ├── drag.mdx
│ │ │ ├── events.mdx
│ │ │ ├── keyboard-shortcuts.mdx
│ │ │ ├── localization.mdx
│ │ │ ├── meta.json
│ │ │ ├── overview.mdx
│ │ │ ├── print.mdx
│ │ │ └── sidebar.mdx
│ │ └── ui/
│ │ ├── context-menu.mdx
│ │ ├── meta.json
│ │ └── range-picker.mdx
│ └── docs-zh/
│ ├── features/
│ │ ├── calendar-header.mdx
│ │ ├── content-slots.mdx
│ │ ├── dark-mode.mdx
│ │ ├── event-dialog.mdx
│ │ ├── meta.json
│ │ ├── multi-calendar-event.mdx
│ │ ├── read-only.mdx
│ │ └── switcher-mode.mdx
│ ├── guides/
│ │ ├── global-css.mdx
│ │ ├── meta.json
│ │ ├── theme-customization.mdx
│ │ └── timezones.mdx
│ ├── introduction/
│ │ ├── dayflow-calendar.mdx
│ │ ├── events.mdx
│ │ ├── index.mdx
│ │ ├── meta.json
│ │ ├── resource-grid.mdx
│ │ ├── resource-timeline.mdx
│ │ ├── use-calendar-app.mdx
│ │ └── views.mdx
│ ├── meta.json
│ ├── plugins/
│ │ ├── drag.mdx
│ │ ├── events.mdx
│ │ ├── keyboard-shortcuts.mdx
│ │ ├── localization.mdx
│ │ ├── meta.json
│ │ ├── overview.mdx
│ │ ├── print.mdx
│ │ └── sidebar.mdx
│ └── ui/
│ ├── context-menu.mdx
│ ├── meta.json
│ └── range-picker.mdx
├── eslint.config.mjs
├── lib/
│ ├── cn.ts
│ ├── i18n.ts
│ ├── layout.shared.tsx
│ ├── site.ts
│ ├── source.tsx
│ └── utils.ts
├── mdx-components.tsx
├── next.config.mjs
├── package.json
├── postcss.config.mjs
├── source.config.ts
├── tsconfig.json
└── utils/
├── palette.ts
└── sampleData.ts
SYMBOL INDEX (874 symbols across 252 files)
FILE: examples/defaultCalendarExample/defaultCalendarExample.tsx
constant TZ_OPTIONS (line 28) | const TZ_OPTIONS = Object.entries(TimeZone).map(([key, value]) => ({
type ExampleThemeMode (line 36) | type ExampleThemeMode = 'light' | 'dark';
function CalendarTypesExample (line 428) | function CalendarTypesExample() {
FILE: examples/utils/palette.ts
type PaletteCalendar (line 3) | interface PaletteCalendar extends Pick<
constant CALENDAR_SIDE_PANEL (line 13) | const CALENDAR_SIDE_PANEL: PaletteCalendar[] = [
FILE: examples/utils/sampleData.ts
constant DEFAULT_TIME_ZONE (line 121) | const DEFAULT_TIME_ZONE = Temporal.Now.timeZoneId();
type Resource (line 209) | interface Resource {
FILE: packages/angular/src/lib/day-flow-calendar.component.ts
class DayFlowCalendarComponent (line 65) | class DayFlowCalendarComponent
method constructor (line 102) | constructor(private cdr: ChangeDetectorRef) {}
method app (line 104) | private get app(): ICalendarApp {
method ngAfterViewInit (line 125) | ngAfterViewInit() {
method ngOnChanges (line 129) | ngOnChanges(changes: SimpleChanges) {
method ngOnDestroy (line 170) | ngOnDestroy() {
method getRendererProps (line 174) | private getRendererProps(): Record<string, unknown> {
method initCalendar (line 181) | private initCalendar() {
method getActiveOverrides (line 200) | private getActiveOverrides(): string[] {
method destroyCalendar (line 226) | private destroyCalendar() {
method isCalendarConfig (line 237) | private static isCalendarConfig(value: unknown): value is CalendarAppC...
method getOrCreateInternalApp (line 246) | private getOrCreateInternalApp(): CalendarApp {
method canSyncInternalCalendarConfig (line 261) | private canSyncInternalCalendarConfig(
method syncInternalCalendarConfig (line 273) | private syncInternalCalendarConfig() {
method resetInternalCalendarState (line 289) | private resetInternalCalendarState() {
method getTemplate (line 295) | getTemplate(name: string): TemplateRef<unknown> | null {
method trackById (line 359) | trackById(_index: number, item: CustomRendering) {
FILE: packages/angular/src/lib/day-flow-calendar.module.ts
class DayFlowCalendarModule (line 13) | class DayFlowCalendarModule {}
FILE: packages/angular/src/lib/day-flow-portal.directive.ts
class DayFlowPortalDirective (line 13) | class DayFlowPortalDirective implements OnChanges, OnDestroy {
method constructor (line 16) | constructor(private el: ElementRef) {}
method ngOnChanges (line 18) | ngOnChanges(changes: SimpleChanges) {
method ngOnDestroy (line 24) | ngOnDestroy() {
FILE: packages/core/scripts/atomic-css-guard-utils.mjs
constant SOURCE_SCAN_ROOTS (line 11) | const SOURCE_SCAN_ROOTS = [
constant FORBIDDEN_TOP_LEVEL_UTILITY_SELECTORS (line 18) | const FORBIDDEN_TOP_LEVEL_UTILITY_SELECTORS = [
constant SOURCE_FILE_PATTERN (line 31) | const SOURCE_FILE_PATTERN = /\.(ts|tsx|js|jsx|mjs|cjs)$/;
constant DIST_JS_PATTERN (line 32) | const DIST_JS_PATTERN = /\.(js|mjs|cjs)$/;
constant EXCLUDED_SOURCE_PATTERNS (line 33) | const EXCLUDED_SOURCE_PATTERNS = [
constant RESPONSIVE_PREFIXES (line 40) | const RESPONSIVE_PREFIXES = new Set(['sm', 'md', 'lg', 'xl', '2xl']);
constant STATE_PREFIXES (line 41) | const STATE_PREFIXES = new Set([
constant EXACT_FORBIDDEN_TOKENS (line 58) | const EXACT_FORBIDDEN_TOKENS = new Set([
constant FORBIDDEN_PREFIXES (line 76) | const FORBIDDEN_PREFIXES = [
function collectFiles (line 146) | function collectFiles(dirPath, filterPattern) {
function isDayFlowSelector (line 165) | function isDayFlowSelector(selector) {
function stripComments (line 173) | function stripComments(source) {
function shouldSkipSourceFile (line 179) | function shouldSkipSourceFile(filePath) {
function normalizeToken (line 183) | function normalizeToken(token) {
function isAllowedToken (line 190) | function isAllowedToken(token) {
function hasForbiddenVariant (line 194) | function hasForbiddenVariant(token) {
constant ALLOWED_CSS_VALUES (line 205) | const ALLOWED_CSS_VALUES = new Set([
function hasForbiddenPrefix (line 217) | function hasForbiddenPrefix(token) {
function isArbitraryUtility (line 226) | function isArbitraryUtility(token) {
function looksLikeForbiddenClassToken (line 242) | function looksLikeForbiddenClassToken(token) {
function extractTokensFromText (line 262) | function extractTokensFromText(text) {
function lineForIndex (line 271) | function lineForIndex(source, index) {
function collectForbiddenTokens (line 275) | function collectForbiddenTokens({
function scanStringLiterals (line 296) | function scanStringLiterals(filePath, content) {
function scanSourceViolations (line 348) | function scanSourceViolations() {
function scanDistJsViolations (line 363) | function scanDistJsViolations(packageRoot) {
function summarizeViolationsByFile (line 382) | function summarizeViolationsByFile(violations) {
function loadBaseline (line 390) | function loadBaseline() {
function writeBaseline (line 398) | function writeBaseline(baseline) {
function diffAgainstBaseline (line 402) | function diffAgainstBaseline(current, baselineSection) {
function parseArgs (line 413) | function parseArgs(argv) {
FILE: packages/core/scripts/build-css.mjs
function stripCascadeLayers (line 13) | function stripCascadeLayers(css) {
function buildCss (line 28) | async function buildCss(inputFile, outputFile) {
FILE: packages/core/scripts/check-dist-styling.mjs
function readCss (line 29) | function readCss(filePath) {
function checkComponentsCss (line 37) | function checkComponentsCss(css) {
FILE: packages/core/src/components/calendarEvent/CalendarEvent.tsx
constant HIGHLIGHT_POP_DURATION_MS (line 49) | const HIGHLIGHT_POP_DURATION_MS = 650;
FILE: packages/core/src/components/calendarEvent/components/AllDayContent.tsx
type AllDayContentProps (line 13) | interface AllDayContentProps {
FILE: packages/core/src/components/calendarEvent/components/EventContent.tsx
function resolveGeneratorName (line 17) | function resolveGeneratorName(
type EventContentProps (line 33) | interface EventContentProps {
FILE: packages/core/src/components/calendarEvent/components/EventDetailPanel.tsx
type EventDetailPanelProps (line 13) | interface EventDetailPanelProps {
FILE: packages/core/src/components/calendarEvent/components/MonthAllDayContent.tsx
type MonthAllDayContentProps (line 15) | interface MonthAllDayContentProps {
FILE: packages/core/src/components/calendarEvent/components/MonthRegularContent.tsx
type MonthRegularContentProps (line 19) | interface MonthRegularContentProps {
FILE: packages/core/src/components/calendarEvent/components/RegularEventContent.tsx
type RegularEventContentProps (line 24) | interface RegularEventContentProps {
FILE: packages/core/src/components/calendarEvent/components/YearEventContent.tsx
type YearEventContentProps (line 14) | interface YearEventContentProps {
FILE: packages/core/src/components/calendarEvent/hooks/__tests__/useEventActions.test.tsx
type HarnessProps (line 17) | interface HarnessProps {
FILE: packages/core/src/components/calendarEvent/hooks/useClickOutside.ts
type UseClickOutsideProps (line 4) | interface UseClickOutsideProps {
FILE: packages/core/src/components/calendarEvent/hooks/useDetailPanelPosition.ts
type UseDetailPanelPositionProps (line 9) | interface UseDetailPanelPositionProps {
FILE: packages/core/src/components/calendarEvent/hooks/useEventActions.ts
constant SINGLE_CLICK_DELAY_MS (line 10) | const SINGLE_CLICK_DELAY_MS = 180;
type UseEventActionsProps (line 12) | interface UseEventActionsProps {
FILE: packages/core/src/components/calendarEvent/hooks/useEventInteraction.ts
type UseEventInteractionProps (line 6) | interface UseEventInteractionProps {
FILE: packages/core/src/components/calendarEvent/hooks/useEventStyles.ts
constant POP_TRANSITION (line 13) | const POP_TRANSITION = 'transform 0.5s cubic-bezier(0.22, 1, 0.36, 1)';
type UseEventStylesProps (line 15) | interface UseEventStylesProps {
FILE: packages/core/src/components/calendarEvent/hooks/useEventVisibility.ts
type EventVisibility (line 11) | type EventVisibility =
type UseEventVisibilityProps (line 18) | interface UseEventVisibilityProps {
FILE: packages/core/src/components/calendarEvent/types.ts
type CalendarEventProps (line 7) | interface CalendarEventProps {
FILE: packages/core/src/components/calendarEvent/utils.ts
type EventSegmentShape (line 5) | type EventSegmentShape = 'full' | 'start' | 'end' | 'middle';
FILE: packages/core/src/components/common/BlossomColorPicker.tsx
type BlossomColorPickerProps (line 7) | interface BlossomColorPickerProps extends Partial<BlossomColorPickerOpti...
FILE: packages/core/src/components/common/CalendarPicker.tsx
type CalendarOption (line 13) | interface CalendarOption {
type CalendarPickerProps (line 18) | interface CalendarPickerProps {
FILE: packages/core/src/components/common/CreateCalendarDialog.tsx
constant PICKER_DEFAULT_COLORS (line 20) | const PICKER_DEFAULT_COLORS = [
FILE: packages/core/src/components/common/DefaultColorPicker.tsx
type DefaultColorPickerProps (line 9) | interface DefaultColorPickerProps {
FILE: packages/core/src/components/common/DefaultEventDetailDialog.tsx
type DefaultEventDetailDialogProps (line 18) | interface DefaultEventDetailDialogProps extends EventDetailDialogProps {
FILE: packages/core/src/components/common/DefaultEventDetailPanel.tsx
type DefaultEventDetailPanelProps (line 33) | interface DefaultEventDetailPanelProps extends EventDetailPanelProps {
FILE: packages/core/src/components/common/EventDetailPanelWithContent.tsx
type EventDetailPanelWithContentProps (line 16) | interface EventDetailPanelWithContentProps extends EventDetailPanelProps {
FILE: packages/core/src/components/common/Icons.tsx
type IconProps (line 1) | interface IconProps {
FILE: packages/core/src/components/common/LoadingButton.tsx
type ButtonProps (line 4) | interface ButtonProps extends Omit<
FILE: packages/core/src/components/common/MiniCalendar.tsx
constant MAX_EVENT_DOTS (line 16) | const MAX_EVENT_DOTS = 4;
type MiniCalendarProps (line 18) | interface MiniCalendarProps {
FILE: packages/core/src/components/common/QuickCreateEventPopup.tsx
type QuickCreateEventPopupProps (line 17) | interface QuickCreateEventPopupProps {
type SuggestionItem (line 24) | interface SuggestionItem {
FILE: packages/core/src/components/common/TodayBox.tsx
type Props (line 6) | interface Props {
FILE: packages/core/src/components/common/ViewHeader.tsx
type ViewHeaderType (line 9) | type ViewHeaderType = 'day' | 'week' | 'month' | 'year';
type ViewSwitcherMode (line 10) | type ViewSwitcherMode = 'buttons' | 'select';
type ViewHeaderProps (line 12) | interface ViewHeaderProps {
FILE: packages/core/src/components/common/ViewSwitcher.tsx
type ViewSwitcherProps (line 9) | interface ViewSwitcherProps {
FILE: packages/core/src/components/contextMenu/components/EventContextMenu.tsx
type EventContextMenuProps (line 16) | interface EventContextMenuProps {
FILE: packages/core/src/components/contextMenu/components/GridContextMenu.tsx
type GridContextMenuProps (line 9) | interface GridContextMenuProps {
FILE: packages/core/src/components/dayView/DayContent.tsx
type DayContentProps (line 36) | interface DayContentProps {
FILE: packages/core/src/components/dayView/RightPanel.tsx
type RightPanelProps (line 11) | interface RightPanelProps {
FILE: packages/core/src/components/eventLayout/calculate/grouping.ts
function groupOverlappingEvents (line 14) | function groupOverlappingEvents(
function analyzeParallelGroups (line 50) | function analyzeParallelGroups(
FILE: packages/core/src/components/eventLayout/calculate/layout.ts
function getIndentStepPercent (line 14) | function getIndentStepPercent(viewType?: 'week' | 'day'): number {
function calculateEventImportance (line 18) | function calculateEventImportance(event: LayoutWeekEvent): number {
function findBranchRootIndent (line 23) | function findBranchRootIndent(
function shouldChildrenBeParallel (line 34) | function shouldChildrenBeParallel(childEvents: LayoutWeekEvent[]): boole...
function calculateNodeLayoutWithVirtualParallel (line 45) | function calculateNodeLayoutWithVirtualParallel(
function calculateParallelChildrenLayout (line 120) | function calculateParallelChildrenLayout(
function calculateLayoutFromStructure (line 207) | function calculateLayoutFromStructure(
FILE: packages/core/src/components/eventLayout/calculate/rebalance.ts
function countDescendants (line 8) | function countDescendants(node: LayoutNode): number {
function calculateParentLoads (line 16) | function calculateParentLoads(
function needsRebalancing (line 29) | function needsRebalancing(
function setParentChildRelation (line 36) | function setParentChildRelation(
function transferNode (line 46) | function transferNode(leafNode: LayoutNode, newParent: LayoutNode): void {
function collectLeaves (line 70) | function collectLeaves(node: LayoutNode, leaves: LayoutNode[]): void {
function findTransferableLeaf (line 78) | function findTransferableLeaf(
function rebalanceGroupLoad (line 91) | function rebalanceGroupLoad(
function rebalanceLoadByGroups (line 116) | function rebalanceLoadByGroups(
FILE: packages/core/src/components/eventLayout/calculate/structure.ts
function checkLoadBalanceParallel (line 17) | function checkLoadBalanceParallel(
function canGroupContain (line 34) | function canGroupContain(
function findBestParentInGroup (line 62) | function findBestParentInGroup(
function findParentWithMinLoad (line 99) | function findParentWithMinLoad(
function setRelation (line 137) | function setRelation(parent: LayoutWeekEvent, child: LayoutWeekEvent) {
function countDescendants (line 144) | function countDescendants(node: LayoutNode): number {
function buildTempNodeMap (line 152) | function buildTempNodeMap(
function findAlternateBranchRoot (line 183) | function findAlternateBranchRoot(
function optimizeChildAssignments (line 218) | function optimizeChildAssignments(
function buildNestedStructure (line 309) | function buildNestedStructure(
FILE: packages/core/src/components/eventLayout/constants.ts
constant LAYOUT_CONFIG (line 1) | const LAYOUT_CONFIG = {
FILE: packages/core/src/components/eventLayout/index.tsx
method calculateDayEventLayouts (line 19) | calculateDayEventLayouts(
FILE: packages/core/src/components/eventLayout/types.ts
type LayoutWeekEvent (line 3) | interface LayoutWeekEvent extends Event {
type LayoutNode (line 11) | interface LayoutNode {
type ParallelGroup (line 19) | interface ParallelGroup {
type LayoutCalculationParams (line 27) | interface LayoutCalculationParams {
FILE: packages/core/src/components/eventLayout/utils.ts
function toLayoutEvent (line 6) | function toLayoutEvent(event: Event): LayoutWeekEvent {
function getStartHour (line 17) | function getStartHour(event: LayoutWeekEvent): number {
function getEndHour (line 21) | function getEndHour(event: LayoutWeekEvent): number {
function getOriginalStartHour (line 25) | function getOriginalStartHour(event: LayoutWeekEvent): number {
function getOriginalEndHour (line 29) | function getOriginalEndHour(event: LayoutWeekEvent): number {
function eventsOverlap (line 36) | function eventsOverlap(
function isExtendedEventParallel (line 52) | function isExtendedEventParallel(
function checkExtendedEventParallel (line 74) | function checkExtendedEventParallel(
function shouldBeParallel (line 99) | function shouldBeParallel(
function canEventContain (line 130) | function canEventContain(
FILE: packages/core/src/components/mobileEventDrawer/components/Switch.tsx
type SwitchProps (line 1) | interface SwitchProps {
FILE: packages/core/src/components/mobileEventDrawer/components/TimePickerWheel.tsx
type TimePickerWheelProps (line 3) | interface TimePickerWheelProps {
FILE: packages/core/src/components/monthView/MultiDayEvent.tsx
type MultiDayEventProps (line 34) | interface MultiDayEventProps {
constant DEFAULT_EVENT_HEIGHT (line 58) | const DEFAULT_EVENT_HEIGHT = 16;
constant POP_TRANSITION (line 59) | const POP_TRANSITION = 'transform 0.5s cubic-bezier(0.22, 1, 0.36, 1)';
FILE: packages/core/src/components/monthView/WeekComponent.tsx
type WeekComponentProps (line 22) | interface WeekComponentProps {
constant MULTI_DAY_TOP_OFFSET (line 75) | const MULTI_DAY_TOP_OFFSET = 33;
constant MORE_TEXT_HEIGHT (line 76) | const MORE_TEXT_HEIGHT = 20;
FILE: packages/core/src/components/monthView/WeekDayCell.tsx
type WeekDayCellProps (line 23) | interface WeekDayCellProps {
FILE: packages/core/src/components/monthView/util.tsx
type MultiDayEventSegment (line 17) | interface MultiDayEventSegment {
type MonthDayLayoutData (line 37) | interface MonthDayLayoutData {
constant ROW_HEIGHT (line 48) | const ROW_HEIGHT = 16;
type RegularEventSegment (line 515) | type RegularEventSegment = {
FILE: packages/core/src/components/search/MobileSearchDialog.tsx
type MobileSearchDialogProps (line 11) | interface MobileSearchDialogProps {
FILE: packages/core/src/components/search/SearchDrawer.tsx
type SearchDrawerProps (line 5) | interface SearchDrawerProps {
FILE: packages/core/src/components/search/SearchResultsList.tsx
type SearchResultsListProps (line 13) | interface SearchResultsListProps {
FILE: packages/core/src/components/weekView/AllDayRow.tsx
type AllDayRowProps (line 25) | interface AllDayRowProps {
FILE: packages/core/src/components/weekView/CompactHeader.tsx
type CompactHeaderProps (line 3) | interface CompactHeaderProps {
FILE: packages/core/src/components/weekView/TimeGrid.tsx
type TimeGridProps (line 40) | interface TimeGridProps {
FILE: packages/core/src/components/weekView/util.ts
type LayoutCacheEntry (line 92) | type LayoutCacheEntry = {
FILE: packages/core/src/components/yearView/DefaultYearView.tsx
type YearViewProps (line 35) | interface YearViewProps {
FILE: packages/core/src/components/yearView/FixedWeekMonthRow.tsx
type FixedWeekMonthRowProps (line 22) | interface FixedWeekMonthRowProps {
FILE: packages/core/src/components/yearView/FixedWeekYearView.tsx
type FixedWeekYearViewProps (line 39) | interface FixedWeekYearViewProps {
FILE: packages/core/src/components/yearView/GridDayPopup.tsx
type GridDayPopupProps (line 9) | interface GridDayPopupProps {
FILE: packages/core/src/components/yearView/GridYearView.tsx
type GridYearViewProps (line 16) | interface GridYearViewProps {
function getIntensityStyle (line 22) | function getIntensityStyle(
function getHeatLevel (line 31) | function getHeatLevel(count: number, levels: number): number {
function buildDayEventMap (line 37) | function buildDayEventMap(
function calcPopupPosition (line 87) | function calcPopupPosition(anchorEl: HTMLElement): {
FILE: packages/core/src/components/yearView/YearDayCell.tsx
type YearDayCellProps (line 5) | interface YearDayCellProps {
FILE: packages/core/src/components/yearView/YearRowComponent.tsx
type YearRowComponentProps (line 12) | interface YearRowComponentProps {
FILE: packages/core/src/components/yearView/__tests__/DefaultYearView.test.tsx
method get (line 29) | get() {
FILE: packages/core/src/components/yearView/utils.ts
type EventDayRange (line 9) | type EventDayRange = {
type YearMultiDaySegment (line 98) | interface YearMultiDaySegment {
function groupDaysIntoRows (line 111) | function groupDaysIntoRows(
function analyzeMultiDayEventsForRow (line 126) | function analyzeMultiDayEventsForRow(
type MonthEventSegment (line 249) | interface MonthEventSegment extends YearMultiDaySegment {
type FixedWeekMonthData (line 253) | interface FixedWeekMonthData {
constant EVENT_ROW_SPACING (line 262) | const EVENT_ROW_SPACING = 18;
constant DATE_HEADER_HEIGHT (line 263) | const DATE_HEADER_HEIGHT = 20;
constant MIN_ROW_HEIGHT (line 264) | const MIN_ROW_HEIGHT = 60;
function analyzeEventsForMonth (line 423) | function analyzeEventsForMonth(
type MonthSegmentCacheEntry (line 546) | type MonthSegmentCacheEntry = {
FILE: packages/core/src/contexts/ThemeContext.tsx
type ThemeContextType (line 17) | interface ThemeContextType {
type ThemeProviderProps (line 34) | interface ThemeProviderProps {
FILE: packages/core/src/core/CalendarApp.ts
class CalendarApp (line 35) | class CalendarApp implements ICalendarApp {
method constructor (line 48) | constructor(config: CalendarAppConfig) {
method resolveLocale (line 111) | private static resolveLocale(locale?: string | Locale): string | Locale {
method timeZone (line 366) | get timeZone(): string {
FILE: packages/core/src/core/CalendarStore.ts
class CalendarStore (line 15) | class CalendarStore {
method constructor (line 27) | constructor(initialEvents: Event[] = []) {
method beginTransaction (line 33) | public beginTransaction(): void {
method endTransaction (line 44) | public endTransaction(): void | Promise<void> {
method createEvent (line 64) | public createEvent(event: Event): void | Promise<void> {
method updateEvent (line 73) | public updateEvent(
method deleteEvent (line 91) | public deleteEvent(id: string): void | Promise<void> {
method getEvent (line 103) | public getEvent(id: string): Event | undefined {
method getAllEvents (line 107) | public getAllEvents(): Event[] {
method emitChange (line 113) | private emitChange(change: EventChange): void | Promise<void> {
method normalizeChanges (line 125) | private static normalizeChanges(changes: EventChange[]): EventChange[] {
FILE: packages/core/src/core/calendarRegistry.ts
constant DEFAULT_CALENDAR_TYPES (line 10) | const DEFAULT_CALENDAR_TYPES: CalendarType[] = [
class CalendarRegistry (line 187) | class CalendarRegistry {
method constructor (line 192) | constructor(
method register (line 233) | register(calendar: CalendarType): void {
method unregister (line 240) | unregister(calendarId: string): boolean {
method get (line 260) | get(calendarId: string): CalendarType | undefined {
method getAll (line 267) | getAll(): CalendarType[] {
method getVisible (line 274) | getVisible(): CalendarType[] {
method has (line 281) | has(calendarId: string): boolean {
method reorder (line 290) | reorder(fromIndex: number, toIndex: number): void {
method setVisibility (line 313) | setVisibility(calendarId: string, visible: boolean): void {
method setAllVisibility (line 333) | setAllVisibility(visible: boolean): void {
method updateCalendar (line 354) | updateCalendar(calendarId: string, updates: Partial<CalendarType>): vo...
method setDefaultCalendar (line 367) | setDefaultCalendar(calendarId: string): void {
method getDefaultCalendarId (line 377) | getDefaultCalendarId(): string {
method getDefaultCalendar (line 384) | getDefaultCalendar(): CalendarType {
method getDefaultWritableCalendar (line 398) | getDefaultWritableCalendar(): CalendarType | undefined {
method setTheme (line 407) | setTheme(theme: ThemeMode): void {
method getTheme (line 414) | getTheme(): ThemeMode {
method resolveColors (line 421) | resolveColors(calendarId?: string, theme?: ThemeMode): CalendarColors {
method getSelectedBgColor (line 446) | getSelectedBgColor(calendarId?: string, theme?: ThemeMode): string {
method getLineColor (line 454) | getLineColor(calendarId?: string, theme?: ThemeMode): string {
method getTextColor (line 462) | getTextColor(calendarId?: string, theme?: ThemeMode): string {
method isDarkTheme (line 470) | private static isDarkTheme(theme: ThemeMode): boolean {
method validate (line 485) | static validate(calendar: Partial<CalendarType>): string[] {
function getDefaultCalendarRegistry (line 529) | function getDefaultCalendarRegistry(): CalendarRegistry {
function setDefaultCalendarRegistry (line 538) | function setDefaultCalendarRegistry(registry: CalendarRegistry): void {
function getCalendarColorsForHex (line 546) | function getCalendarColorsForHex(hex: string): {
FILE: packages/core/src/core/config.ts
function isObject (line 56) | function isObject(item: any): item is Record<string, any> {
function deepMerge (line 61) | function deepMerge<T extends Record<string, any>>(
function createCalendarConfig (line 83) | function createCalendarConfig(
function createDragConfig (line 92) | function createDragConfig(
function createViewConfig (line 101) | function createViewConfig(
function validateCalendarConfig (line 111) | function validateCalendarConfig(
class ConfigManager (line 153) | class ConfigManager {
method constructor (line 156) | constructor(initialConfig?: Partial<CalendarConfig>) {
method getConfig (line 160) | getConfig(): CalendarConfig {
method getDragConfig (line 164) | getDragConfig() {
method getViewConfig (line 168) | getViewConfig(viewType: 'day' | 'week' | 'month' | 'agenda') {
method updateConfig (line 172) | updateConfig(updates: Partial<CalendarConfig>): void {
method resetConfig (line 180) | resetConfig(newConfig?: Partial<CalendarConfig>): void {
FILE: packages/core/src/core/events/EventManager.ts
class EventManager (line 11) | class EventManager {
method constructor (line 19) | constructor(
method normalizeEvent (line 35) | private normalizeEvent(event: Event): Event {
method normalizeEventUpdate (line 51) | private normalizeEventUpdate(
method setupStoreListeners (line 61) | private setupStoreListeners(): void {
method getStore (line 96) | getStore(): CalendarStore {
method pushToUndo (line 100) | pushToUndo(eventsSnapshot?: Event[]): void {
method undo (line 110) | undo(): void {
method applyEventsChanges (line 123) | applyEventsChanges(
method addEvent (line 210) | addEvent(event: Event): void {
method addExternalEvents (line 216) | addExternalEvents(calendarId: string, events: Event[]): void {
method syncExternalEventsToState (line 226) | private syncExternalEventsToState(): void {
method updateEvent (line 241) | async updateEvent(
method deleteEvent (line 296) | async deleteEvent(id: string): Promise<void> {
method getAllEvents (line 303) | getAllEvents(): Event[] {
method getEvents (line 307) | getEvents(): Event[] {
method onEventClick (line 323) | onEventClick(event: Event): void {
method onEventDoubleClick (line 327) | onEventDoubleClick(
method onMoreEventsClick (line 334) | onMoreEventsClick(date: Date): void {
method onEventDetailToggle (line 338) | onEventDetailToggle(eventId: string | null): void {
method onMobileEventDetailToggle (line 343) | onMobileEventDetailToggle(event: Event | null): void {
method highlightEvent (line 348) | highlightEvent(eventId: string | null): void {
method selectEvent (line 355) | selectEvent(eventId: string | null): void {
method dismissUI (line 362) | dismissUI(): void {
FILE: packages/core/src/core/navigation/NavigationController.ts
class NavigationController (line 13) | class NavigationController {
method getAgendaPageDays (line 16) | private static getAgendaPageDays(view?: CalendarView): number {
method constructor (line 23) | constructor(
method changeView (line 36) | changeView(view: CalendarViewType): void {
method getCurrentView (line 47) | getCurrentView(): CalendarView {
method emitVisibleRange (line 57) | emitVisibleRange(
method handleVisibleRangeChange (line 69) | handleVisibleRangeChange(reason: RangeChangeReason): void {
method setCurrentDate (line 130) | setCurrentDate(date: Date): void {
method getCurrentDate (line 138) | getCurrentDate(): Date {
method setVisibleMonth (line 142) | setVisibleMonth(date: Date): void {
method getVisibleMonth (line 154) | getVisibleMonth(): Date {
method goToToday (line 158) | goToToday(): void {
method goToPrevious (line 164) | goToPrevious(): void {
method goToNext (line 192) | goToNext(): void {
method selectDate (line 220) | selectDate(date: Date): void {
FILE: packages/core/src/core/permissions/CalendarPermissions.ts
function getReadOnlyConfig (line 8) | function getReadOnlyConfig(
function canMutateFromUI (line 49) | function canMutateFromUI(
FILE: packages/core/src/core/plugins/PluginManager.ts
class PluginManager (line 4) | class PluginManager {
method constructor (line 5) | constructor(
method install (line 10) | install(plugin: CalendarPlugin, app: ICalendarApp): void {
method getPlugin (line 19) | getPlugin<T = unknown>(name: string): T | undefined {
method hasPlugin (line 24) | hasPlugin(name: string): boolean {
method getPluginConfig (line 28) | getPluginConfig(pluginName: string): Record<string, unknown> {
method updatePluginConfig (line 33) | updatePluginConfig(
FILE: packages/core/src/core/useCalendarApp.ts
function useCalendarApp (line 25) | function useCalendarApp(
FILE: packages/core/src/factories/index.ts
function createStandardViews (line 15) | function createStandardViews(config?: {
FILE: packages/core/src/hooks/useCalendarDrop.ts
type CalendarDropData (line 8) | interface CalendarDropData {
type CalendarDropOptions (line 15) | interface CalendarDropOptions {
type CalendarDropReturn (line 20) | interface CalendarDropReturn {
function useCalendarDrop (line 33) | function useCalendarDrop(
FILE: packages/core/src/hooks/useWeekViewSwipe.ts
type UseWeekViewSwipeParams (line 6) | interface UseWeekViewSwipeParams {
FILE: packages/core/src/hooks/virtualScroll/useVirtualScroll.ts
constant VIRTUAL_SCROLL_CONFIG (line 17) | const VIRTUAL_SCROLL_CONFIG = {
FILE: packages/core/src/locale/LocaleContext.tsx
type LocaleContextValue (line 5) | interface LocaleContextValue {
FILE: packages/core/src/locale/LocaleProvider.tsx
type LocaleProviderProps (line 15) | interface LocaleProviderProps {
FILE: packages/core/src/locale/intl.ts
function getIntlLabel (line 4) | function getIntlLabel(
function capitalize (line 34) | function capitalize(str: string): string {
FILE: packages/core/src/locale/locales/index.ts
constant LOCALES (line 11) | const LOCALES: Record<string, Locale> = {
type SupportedLang (line 15) | type SupportedLang = string;
function registerLocale (line 23) | function registerLocale(locale: Locale) {
FILE: packages/core/src/locale/translator.ts
function t (line 13) | function t(key: TranslationKey, locale: LocaleCode = 'en-US'): string {
FILE: packages/core/src/locale/types.ts
type LocaleCode (line 1) | type LocaleCode = string;
type TranslationKey (line 3) | type TranslationKey =
type LocaleDict (line 78) | type LocaleDict = Partial<Record<TranslationKey, string>>;
type LocaleMessages (line 79) | type LocaleMessages = Partial<Record<TranslationKey, string>>;
type Locale (line 81) | interface Locale {
FILE: packages/core/src/locale/useLocale.ts
function useLocale (line 8) | function useLocale(): LocaleContextValue {
FILE: packages/core/src/locale/utils.ts
function normalizeLocale (line 7) | function normalizeLocale(locale: string): SupportedLang {
function isValidLocale (line 20) | function isValidLocale(locale: string): boolean {
FILE: packages/core/src/plugins/dragBridge.ts
type DragForViewFn (line 3) | type DragForViewFn = (
function registerDragImplementation (line 10) | function registerDragImplementation(fn: DragForViewFn) {
constant NO_OP (line 14) | const NO_OP: DragHookReturn = {
function useDragForView (line 36) | function useDragForView(
FILE: packages/core/src/plugins/eventsPlugin.ts
function getCurrentWeekStart (line 20) | function getCurrentWeekStart(date: Date): Date {
function createEventsPlugin (line 29) | function createEventsPlugin(
FILE: packages/core/src/plugins/index.ts
function createStandardPlugins (line 8) | function createStandardPlugins(config?: {
FILE: packages/core/src/plugins/sidebarBridge.ts
type SidebarBridgeReturn (line 3) | interface SidebarBridgeReturn {
type SidebarBridgeFn (line 14) | type SidebarBridgeFn = (app: ICalendarApp) => SidebarBridgeReturn;
function registerSidebarImplementation (line 18) | function registerSidebarImplementation(fn: SidebarBridgeFn) {
constant NO_OP (line 22) | const NO_OP: SidebarBridgeReturn = {
function useSidebarBridge (line 35) | function useSidebarBridge(app: ICalendarApp): SidebarBridgeReturn {
FILE: packages/core/src/renderer/CalendarRenderer.tsx
class CalendarRenderer (line 10) | class CalendarRenderer {
method constructor (line 17) | constructor(
method setProps (line 29) | setProps(props: Record<string, unknown>): void {
method requestRender (line 35) | private requestRender(): void {
method mount (line 49) | mount(container: HTMLElement): void {
method unmount (line 57) | unmount(): void {
method getCustomRenderingStore (line 68) | getCustomRenderingStore(): CustomRenderingStore {
method render (line 72) | private render(): void {
FILE: packages/core/src/renderer/CalendarRoot.tsx
type CalendarRootProps (line 43) | interface CalendarRootProps {
FILE: packages/core/src/renderer/ContentSlot.tsx
type ContentSlotProps (line 13) | interface ContentSlotProps {
function generateId (line 21) | function generateId() {
function ContentSlot (line 30) | function ContentSlot({
FILE: packages/core/src/renderer/CustomRenderingStore.ts
type CustomRendering (line 1) | interface CustomRendering {
type CustomRenderingListener (line 8) | type CustomRenderingListener = (
class CustomRenderingStore (line 12) | class CustomRenderingStore {
method constructor (line 18) | constructor(initialOverrides?: string[]) {
method register (line 28) | register(rendering: CustomRendering): void {
method unregister (line 36) | unregister(id: string): void {
method setOverrides (line 46) | setOverrides(names: string[]): void {
method isOverridden (line 55) | isOverridden(generatorName: string): boolean {
method subscribe (line 63) | subscribe(listener: CustomRenderingListener): () => void {
method subscribeToOverrides (line 76) | subscribeToOverrides(listener: () => void): () => void {
method notify (line 84) | private notify(): void {
method notifyOverrides (line 88) | private notifyOverrides(): void {
FILE: packages/core/src/renderer/hooks/useAppSubscription.ts
type AppSubscriptionResult (line 5) | interface AppSubscriptionResult {
function useAppSubscription (line 17) | function useAppSubscription(app: ICalendarApp): AppSubscriptionResult {
FILE: packages/core/src/renderer/hooks/useEventDialogController.ts
type DialogProps (line 12) | interface DialogProps {
type EventDialogController (line 22) | interface EventDialogController {
function useEventDialogController (line 38) | function useEventDialogController(
FILE: packages/core/src/renderer/hooks/useQuickCreateController.ts
type QuickCreateController (line 9) | interface QuickCreateController {
function useQuickCreateController (line 28) | function useQuickCreateController(
FILE: packages/core/src/renderer/hooks/useResponsive.ts
type ResponsiveResult (line 3) | interface ResponsiveResult {
function useResponsive (line 11) | function useResponsive(): ResponsiveResult {
FILE: packages/core/src/renderer/hooks/useSearchController.ts
type SearchController (line 8) | interface SearchController {
function useSearchController (line 30) | function useSearchController(
FILE: packages/core/src/setupTests.ts
method observe (line 6) | observe() {
method unobserve (line 10) | unobserve() {
method disconnect (line 14) | disconnect() {
FILE: packages/core/src/styles/__tests__/dist-css.test.ts
constant DIST (line 22) | const DIST = path.resolve(__dirname, '../../../dist');
function readDist (line 24) | function readDist(filename: string): string {
function extractBlock (line 38) | function extractBlock(css: string, selectorPattern: RegExp): string | nu...
function extractToken (line 49) | function extractToken(css: string, token: string): string | undefined {
constant REQUIRED_COLOR_MAPPINGS (line 58) | const REQUIRED_COLOR_MAPPINGS: string[] = [
constant FORBIDDEN_BARE_UTILITIES (line 84) | const FORBIDDEN_BARE_UTILITIES = [
function isDayFlowSelector (line 102) | function isDayFlowSelector(sel: string): boolean {
constant SCOPE_BLOCK_SELECTOR (line 110) | const SCOPE_BLOCK_SELECTOR =
FILE: packages/core/src/types/calendar.ts
type DayData (line 7) | interface DayData {
type WeeksData (line 21) | interface WeeksData {
FILE: packages/core/src/types/calendarTypes.ts
type CalendarColors (line 6) | interface CalendarColors {
type CalendarType (line 21) | interface CalendarType {
type ThemeMode (line 63) | type ThemeMode = 'light' | 'dark' | 'auto';
type ThemeColors (line 68) | interface ThemeColors {
type ThemeConfig (line 78) | interface ThemeConfig {
type CalendarsConfig (line 89) | interface CalendarsConfig {
FILE: packages/core/src/types/config.ts
type DragConfig (line 9) | interface DragConfig {
FILE: packages/core/src/types/core.ts
type TComponent (line 15) | type TComponent = AnyComponent<any, any>;
type TNode (line 17) | type TNode = ComponentChildren;
type ViewType (line 22) | enum ViewType {
type CalendarViewType (line 31) | type CalendarViewType = ViewType | string;
type CalendarPlugin (line 37) | interface CalendarPlugin {
type CalendarView (line 48) | interface CalendarView {
type RangeChangeReason (line 55) | type RangeChangeReason =
type EventChange (line 61) | type EventChange =
type CalendarCallbacks (line 70) | interface CalendarCallbacks {
type CalendarHeaderProps (line 113) | interface CalendarHeaderProps {
type EventContentSlotArgs (line 128) | interface EventContentSlotArgs {
type EventContextMenuSlotArgs (line 139) | interface EventContextMenuSlotArgs {
type GridContextMenuSlotArgs (line 145) | interface GridContextMenuSlotArgs {
type AllDaySortComparator (line 159) | type AllDaySortComparator = (a: Event, b: Event) => number;
type CalendarAppConfig (line 161) | interface CalendarAppConfig {
type ReadOnlyConfig (line 191) | interface ReadOnlyConfig {
type CalendarAppState (line 200) | interface CalendarAppState {
type ICalendarApp (line 222) | interface ICalendarApp {
type UseCalendarAppReturn (line 341) | interface UseCalendarAppReturn {
type CalendarConfig (line 392) | interface CalendarConfig {
type UseCalendarReturn (line 412) | interface UseCalendarReturn {
FILE: packages/core/src/types/dragIndicator.ts
type Mode (line 12) | type Mode = 'create' | 'move' | 'resize' | null;
type DragRef (line 18) | interface DragRef {
type EventDetailPosition (line 46) | interface EventDetailPosition {
type DragIndicatorProps (line 54) | interface DragIndicatorProps {
type DragIndicatorRenderer (line 73) | interface DragIndicatorRenderer {
type UnifiedDragRef (line 79) | interface UnifiedDragRef extends DragRef {
type useDragProps (line 111) | interface useDragProps extends Partial<DragConfig> {
type MonthDragState (line 144) | type MonthDragState = {
type WeekDayDragState (line 153) | type WeekDayDragState = {
type useDragReturn (line 164) | interface useDragReturn {
type MonthEventDragState (line 201) | type MonthEventDragState = MonthDragState;
type UseDragStateReturn (line 206) | interface UseDragStateReturn {
type UseDragCommonReturn (line 233) | interface UseDragCommonReturn {
type UseDragManagerReturn (line 252) | interface UseDragManagerReturn {
type UseDragHandlersReturn (line 270) | interface UseDragHandlersReturn {
type UseDragHandlersParams (line 290) | interface UseDragHandlersParams {
type UseMonthDragReturn (line 297) | interface UseMonthDragReturn {
type UseMonthDragParams (line 304) | interface UseMonthDragParams {
type UseWeekDayDragReturn (line 311) | interface UseWeekDayDragReturn {
type UseWeekDayDragParams (line 320) | interface UseWeekDayDragParams {
FILE: packages/core/src/types/event.ts
type Event (line 8) | interface Event {
FILE: packages/core/src/types/eventDetail.ts
type EventDetailPanelProps (line 15) | interface EventDetailPanelProps {
type EventDetailPanelRenderer (line 46) | type EventDetailPanelRenderer = AnyComponent<EventDetailPanelProps, any>;
type EventDetailContentProps (line 51) | interface EventDetailContentProps {
type EventDetailContentRenderer (line 68) | type EventDetailContentRenderer = AnyComponent<
type EventDetailDialogProps (line 76) | interface EventDetailDialogProps {
type EventDetailDialogRenderer (line 95) | type EventDetailDialogRenderer = AnyComponent<
FILE: packages/core/src/types/factory.ts
type BaseViewProps (line 14) | interface BaseViewProps<TConfig = unknown> {
type DayViewProps (line 50) | type DayViewProps = BaseViewProps<DayViewConfig>;
type WeekViewProps (line 55) | type WeekViewProps = BaseViewProps<WeekViewConfig>;
type MonthViewProps (line 60) | type MonthViewProps = BaseViewProps<MonthViewConfig>;
type AgendaViewProps (line 65) | type AgendaViewProps = BaseViewProps<AgendaViewConfig>;
type YearViewProps (line 70) | type YearViewProps = BaseViewProps<YearViewConfig>;
type ViewFactoryConfig (line 76) | interface ViewFactoryConfig {
type DayViewConfig (line 88) | interface DayViewConfig extends ViewFactoryConfig {
type WeekViewConfig (line 98) | interface WeekViewConfig extends ViewFactoryConfig {
type MonthScrollConfig (line 126) | interface MonthScrollConfig {
type MonthViewConfig (line 140) | interface MonthViewConfig extends ViewFactoryConfig {
type AgendaViewConfig (line 177) | interface AgendaViewConfig extends ViewFactoryConfig {
type YearViewConfig (line 201) | interface YearViewConfig extends ViewFactoryConfig {
type ViewAdapterProps (line 244) | interface ViewAdapterProps extends BaseViewProps {
type DragIntegrationProps (line 256) | interface DragIntegrationProps {
type VirtualScrollIntegrationProps (line 282) | interface VirtualScrollIntegrationProps {
type ViewFactory (line 294) | interface ViewFactory<TConfig = ViewFactoryConfig> {
FILE: packages/core/src/types/hook.ts
type VirtualItem (line 6) | interface VirtualItem {
type UseVirtualScrollProps (line 16) | interface UseVirtualScrollProps {
type UseVirtualScrollReturn (line 31) | interface UseVirtualScrollReturn {
FILE: packages/core/src/types/layout.ts
constant LAYOUT_CONFIG (line 8) | const LAYOUT_CONFIG = {
type EventLayout (line 23) | interface EventLayout {
type NestedLayer (line 38) | interface NestedLayer {
type EventGroup (line 49) | interface EventGroup {
type EventRelations (line 63) | interface EventRelations {
type SubtreeAnalysis (line 76) | interface SubtreeAnalysis {
type BalanceStrategy (line 89) | interface BalanceStrategy {
type TransferOperation (line 99) | interface TransferOperation {
type SpecialLayoutRule (line 110) | interface SpecialLayoutRule {
FILE: packages/core/src/types/mobileEvent.ts
type MobileEventProps (line 7) | interface MobileEventProps {
FILE: packages/core/src/types/monthView.ts
type UseVirtualMonthScrollProps (line 5) | interface UseVirtualMonthScrollProps {
type UseVirtualMonthScrollReturn (line 17) | interface UseVirtualMonthScrollReturn {
constant VIRTUAL_MONTH_SCROLL_CONFIG (line 48) | const VIRTUAL_MONTH_SCROLL_CONFIG = {
type VirtualWeekItem (line 62) | interface VirtualWeekItem {
class WeekDataCache (line 70) | class WeekDataCache {
method constructor (line 75) | constructor(maxSize: number = VIRTUAL_MONTH_SCROLL_CONFIG.BUFFER_SIZE) {
method getKey (line 79) | private static getKey(date: Date): string {
method get (line 83) | get(weekStartDate: Date): WeeksData | undefined {
method set (line 93) | set(weekStartDate: Date, data: WeeksData): void {
method updateAccessOrder (line 107) | private updateAccessOrder(key: string): void {
method getSize (line 115) | getSize(): number {
method clear (line 119) | clear(): void {
FILE: packages/core/src/types/plugin.ts
type TitleBarSlotProps (line 10) | interface TitleBarSlotProps {
type SidebarHeaderSlotArgs (line 15) | interface SidebarHeaderSlotArgs {
type CreateCalendarDialogColorPickerProps (line 20) | interface CreateCalendarDialogColorPickerProps {
type ColorPickerProps (line 29) | interface ColorPickerProps {
type CreateCalendarDialogProps (line 35) | interface CreateCalendarDialogProps {
type EventsService (line 46) | interface EventsService {
type EventsPluginConfig (line 73) | interface EventsPluginConfig {
type DragHookOptions (line 83) | interface DragHookOptions extends Partial<DragConfig> {
type DragHookReturn (line 116) | interface DragHookReturn {
type DragPluginConfig (line 128) | interface DragPluginConfig {
type DragService (line 156) | interface DragService {
FILE: packages/core/src/types/search.ts
type CalendarSearchEvent (line 5) | type CalendarSearchEvent = Event & {
type CalendarSearchProps (line 10) | interface CalendarSearchProps {
FILE: packages/core/src/types/timezone.ts
type TimeZone (line 7) | enum TimeZone {
type TimeZoneValue (line 139) | type TimeZoneValue = TimeZone | string;
FILE: packages/core/src/utils/calendarApp/configSync.ts
type SyncableCalendarAppConfig (line 4) | type SyncableCalendarAppConfig = Pick<
type CalendarAppConfigSyncSnapshot (line 19) | type CalendarAppConfigSyncSnapshot = {
type CalendarAppConfigUpdater (line 24) | type CalendarAppConfigUpdater = {
function pickSyncableConfig (line 28) | function pickSyncableConfig(
function createConfigSyncSnapshot (line 46) | function createConfigSyncSnapshot(
function getCallbackConfigUpdate (line 55) | function getCallbackConfigUpdate(
function getSyncConfigUpdates (line 66) | function getSyncConfigUpdates(
function syncCalendarAppConfig (line 101) | function syncCalendarAppConfig(
FILE: packages/core/src/utils/calendarApp/normalizedConfig.ts
type CalendarAppConfigGetter (line 3) | type CalendarAppConfigGetter = () => CalendarAppConfig;
function createNormalizedCalendarAppConfigGetter (line 5) | function createNormalizedCalendarAppConfigGetter(
FILE: packages/core/src/utils/calendarApp/viewConfigComparison.ts
type ViewConfigComparison (line 3) | type ViewConfigComparison = {
FILE: packages/core/src/utils/calendarDataUtils.ts
function generateWeekRange (line 133) | function generateWeekRange(
FILE: packages/core/src/utils/clipboardStore.ts
class ClipboardStore (line 3) | class ClipboardStore {
method setEvent (line 6) | setEvent(event: Event) {
method getEvent (line 10) | getEvent(): Event | null {
method hasEvent (line 14) | hasEvent(): boolean {
method clear (line 18) | clear() {
FILE: packages/core/src/utils/compareUtils.ts
function isDeepEqual (line 5) | function isDeepEqual(a: unknown, b: unknown): boolean {
FILE: packages/core/src/utils/crossRegionDrag.ts
type RestoreTimedDragOptions (line 1) | interface RestoreTimedDragOptions {
type RestoredTimedDragState (line 14) | interface RestoredTimedDragState {
FILE: packages/core/src/utils/eventHelpers.ts
type CreateEventParams (line 29) | interface CreateEventParams {
type CreateAllDayEventDateInput (line 47) | type CreateAllDayEventDateInput = Date | Temporal.PlainDate;
type CreateAllDayEventParams (line 49) | interface CreateAllDayEventParams extends Omit<
type CreateTimezoneEventParams (line 61) | interface CreateTimezoneEventParams {
function normalizeLocalTime (line 88) | function normalizeLocalTime(
function isAllDayDateInput (line 108) | function isAllDayDateInput(
function normalizeZonedTime (line 117) | function normalizeZonedTime(
function createEvent (line 174) | function createEvent(params: CreateEventParams): Event {
function createTimezoneEvent (line 226) | function createTimezoneEvent(params: CreateTimezoneEventParams): Event {
function createEvents (line 249) | function createEvents(paramsArray: CreateEventParams[]): Event[] {
function createTimezoneEvents (line 256) | function createTimezoneEvents(
function createAllDayEvent (line 295) | function createAllDayEvent(
FILE: packages/core/src/utils/ics/icsGenerator.ts
function generateICS (line 20) | function generateICS(
function downloadICS (line 56) | function downloadICS(
FILE: packages/core/src/utils/ics/icsParser.ts
function parseICS (line 22) | function parseICS(
FILE: packages/core/src/utils/ics/index.ts
function importICSFile (line 20) | async function importICSFile(
FILE: packages/core/src/utils/ics/types.ts
type ICSVEvent (line 13) | interface ICSVEvent {
type ICSDateParams (line 37) | interface ICSDateParams {
type ICSImportOptions (line 47) | interface ICSImportOptions {
type ICSExportOptions (line 61) | interface ICSExportOptions {
type ICSImportResult (line 75) | interface ICSImportResult {
type ICSParseError (line 91) | interface ICSParseError {
FILE: packages/core/src/utils/ics/utils.ts
function pad2 (line 20) | function pad2(num: number | string): string {
function parseICSDate (line 32) | function parseICSDate(
function formatICSDate (line 102) | function formatICSDate(
function formatDateToICSTimestamp (line 140) | function formatDateToICSTimestamp(date: Date): string {
function escapeICSValue (line 154) | function escapeICSValue(value: string): string {
function unescapeICSValue (line 163) | function unescapeICSValue(value: string): string {
function foldLine (line 172) | function foldLine(line: string): string {
function formatProperty (line 185) | function formatProperty(
function generateVEvent (line 204) | function generateVEvent(event: Event): string[] {
function extractVEvents (line 246) | function extractVEvents(lines: string[]): string[][] {
function parseVEventLines (line 273) | function parseVEventLines(lines: string[]): ICSVEvent {
function convertToDayFlowEvent (line 330) | function convertToDayFlowEvent(
FILE: packages/core/src/utils/logger.ts
type LogLevel (line 6) | type LogLevel = 'log' | 'warn' | 'error' | 'debug';
class Logger (line 8) | class Logger {
method constructor (line 11) | constructor() {
method formatMessage (line 17) | private formatMessage(
method log (line 45) | log(message: string, ...args: unknown[]): void {
method warn (line 49) | warn(message: string, ...args: unknown[]): void {
method error (line 53) | error(message: string, ...args: unknown[]): void {
method debug (line 57) | debug(message: string, ...args: unknown[]): void {
FILE: packages/core/src/utils/styleUtils.ts
constant DEFAULT_WIDTH (line 7) | const DEFAULT_WIDTH = '240px';
function normalizeCssWidth (line 27) | function normalizeCssWidth(
function scrollbarTakesSpace (line 52) | function scrollbarTakesSpace(): boolean {
FILE: packages/core/src/utils/subscriptionUtils.ts
type SubscribeResult (line 6) | interface SubscribeResult {
function subscribeCalendar (line 15) | async function subscribeCalendar(url: string): Promise<SubscribeResult> {
FILE: packages/core/src/utils/temporal.ts
function isPlainDate (line 15) | function isPlainDate(date: unknown): date is Temporal.PlainDate {
function isZonedDateTime (line 45) | function isZonedDateTime(date: unknown): date is Temporal.ZonedDateTime {
function isDate (line 57) | function isDate(value: unknown): value is Date {
function dateToZonedDateTime (line 71) | function dateToZonedDateTime(
function dateToPlainDate (line 85) | function dateToPlainDate(date: Date): Temporal.PlainDate {
function zonedDateTimeToDate (line 98) | function zonedDateTimeToDate(zdt: Temporal.ZonedDateTime): Date {
function plainDateToDate (line 113) | function plainDateToDate(
function temporalToDate (line 138) | function temporalToDate(
function extractHourFromTemporal (line 204) | function extractHourFromTemporal(
function createTemporalWithHour (line 241) | function createTemporalWithHour(
function isSamePlainDate (line 286) | function isSamePlainDate(
function isMultiDayTemporalEvent (line 324) | function isMultiDayTemporalEvent(
function getStartOfTemporal (line 342) | function getStartOfTemporal(
function getEndOfTemporal (line 379) | function getEndOfTemporal(
function daysBetween (line 426) | function daysBetween(
function daysDifference (line 449) | function daysDifference(date1: Date, date2: Date): number {
function addDays (line 467) | function addDays(date: Date, days: number): Date {
function now (line 476) | function now(
function today (line 485) | function today(
FILE: packages/core/src/utils/temporalTypeGuards.ts
function isPlainDate (line 21) | function isPlainDate(temporal: unknown): temporal is Temporal.PlainDate {
function isPlainDateTime (line 36) | function isPlainDateTime(
function isZonedDateTime (line 53) | function isZonedDateTime(
function temporalToDate (line 73) | function temporalToDate(
function temporalToVisualDate (line 150) | function temporalToVisualDate(
function temporalToVisualTemporal (line 223) | function temporalToVisualTemporal(
function dateToPlainDate (line 269) | function dateToPlainDate(date: Date): Temporal.PlainDate {
function dateToPlainDateTime (line 280) | function dateToPlainDateTime(date: Date): Temporal.PlainDateTime {
function dateToZonedDateTime (line 295) | function dateToZonedDateTime(
function plainDateTimeToDate (line 314) | function plainDateTimeToDate(pdt: Temporal.PlainDateTime): Date {
function plainDateToDate (line 329) | function plainDateToDate(pd: Temporal.PlainDate): Date {
function extractHourFromTemporal (line 341) | function extractHourFromTemporal(
function setHourInTemporal (line 366) | function setHourInTemporal(
function getPlainDate (line 398) | function getPlainDate(
function isSameTemporal (line 422) | function isSameTemporal(
FILE: packages/core/src/utils/testDataUtils.ts
function getTestEvents (line 22) | function getTestEvents(): Event[] {
FILE: packages/core/src/utils/throttle.ts
function throttle (line 9) | function throttle<T extends (...args: unknown[]) => unknown>(
FILE: packages/core/src/utils/timeUtils.ts
type TemporalZoneShape (line 13) | interface TemporalZoneShape {
constant TIME_STEP (line 48) | const TIME_STEP = 0.25;
FILE: packages/core/src/utils/timeZoneUtils.ts
function canonicalizeTimeZoneCandidate (line 5) | function canonicalizeTimeZoneCandidate(timeZone: string): string | undef...
function normalizeTimeZoneValue (line 15) | function normalizeTimeZoneValue(
FILE: packages/core/src/utils/utilityFunctions.ts
function generateUniKey (line 16) | function generateUniKey() {
FILE: packages/core/src/views/AgendaView.tsx
type AgendaEntry (line 29) | type AgendaEntry = {
type AgendaDayGroup (line 43) | type AgendaDayGroup = {
constant DAY_MS (line 49) | const DAY_MS = 24 * 60 * 60 * 1000;
FILE: packages/core/src/views/MonthView.tsx
constant STATIC_TRANSITION_DURATION (line 121) | const STATIC_TRANSITION_DURATION = 300;
constant EMPTY_WEEK_EVENTS (line 122) | const EMPTY_WEEK_EVENTS: Event[] = [];
FILE: packages/core/src/views/utils/dragCreate.ts
type CreateStartFn (line 10) | type CreateStartFn = (
constant DRAG_CREATE_THRESHOLD (line 16) | const DRAG_CREATE_THRESHOLD = 5;
function startPendingCreate (line 33) | function startPendingCreate(
function finalizeCreateOnDblClick (line 93) | function finalizeCreateOnDblClick(): void {
FILE: packages/core/src/views/utils/weekView.ts
type WeekDateDisplay (line 3) | interface WeekDateDisplay {
type FullWeekDateDisplay (line 10) | interface FullWeekDateDisplay extends WeekDateDisplay {
type BuildWeekDayLabelsParams (line 15) | interface BuildWeekDayLabelsParams {
FILE: packages/create-dayflow/src/index.ts
constant FRAMEWORKS (line 14) | const FRAMEWORKS = [
type Framework (line 21) | type Framework = (typeof FRAMEWORKS)[number]['value'];
constant ADAPTER_PACKAGE (line 23) | const ADAPTER_PACKAGE: Record<Framework, string> = {
constant PLUGINS (line 30) | const PLUGINS = [
type Plugin (line 53) | type Plugin = (typeof PLUGINS)[number]['value'];
constant PLUGIN_PACKAGE (line 55) | const PLUGIN_PACKAGE: Record<Plugin, string> = {
constant PACKAGE_MANAGERS (line 62) | const PACKAGE_MANAGERS = [
type PackageManager (line 69) | type PackageManager = (typeof PACKAGE_MANAGERS)[number]['value'];
function detectPackageManager (line 71) | function detectPackageManager(): PackageManager {
function getInstallCommand (line 83) | function getInstallCommand(pm: PackageManager, packages: string[]): stri...
function getPluginImportName (line 99) | function getPluginImportName(plugin: Plugin): string {
function buildNextSteps (line 114) | function buildNextSteps(
function findCssFile (line 157) | function findCssFile(dir: string): string | null {
function main (line 202) | async function main() {
FILE: packages/plugins/drag/src/components/DragIndicatorComponent.tsx
type DragIndicatorComponentProps (line 9) | interface DragIndicatorComponentProps extends DragIndicatorProps {
FILE: packages/plugins/drag/src/components/MonthDragIndicator.tsx
type MonthDragIndicatorProps (line 23) | interface MonthDragIndicatorProps {
FILE: packages/plugins/drag/src/hooks/useDragHandlers.ts
type InternalDragRef (line 70) | type InternalDragRef = {
type DateCellRect (line 139) | type DateCellRect = {
FILE: packages/plugins/drag/src/hooks/useDragState.ts
type InternalDragRef (line 14) | type InternalDragRef = UnifiedDragRef & { pendingMove?: boolean };
FILE: packages/plugins/drag/src/hooks/utils/dateGridDrag.ts
type DateGridDragLike (line 9) | type DateGridDragLike = {
type DateGridPreviewRangeUpdate (line 28) | type DateGridPreviewRangeUpdate = {
type DateGridPreviewTargetUpdate (line 35) | type DateGridPreviewTargetUpdate = {
type DateGridPreviewUpdate (line 40) | type DateGridPreviewUpdate =
type BuildDateGridPreviewUpdateParams (line 45) | type BuildDateGridPreviewUpdateParams = {
type BuildDateGridCreateEventParams (line 52) | type BuildDateGridCreateEventParams = {
type DateGridMoveStartDragUpdates (line 59) | type DateGridMoveStartDragUpdates = {
type BuildDateGridMoveStartDataParams (line 79) | type BuildDateGridMoveStartDataParams = {
type DateGridDropResultBase (line 288) | type DateGridDropResultBase = {
type DateGridDropResult (line 292) | type DateGridDropResult =
type BuildDateGridDropResultParams (line 311) | type BuildDateGridDropResultParams = {
FILE: packages/plugins/drag/src/hooks/utils/eventEditing.ts
constant DAY_IN_MS (line 12) | const DAY_IN_MS = 24 * 60 * 60 * 1000;
type TimedEventHoursForEditing (line 14) | interface TimedEventHoursForEditing {
FILE: packages/plugins/drag/src/hooks/utils/weekDay/completion.ts
type WeekDayFinalizeDragLike (line 9) | type WeekDayFinalizeDragLike = {
type WeekDayCreateDragLike (line 19) | type WeekDayCreateDragLike = {
type WeekDayDropDragLike (line 24) | type WeekDayDropDragLike = {
FILE: packages/plugins/drag/src/hooks/utils/weekDay/crossRegion.ts
type CrossRegionMoveDragLike (line 13) | type CrossRegionMoveDragLike = {
type BuildCrossRegionAllDayPreviewParams (line 27) | type BuildCrossRegionAllDayPreviewParams = {
type BuildCrossRegionTimedPreviewParams (line 33) | type BuildCrossRegionTimedPreviewParams = {
type UniversalMoveDropDragLike (line 44) | type UniversalMoveDropDragLike = {
type BuildUniversalMoveDropResultParams (line 56) | type BuildUniversalMoveDropResultParams = {
FILE: packages/plugins/drag/src/hooks/utils/weekDay/drag.ts
constant DAY_IN_MS (line 8) | const DAY_IN_MS = 24 * 60 * 60 * 1000;
type EditingHours (line 10) | type EditingHours = {
type SegmentInfo (line 17) | type SegmentInfo = {
type MoveStartDragUpdates (line 23) | type MoveStartDragUpdates = {
type ResizeStartDragUpdates (line 51) | type ResizeStartDragUpdates = {
type WeekDayMoveStartParams (line 73) | type WeekDayMoveStartParams = {
type WeekDayResizeStartParams (line 84) | type WeekDayResizeStartParams = {
type WeekDayCreateStartDragUpdates (line 93) | type WeekDayCreateStartDragUpdates = {
type WeekDayCreateStartParams (line 109) | type WeekDayCreateStartParams = {
type CreateAllDayPreviewDragLike (line 121) | type CreateAllDayPreviewDragLike = {
type ResizeAllDayPreviewDragLike (line 127) | type ResizeAllDayPreviewDragLike = {
type TimedResizePreviewDragLike (line 133) | type TimedResizePreviewDragLike = {
type TimedMovePreviewDragLike (line 144) | type TimedMovePreviewDragLike = {
FILE: packages/plugins/drag/src/hooks/utils/weekDay/preview.ts
type SingleDayTimedResizeEventParams (line 8) | type SingleDayTimedResizeEventParams = {
type TimedCreatePreviewDragLike (line 19) | type TimedCreatePreviewDragLike = {
FILE: packages/plugins/drag/src/plugin.ts
function createDragPlugin (line 15) | function createDragPlugin(
function isDragService (line 122) | function isDragService(obj: unknown): obj is DragService {
function createDragConfig (line 132) | function createDragConfig(
FILE: packages/plugins/drag/src/utils/throttle.ts
function throttle (line 5) | function throttle<T extends (...args: unknown[]) => unknown>(
FILE: packages/plugins/keyboard-shortcuts/src/plugin.ts
type KeyboardShortcutsConfig (line 15) | interface KeyboardShortcutsConfig {
function handleTabNavigation (line 47) | function handleTabNavigation(app: ICalendarApp, reverse: boolean) {
function handlePaste (line 174) | async function handlePaste(app: ICalendarApp) {
type KeyboardShortcutsService (line 256) | interface KeyboardShortcutsService {
function createKeyboardShortcutsPlugin (line 265) | function createKeyboardShortcutsPlugin(
FILE: packages/plugins/localization/src/locales/index.ts
constant LOCALES (line 11) | const LOCALES = {
FILE: packages/plugins/localization/src/locales/types.ts
type LocaleMessages (line 1) | type LocaleMessages = Record<string, string>;
type LocaleNamespace (line 2) | type LocaleNamespace = 'core' | 'scheduler' | string;
type DayflowLocale (line 4) | interface DayflowLocale {
FILE: packages/plugins/localization/src/plugin.ts
type LocalizationHost (line 10) | interface LocalizationHost {
type LocalizationPluginCleanup (line 15) | type LocalizationPluginCleanup = () => void;
type LocalizationPlugin (line 17) | interface LocalizationPlugin {
type LocalizationConfig (line 22) | interface LocalizationConfig {
constant CORE_NAMESPACE (line 34) | const CORE_NAMESPACE = 'core';
constant DEFAULT_APP_REGISTRY_NAMESPACE (line 35) | const DEFAULT_APP_REGISTRY_NAMESPACE = 'scheduler';
function hasAppLocaleRegistry (line 37) | function hasAppLocaleRegistry(
function getLocaleMessages (line 45) | function getLocaleMessages(
function createLocaleForNamespace (line 59) | function createLocaleForNamespace(
function createLocalizationPlugin (line 79) | function createLocalizationPlugin(
FILE: packages/plugins/sidebar/scripts/build-css.mjs
function buildCss (line 13) | async function buildCss(inputFile, outputFile) {
FILE: packages/plugins/sidebar/src/components/CalendarChip.tsx
type CalendarChipProps (line 1) | interface CalendarChipProps {
FILE: packages/plugins/sidebar/src/components/CalendarList.tsx
type CalendarListProps (line 10) | interface CalendarListProps {
type CalendarItemProps (line 31) | interface CalendarItemProps {
FILE: packages/plugins/sidebar/src/components/DeleteCalendarDialog.tsx
constant CAL_SENTINEL (line 11) | const CAL_SENTINEL = '\u0001C\u0001';
function renderWithChip (line 13) | function renderWithChip(template: string, name: string, color: string) {
type DeleteCalendarDialogProps (line 23) | interface DeleteCalendarDialogProps {
FILE: packages/plugins/sidebar/src/components/ImportCalendarDialog.tsx
type ImportCalendarDialogProps (line 11) | interface ImportCalendarDialogProps {
constant NEW_CALENDAR_ID (line 18) | const NEW_CALENDAR_ID = 'new-calendar';
FILE: packages/plugins/sidebar/src/components/MergeCalendarDialog.tsx
constant SOURCE_SENTINEL (line 6) | const SOURCE_SENTINEL = '\u0001S\u0001';
constant TARGET_SENTINEL (line 7) | const TARGET_SENTINEL = '\u0001T\u0001';
function renderLine (line 9) | function renderLine(
type MergeCalendarDialogProps (line 25) | interface MergeCalendarDialogProps {
FILE: packages/plugins/sidebar/src/components/MergeMenuItem.tsx
type MergeMenuItemProps (line 9) | interface MergeMenuItemProps {
FILE: packages/plugins/sidebar/src/components/SidebarHeader.tsx
type SidebarHeaderProps (line 3) | interface SidebarHeaderProps {
FILE: packages/plugins/sidebar/src/components/SubscribeCalendarDialog.tsx
type SubscribeCalendarDialogProps (line 4) | interface SubscribeCalendarDialogProps {
FILE: packages/plugins/sidebar/src/plugin.ts
constant DEFAULT_SIDEBAR_WIDTH (line 23) | const DEFAULT_SIDEBAR_WIDTH = '240px';
constant COLORS (line 25) | const COLORS = [
type CalendarSidebarRenderProps (line 37) | interface CalendarSidebarRenderProps {
type SidebarPluginConfig (line 63) | interface SidebarPluginConfig {
type SidebarControlRef (line 86) | interface SidebarControlRef {
type SidebarService (line 98) | interface SidebarService {
function createSidebarPlugin (line 109) | function createSidebarPlugin(
FILE: packages/react/src/DayFlowCalendar.tsx
type DayFlowCalendarProps (line 28) | interface DayFlowCalendarProps {
function computeActiveOverrides (line 75) | function computeActiveOverrides(
function overridesChanged (line 108) | function overridesChanged(prev: string[], next: string[]): boolean {
FILE: packages/react/src/hooks/useCalendarApp.ts
function useCalendarApp (line 10) | function useCalendarApp(
FILE: packages/svelte/index.d.ts
class DayFlowCalendar (line 26) | class DayFlowCalendar extends SvelteComponent<
FILE: packages/svelte/rollup.config.js
method onwarn (line 41) | onwarn(warning, warn) {
FILE: packages/svelte/src/useCalendarApp.ts
function useCalendarApp (line 9) | function useCalendarApp(
FILE: packages/ui/context-menu/scripts/build-css.mjs
function buildCss (line 13) | async function buildCss(inputFile, outputFile) {
FILE: packages/ui/context-menu/src/ContextMenu.tsx
type IconProps (line 6) | interface IconProps {
type ContextMenuProps (line 30) | interface ContextMenuProps {
constant COLORS (line 264) | const COLORS = [
FILE: packages/ui/range-picker/scripts/build-css.mjs
function buildCss (line 13) | async function buildCss(inputFile, outputFile) {
FILE: packages/ui/range-picker/src/components/CalendarGrid.tsx
type CalendarGridProps (line 3) | interface CalendarGridProps {
FILE: packages/ui/range-picker/src/components/CalendarHeader.tsx
type CalendarHeaderProps (line 9) | interface CalendarHeaderProps {
FILE: packages/ui/range-picker/src/components/RangePickerPanel.tsx
type RangePickerPanelProps (line 9) | interface RangePickerPanelProps {
FILE: packages/ui/range-picker/src/components/TimeSelector.tsx
type TimeSelectorProps (line 8) | interface TimeSelectorProps {
FILE: packages/ui/range-picker/src/constants.ts
constant DEFAULT_FORMAT (line 1) | const DEFAULT_FORMAT = 'YYYY-MM-DD';
constant DEFAULT_TIME_FORMAT (line 2) | const DEFAULT_TIME_FORMAT = 'HH:mm';
constant HOURS (line 3) | const HOURS = Array.from({ length: 24 }, (_, index) => index);
constant MINUTES (line 4) | const MINUTES = Array.from({ length: 60 }, (_, index) => index);
FILE: packages/ui/range-picker/src/icons.tsx
type IconProps (line 1) | interface IconProps {
FILE: packages/ui/range-picker/src/types.ts
type ZonedRange (line 3) | type ZonedRange = [Temporal.ZonedDateTime, Temporal.ZonedDateTime];
type Locale (line 5) | interface Locale {
type RangePickerProps (line 10) | interface RangePickerProps {
FILE: packages/ui/range-picker/src/utils/rangePicker.ts
type TemporalZoneShape (line 7) | interface TemporalZoneShape {
type TemporalLike (line 12) | interface TemporalLike extends TemporalZoneShape {
constant TOKEN_REGEX (line 25) | const TOKEN_REGEX = /(YYYY|YY|MM|DD|HH|mm)/g;
FILE: packages/ui/range-picker/src/utils/temporal.ts
function isPlainDate (line 3) | function isPlainDate(temporal: unknown): temporal is Temporal.PlainDate {
FILE: packages/vue/src/DayFlowCalendar.ts
method setup (line 37) | setup(props, { slots }) {
FILE: packages/vue/src/composables/useCalendarApp.ts
function useCalendarApp (line 10) | function useCalendarApp(
FILE: website/app/(home)/layout.tsx
function Layout (line 5) | function Layout({ children }: LayoutProps<'/'>) {
FILE: website/app/(home)/page.tsx
function HomePage (line 16) | function HomePage() {
FILE: website/app/api/search/route.ts
type SearchSource (line 19) | type SearchSource = (typeof sourcesByLocale)[keyof typeof sourcesByLocale];
type SearchPage (line 20) | type SearchPage = ReturnType<SearchSource['getPages']>[number];
type TreeNode (line 22) | type TreeNode = {
function findPagePath (line 29) | function findPagePath(
function buildBreadcrumbs (line 48) | function buildBreadcrumbs(docSource: SearchSource, page: SearchPage) {
function getStructuredData (line 69) | async function getStructuredData(page: SearchPage) {
function buildSearchIndex (line 88) | async function buildSearchIndex(docSource: SearchSource, page: SearchPag...
method indexes (line 111) | indexes() {
constant GET (line 124) | const GET = search.staticGET;
FILE: website/app/blog/[...slug]/page.tsx
function findPost (line 7) | function findPost(slug: string[]) {
function BlogPost (line 12) | async function BlogPost(props: {
function generateStaticParams (line 50) | function generateStaticParams() {
function generateMetadata (line 56) | async function generateMetadata(props: {
FILE: website/app/blog/layout.tsx
function Layout (line 5) | function Layout({ children }: { children: React.ReactNode }) {
FILE: website/app/blog/page.tsx
function BlogPage (line 10) | function BlogPage() {
FILE: website/app/docs-ja/[[...slug]]/page.tsx
function Page (line 9) | async function Page(props: PageProps<'/docs-ja/[[...slug]]'>) {
function generateStaticParams (line 36) | function generateStaticParams() {
function generateMetadata (line 40) | async function generateMetadata(
FILE: website/app/docs-ja/layout.tsx
function Layout (line 8) | function Layout({ children }: LayoutProps<'/docs-ja'>) {
FILE: website/app/docs-zh/[[...slug]]/page.tsx
function Page (line 9) | async function Page(props: PageProps<'/docs-zh/[[...slug]]'>) {
function generateStaticParams (line 36) | function generateStaticParams() {
function generateMetadata (line 40) | async function generateMetadata(
FILE: website/app/docs-zh/layout.tsx
function Layout (line 8) | function Layout({ children }: LayoutProps<'/docs-zh'>) {
FILE: website/app/docs/[[...slug]]/page.tsx
function Page (line 9) | async function Page(props: PageProps<'/docs/[[...slug]]'>) {
function generateStaticParams (line 37) | function generateStaticParams() {
function generateMetadata (line 41) | async function generateMetadata(
FILE: website/app/docs/layout.tsx
function Layout (line 8) | function Layout({ children }: LayoutProps<'/docs'>) {
FILE: website/app/layout.tsx
function Layout (line 51) | function Layout({ children }: LayoutProps<'/'>) {
FILE: website/app/llms-full.txt/route.ts
function GET (line 5) | async function GET() {
FILE: website/app/llms.txt/route.ts
function GET (line 5) | function GET() {
FILE: website/app/og/docs/[...slug]/route.tsx
function GET (line 10) | async function GET(
function generateStaticParams (line 31) | function generateStaticParams() {
FILE: website/app/robots.ts
function robots (line 7) | function robots(): MetadataRoute.Robots {
FILE: website/app/showcase/mobile-event-detail/page.tsx
function MobileEventDetailSimulatorPage (line 13) | function MobileEventDetailSimulatorPage() {
FILE: website/app/sitemap.ts
function sitemap (line 10) | function sitemap(): MetadataRoute.Sitemap {
FILE: website/components/AppProvider.tsx
function AppProvider (line 11) | function AppProvider({ children }: { children: ReactNode }) {
FILE: website/components/CliPreview.tsx
function CliPreview (line 14) | function CliPreview() {
FILE: website/components/ColorPalette.tsx
type ColorSwatchProps (line 6) | interface ColorSwatchProps {
FILE: website/components/DocsHeader.tsx
constant BASE (line 14) | const BASE = process.env.NEXT_PUBLIC_BASE_PATH || '';
constant PRO_URL (line 15) | const PRO_URL = 'https://pro.dayflow.studio';
function DiscordIcon (line 17) | function DiscordIcon({ className }: { className?: string }) {
function GithubIcon (line 31) | function GithubIcon({ className }: { className?: string }) {
constant DISCORD_URL (line 45) | const DISCORD_URL = 'https://discord.gg/9vdFZKJqBb';
type DocsHeaderProps (line 47) | interface DocsHeaderProps {
function DocsHeader (line 57) | function DocsHeader({ githubUrl }: DocsHeaderProps) {
FILE: website/components/DocsSearchDialog.tsx
type SearchLink (line 22) | type SearchLink = [name: string, href: string];
type TagItem (line 24) | type TagItem = {
type SearchResultItem (line 29) | type SearchResultItem = {
type SearchDocument (line 37) | type SearchDocument = SearchResultItem & {
type DocsSearchDialogProps (line 42) | interface DocsSearchDialogProps {
function isCjkLocale (line 54) | function isCjkLocale(locale: string) {
function createSearchDocument (line 58) | function createSearchDocument(locale: string) {
type SearchIndexDocument (line 71) | type SearchIndexDocument = ReturnType<typeof createSearchDocument>;
function loadSearchDatabases (line 78) | function loadSearchDatabases(from = '/api/search') {
function searchStaticDocs (line 124) | async function searchStaticDocs({
function DocsSearchDialog (line 191) | function DocsSearchDialog({
FILE: website/components/FrameworkInstall.tsx
constant CREATE_COMMANDS (line 180) | const CREATE_COMMANDS: Record<string, string> = {
function CreateDayflowTabs (line 234) | function CreateDayflowTabs() {
function PackageTabs (line 248) | function PackageTabs({ pkg }: { pkg: string }) {
function FrameworkInstall (line 269) | function FrameworkInstall() {
FILE: website/components/FrameworkTabs.tsx
function FrameworkTabs (line 81) | function FrameworkTabs({ children }: { children: React.ReactNode }) {
function Tab (line 108) | function Tab({
FILE: website/components/LanguageSwitcher.tsx
function switchTo (line 12) | function switchTo(newLocale: LanguageCode, currentPath: string) {
function LanguageSwitcher (line 46) | function LanguageSwitcher() {
FILE: website/components/ai/page-actions.tsx
function LLMCopyButton (line 16) | function LLMCopyButton({
function ViewOptions (line 66) | function ViewOptions({
FILE: website/components/showcase/ColorPickerShowcase.tsx
function ColorPickerShowcase (line 21) | function ColorPickerShowcase() {
FILE: website/components/showcase/CustomDetailDialogShowcase.tsx
constant COLOR_PRESETS (line 38) | const COLOR_PRESETS = CALENDAR_SIDE_PANEL.map(item => ({
constant META_PRESETS (line 44) | const META_PRESETS = [
FILE: website/components/showcase/CustomDetailPanelShowcase.tsx
type SwitcherMode (line 28) | type SwitcherMode = 'buttons' | 'select';
type DemoCalendarProps (line 30) | interface DemoCalendarProps {
constant META_PRESETS (line 40) | const META_PRESETS = [
FILE: website/components/showcase/EventContentShowcase.tsx
constant BASE (line 22) | const BASE = process.env.NEXT_PUBLIC_BASE_PATH || '';
FILE: website/components/showcase/FeatureShowcase.tsx
type SwitcherMode (line 32) | type SwitcherMode = 'buttons' | 'select';
type DemoCalendarProps (line 34) | interface DemoCalendarProps {
type FeatureCardProps (line 40) | interface FeatureCardProps {
FILE: website/components/showcase/InteractiveCalendar.tsx
constant LOCALES_OPTIONS (line 50) | const LOCALES_OPTIONS = [
function InteractiveCalendar (line 70) | function InteractiveCalendar() {
FILE: website/components/showcase/LiveDemo.tsx
function LiveDemo (line 7) | function LiveDemo() {
FILE: website/components/showcase/SidebarShowcases.tsx
constant SIDEBAR_CALENDAR_IDS (line 22) | const SIDEBAR_CALENDAR_IDS = new Set([
constant BASE_CALENDARS (line 30) | const BASE_CALENDARS: CalendarType[] = getWebsiteCalendars().filter(cale...
FILE: website/components/showcase/livedemo/CalendarViewer.tsx
type CalendarViewerProps (line 13) | interface CalendarViewerProps {
function CalendarViewer (line 22) | function CalendarViewer({
FILE: website/components/showcase/livedemo/ControlPanel.tsx
type ControlPanelProps (line 37) | interface ControlPanelProps {
constant VIEW_OPTIONS (line 47) | const VIEW_OPTIONS = [
constant TIME_ZONE_OPTIONS (line 55) | const TIME_ZONE_OPTIONS = Object.entries(TimeZone).toSorted((a, b) =>
function FeatureCheckbox (line 65) | function FeatureCheckbox({
function ControlPanel (line 94) | function ControlPanel({
FILE: website/components/showcase/livedemo/MiniDotsFeature.tsx
type MiniDotsFeatureProps (line 15) | interface MiniDotsFeatureProps {
function MiniDotsFeature (line 20) | function MiniDotsFeature({
FILE: website/components/showcase/livedemo/MultiCalFeature.tsx
type MultiCalFeatureProps (line 15) | interface MultiCalFeatureProps {
function MultiCalFeature (line 20) | function MultiCalFeature({
FILE: website/components/showcase/livedemo/ThemeColorColumn.tsx
type ThemeColorColumnProps (line 23) | interface ThemeColorColumnProps {
function ThemeColorColumn (line 42) | function ThemeColorColumn({
FILE: website/components/showcase/livedemo/types.ts
constant DEFAULT_THEME_COLOR (line 3) | const DEFAULT_THEME_COLOR = '#6786e6';
type YearMode (line 5) | type YearMode = 'fixed-week' | 'canvas' | 'grid';
type SwitcherMode (line 6) | type SwitcherMode = 'buttons' | 'select';
type CalendarFeatures (line 8) | interface CalendarFeatures {
type CalendarSelections (line 21) | interface CalendarSelections {
FILE: website/components/showcase/mobile-event-detail/MobileEventDetailSimulator.tsx
type DraftEvent (line 22) | type DraftEvent = NonNullable<MobileEventProps['draftEvent']>;
FILE: website/components/ui/badge.tsx
type BadgeProps (line 27) | interface BadgeProps
function Badge (line 32) | function Badge({ className, variant, ...props }: BadgeProps) {
FILE: website/components/ui/button.tsx
type ButtonProps (line 37) | interface ButtonProps
FILE: website/lib/i18n.ts
type LanguageCode (line 7) | type LanguageCode = (typeof languages)[number]['code'];
function getLanguageFromPathname (line 16) | function getLanguageFromPathname(pathname: string) {
function getLanguageCodeFromPathname (line 28) | function getLanguageCodeFromPathname(pathname: string): LanguageCode {
FILE: website/lib/layout.shared.tsx
constant BASE (line 13) | const BASE = process.env.NEXT_PUBLIC_BASE_PATH || '';
constant PRO_URL (line 14) | const PRO_URL = 'https://pro.dayflow.studio';
function DiscordIcon (line 50) | function DiscordIcon() {
function GithubButton (line 64) | function GithubButton() {
function baseOptions (line 117) | function baseOptions(): BaseLayoutProps {
function homeOptions (line 152) | function homeOptions(): BaseLayoutProps {
FILE: website/lib/site.ts
constant BASE_PATH (line 3) | const BASE_PATH =
constant SITE_URL (line 14) | const SITE_URL = rawSiteUrl.endsWith('/')
constant SITE_METADATA_BASE (line 18) | const SITE_METADATA_BASE = new URL(SITE_URL);
FILE: website/lib/source.tsx
function getPageImage (line 57) | function getPageImage(page: InferPageType<typeof source>) {
function getLLMText (line 66) | async function getLLMText(page: InferPageType<typeof source>) {
FILE: website/lib/utils.ts
function cn (line 5) | function cn(...inputs: ClassValue[]) {
FILE: website/mdx-components.tsx
constant BASE (line 13) | const BASE = process.env.NEXT_PUBLIC_BASE_PATH || '';
function DocImg (line 15) | function DocImg({
function getMDXComponents (line 35) | function getMDXComponents(components?: MDXComponents): MDXComponents {
FILE: website/utils/palette.ts
type PaletteCalendar (line 3) | interface PaletteCalendar extends Pick<CalendarType, 'id' | 'name' | 'ic...
constant CALENDAR_SIDE_PANEL (line 9) | const CALENDAR_SIDE_PANEL: PaletteCalendar[] = [
FILE: website/utils/sampleData.ts
constant DEFAULT_TIME_ZONE (line 121) | const DEFAULT_TIME_ZONE = Temporal.Now.timeZoneId();
Condensed preview — 615 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (3,380K chars).
[
{
"path": ".editorconfig",
"chars": 167,
"preview": "root = true\n\n[*]\nend_of_line = lf\ninsert_final_newline = true\nindent_style = space\nindent_size = 2\ncharset = utf-8\ntrim_"
},
{
"path": ".github/FUNDING.yml",
"chars": 855,
"preview": "# These are supported funding model platforms\n\ngithub: [JayceV552]\npatreon: # Replace with a single Patreon username\nope"
},
{
"path": ".github/ISSUE_TEMPLATE/bug_report.md",
"chars": 829,
"preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: ''\nassignees: ''\n---\n\n**Describe the bu"
},
{
"path": ".github/ISSUE_TEMPLATE/feature_request.md",
"chars": 594,
"preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: ''\nassignees: ''\n---\n\n**Is your feat"
},
{
"path": ".github/workflows/deploy.yml",
"chars": 1522,
"preview": "name: Deploy to GitHub Pages\n\non:\n push:\n branches:\n - main\n workflow_dispatch:\n\npermissions:\n contents: read"
},
{
"path": ".gitignore",
"chars": 436,
"preview": "# Dependencies\nnode_modules\n.pnp\n.pnp.js\n\n# Testing\ncoverage\n\n# Next.js\nbuild\ndist\nwebsite/.next\nwebsite/out\n\n# Producti"
},
{
"path": ".nojekyll",
"chars": 0,
"preview": ""
},
{
"path": ".npmignore",
"chars": 569,
"preview": "# Source files\nsrc/\nwebsite/\nexamples/\n\n# Development files\n.git/\n.gitignore\n.vscode/\n.idea/\n\n# Build artifacts\n.next/\nn"
},
{
"path": ".oxfmtrc.jsonc",
"chars": 934,
"preview": "// https://oxc.rs/docs/guide/usage/formatter/config-file-reference.html\n\n{\n \"$schema\": \"./node_modules/oxfmt/configurat"
},
{
"path": ".oxlintrc.json",
"chars": 4273,
"preview": "{\n \"$schema\": \"./node_modules/oxlint/configuration_schema.json\",\n \"ignorePatterns\": [\"**/*.mdx\"],\n \"plugins\": [\n \""
},
{
"path": ".vscode/extensions.json",
"chars": 186,
"preview": "{\n \"recommendations\": [\n \"oxc.oxc-vscode\",\n \"bradlc.vscode-tailwindcss\",\n \"fill-labs.dependi\",\n \"svelte.sve"
},
{
"path": ".vscode/settings.json",
"chars": 1762,
"preview": "{\n \"files.eol\": \"\\n\",\n\n // Suppress CSS language-server warnings for Tailwind-specific at-rules\n // (@apply, @variant"
},
{
"path": ".zed/settings.json",
"chars": 3023,
"preview": "{\n \"formatter\": \"language_server\",\n \"format_on_save\": \"on\",\n\n \"languages\": {\n \"JavaScript\": {\n \"formatter\": {"
},
{
"path": "CHANGELOG.md",
"chars": 12902,
"preview": "# Changelog\n\nAll notable changes to this project will be documented in this file.\n\n## [3.6.0] - 2026-05-03\n\n### New Feat"
},
{
"path": "CNAME",
"chars": 23,
"preview": "calendar.dayflow.studio"
},
{
"path": "CONTRIBUTING.md",
"chars": 2265,
"preview": "# Contribution Guide\n\nThank you for your interest in contributing to **DayFlow**! We welcome contributions from the comm"
},
{
"path": "LICENSE",
"chars": 1065,
"preview": "MIT License\n\nCopyright (c) 2025 Jayce Li\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\no"
},
{
"path": "README.ja.md",
"chars": 1766,
"preview": "# DayFlow\n\n[English](README.md) | [中文](README.zh.md) | **日本語** | [はじめに & コントリビューション](CONTRIBUTING.md)\n\nドラッグ&ドロップ、マルチビュー、"
},
{
"path": "README.md",
"chars": 2151,
"preview": "# DayFlow\n\n**English** | [中文](README.zh.md) | [日本語](README.ja.md) | [Getting Started & Contributing](CONTRIBUTING.md)\n\nA"
},
{
"path": "README.zh.md",
"chars": 1650,
"preview": "# DayFlow\n\n[English](README.md) | **中文** | [日本語](README.ja.md) | [快速开始 & 贡献](CONTRIBUTING.md)\n\n一个灵活且功能丰富的 React 日历组件库,支持"
},
{
"path": "examples/defaultCalendarExample/defaultCalendarExample.tsx",
"chars": 16105,
"preview": "import {\n Event,\n CalendarType,\n EventChange,\n ReadOnlyConfig,\n TimeZone,\n ViewType,\n} from '@dayflow/core';\nimpor"
},
{
"path": "examples/main.tsx",
"chars": 498,
"preview": "// import 'preact/debug';\nimport { createRoot } from 'react-dom/client';\n\n// Local example shell utilities live in examp"
},
{
"path": "examples/styles/tailwind.css",
"chars": 175,
"preview": "@import 'tailwindcss/preflight' layer(base);\n@import 'tailwindcss/theme' layer(theme);\n@import 'tailwindcss/utilities';\n"
},
{
"path": "examples/utils/palette.ts",
"chars": 3670,
"preview": "import { CalendarType, CalendarColors } from '@dayflow/core';\n\ninterface PaletteCalendar extends Pick<\n CalendarType,\n "
},
{
"path": "examples/utils/sampleData.ts",
"chars": 14816,
"preview": "import { Event } from '@dayflow/core';\nimport { Temporal } from 'temporal-polyfill';\n\nconst calendarIds = [\n 'team',\n "
},
{
"path": "index.html",
"chars": 308,
"preview": "<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-w"
},
{
"path": "lefthook.yml",
"chars": 395,
"preview": "pre-commit:\n jobs:\n - run: pnpm --filter @dayflow/core run check:css\n\n - run: pnpm format\n stage_fixed: true"
},
{
"path": "package.json",
"chars": 1684,
"preview": "{\n \"name\": \"dayflow-monorepo\",\n \"version\": \"3.1.2\",\n \"private\": true,\n \"description\": \"Multi-framework calendar comp"
},
{
"path": "packages/angular/LICENSE",
"chars": 1065,
"preview": "MIT License\n\nCopyright (c) 2025 Jayce Li\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\no"
},
{
"path": "packages/angular/README.md",
"chars": 2576,
"preview": "# DayFlow Angular\n\nA flexible and feature-rich Angular calendar component library with drag-and-drop support, multiple v"
},
{
"path": "packages/angular/ng-packagr.json",
"chars": 177,
"preview": "{\n \"$schema\": \"./node_modules/ng-packagr/ng-package.schema.json\",\n \"lib\": {\n \"entryFile\": \"src/public-api.ts\"\n },\n"
},
{
"path": "packages/angular/package.json",
"chars": 940,
"preview": "{\n \"name\": \"@dayflow/angular\",\n \"version\": \"3.6.2\",\n \"description\": \"Angular adapter for DayFlow calendar\",\n \"files\""
},
{
"path": "packages/angular/src/lib/day-flow-calendar.component.ts",
"chars": 11282,
"preview": "import {\n ElementRef,\n OnChanges,\n OnDestroy,\n AfterViewInit,\n SimpleChanges,\n TemplateRef,\n ChangeDetectorRef,\n "
},
{
"path": "packages/angular/src/lib/day-flow-calendar.module.ts",
"chars": 514,
"preview": "import { CommonModule } from '@angular/common';\nimport { NgModule } from '@angular/core';\n\nimport { DayFlowCalendarCompo"
},
{
"path": "packages/angular/src/lib/day-flow-portal.directive.ts",
"chars": 603,
"preview": "import {\n ElementRef,\n OnChanges,\n SimpleChanges,\n OnDestroy,\n Directive,\n Input,\n} from '@angular/core';\n\n@Direct"
},
{
"path": "packages/angular/src/public-api.ts",
"chars": 230,
"preview": "/*\n * Public API Surface of @dayflow/angular\n */\n\nexport * from './lib/day-flow-calendar.component';\nexport * from './li"
},
{
"path": "packages/angular/tsconfig.json",
"chars": 348,
"preview": "{\n \"extends\": \"../../tsconfig.json\",\n \"compilerOptions\": {\n \"outDir\": \"./dist/out-tsc\",\n \"types\": [],\n \"noUnu"
},
{
"path": "packages/core/LICENSE",
"chars": 1065,
"preview": "MIT License\n\nCopyright (c) 2025 Jayce Li\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\no"
},
{
"path": "packages/core/README.md",
"chars": 2577,
"preview": "# DayFlow Core\n\nThe core engine of DayFlow, a flexible and feature-rich calendar library with drag-and-drop support, mul"
},
{
"path": "packages/core/bundle-analysis.html",
"chars": 358018,
"preview": "<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-w"
},
{
"path": "packages/core/jest.config.mjs",
"chars": 1298,
"preview": "export default {\n preset: 'ts-jest',\n testEnvironment: 'jsdom',\n roots: ['<rootDir>/src'],\n testMatch: ['**/__tests_"
},
{
"path": "packages/core/package.json",
"chars": 3262,
"preview": "{\n \"name\": \"@dayflow/core\",\n \"version\": \"3.6.2\",\n \"description\": \"A flexible and feature-rich calendar engine powered"
},
{
"path": "packages/core/postcss.build.mjs",
"chars": 92,
"preview": "export default {\n plugins: {\n '@tailwindcss/postcss': {},\n autoprefixer: {},\n },\n};\n"
},
{
"path": "packages/core/rollup.config.js",
"chars": 1723,
"preview": "import path from 'node:path';\n\nimport resolve from '@rollup/plugin-node-resolve';\nimport terser from '@rollup/plugin-ter"
},
{
"path": "packages/core/scripts/atomic-css-baseline.json",
"chars": 35,
"preview": "{\n \"source\": {},\n \"distJs\": {}\n}\n"
},
{
"path": "packages/core/scripts/atomic-css-guard-utils.mjs",
"chars": 9678,
"preview": "import fs from 'node:fs';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst __dirname = pat"
},
{
"path": "packages/core/scripts/build-css.mjs",
"chars": 1505,
"preview": "import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport tailw"
},
{
"path": "packages/core/scripts/check-dist-styling.mjs",
"chars": 2896,
"preview": "import fs from 'node:fs';\nimport path from 'node:path';\n\nimport {\n FORBIDDEN_TOP_LEVEL_UTILITY_SELECTORS,\n diffAgainst"
},
{
"path": "packages/core/scripts/check-semantic-css.mjs",
"chars": 2018,
"preview": "import path from 'node:path';\n\nimport {\n diffAgainstBaseline,\n loadBaseline,\n parseArgs,\n scanSourceViolations,\n su"
},
{
"path": "packages/core/src/components/calendarEvent/CalendarEvent.tsx",
"chars": 18460,
"preview": "import { memo } from 'preact/compat';\nimport {\n useRef,\n useState,\n useEffect,\n useCallback,\n useMemo,\n useContext"
},
{
"path": "packages/core/src/components/calendarEvent/__tests__/CalendarEvent.contract.test.tsx",
"chars": 7128,
"preview": "import { render } from '@testing-library/preact';\nimport { Temporal } from 'temporal-polyfill';\n\nimport CalendarEvent fr"
},
{
"path": "packages/core/src/components/calendarEvent/__tests__/CalendarEvent.timezone.test.tsx",
"chars": 1822,
"preview": "import { render } from '@testing-library/preact';\nimport { Temporal } from 'temporal-polyfill';\n\nimport CalendarEvent fr"
},
{
"path": "packages/core/src/components/calendarEvent/components/AllDayContent.tsx",
"chars": 3443,
"preview": "import { ComponentChildren } from 'preact';\n\nimport { CalendarDays } from '@/components/common/Icons';\nimport { MultiDay"
},
{
"path": "packages/core/src/components/calendarEvent/components/EventContent.tsx",
"chars": 6946,
"preview": "import { ComponentChildren } from 'preact';\n\nimport MultiDayEvent from '@/components/monthView/MultiDayEvent';\nimport { "
},
{
"path": "packages/core/src/components/calendarEvent/components/EventDetailPanel.tsx",
"chars": 1971,
"preview": "import { RefObject } from 'preact';\n\nimport DefaultEventDetailPanel from '@/components/common/DefaultEventDetailPanel';\n"
},
{
"path": "packages/core/src/components/calendarEvent/components/MonthAllDayContent.tsx",
"chars": 1551,
"preview": "import { CalendarDays } from '@/components/common/Icons';\nimport { monthAllDayContent, eventIcon } from '@/styles/classN"
},
{
"path": "packages/core/src/components/calendarEvent/components/MonthRegularContent.tsx",
"chars": 2003,
"preview": "import { monthRegularContent, monthEventColorBar } from '@/styles/classNames';\nimport { Event, ICalendarApp } from '@/ty"
},
{
"path": "packages/core/src/components/calendarEvent/components/RegularEventContent.tsx",
"chars": 6970,
"preview": "import { ComponentChildren } from 'preact';\n\nimport {\n eventColorBar,\n eventTitleSmall,\n eventTime,\n resizeHandleLef"
},
{
"path": "packages/core/src/components/calendarEvent/components/YearEventContent.tsx",
"chars": 4724,
"preview": "import { ComponentChildren } from 'preact';\n\nimport { getEventIcon } from '@/components/monthView/util';\nimport { YearMu"
},
{
"path": "packages/core/src/components/calendarEvent/components/__tests__/EventContent.test.tsx",
"chars": 3528,
"preview": "import { render, screen } from '@testing-library/preact';\nimport { Temporal } from 'temporal-polyfill';\n\nimport { EventC"
},
{
"path": "packages/core/src/components/calendarEvent/components/__tests__/RegularEventContent.test.tsx",
"chars": 1195,
"preview": "import { render } from '@testing-library/preact';\nimport { Temporal } from 'temporal-polyfill';\n\nimport RegularEventCont"
},
{
"path": "packages/core/src/components/calendarEvent/hooks/__tests__/useEventActions.test.tsx",
"chars": 18484,
"preview": "import { render, fireEvent, act } from '@testing-library/preact';\nimport { useRef } from 'preact/hooks';\nimport { Tempor"
},
{
"path": "packages/core/src/components/calendarEvent/hooks/useClickOutside.ts",
"chars": 2525,
"preview": "import { RefObject } from 'preact';\nimport { useEffect } from 'preact/hooks';\n\ninterface UseClickOutsideProps {\n eventR"
},
{
"path": "packages/core/src/components/calendarEvent/hooks/useDetailPanelPosition.ts",
"chars": 6830,
"preview": "import { RefObject } from 'preact';\nimport { useState, useCallback, useEffect } from 'preact/hooks';\n\nimport { getTimeCo"
},
{
"path": "packages/core/src/components/calendarEvent/hooks/useEventActions.ts",
"chars": 13527,
"preview": "import { RefObject } from 'preact';\nimport { useCallback, useEffect, useRef, useState } from 'preact/hooks';\n\nimport { g"
},
{
"path": "packages/core/src/components/calendarEvent/hooks/useEventInteraction.ts",
"chars": 6278,
"preview": "import { useRef, useState } from 'preact/hooks';\n\nimport { MultiDayEventSegment } from '@/components/monthView/util';\nim"
},
{
"path": "packages/core/src/components/calendarEvent/hooks/useEventStyles.ts",
"chars": 13504,
"preview": "import { RefObject } from 'preact';\n\nimport type { EventVisibility } from '@/components/calendarEvent/hooks/useEventVisi"
},
{
"path": "packages/core/src/components/calendarEvent/hooks/useEventVisibility.ts",
"chars": 7213,
"preview": "import { RefObject } from 'preact';\nimport { useEffect, useCallback } from 'preact/hooks';\n\nimport {\n getCalendarConten"
},
{
"path": "packages/core/src/components/calendarEvent/index.tsx",
"chars": 102,
"preview": "import CalendarEvent from './CalendarEvent';\n\nexport { CalendarEvent };\nexport default CalendarEvent;\n"
},
{
"path": "packages/core/src/components/calendarEvent/types.ts",
"chars": 2941,
"preview": "import { ComponentChildren, RefObject } from 'preact';\n\nimport { MultiDayEventSegment } from '@/components/monthView/uti"
},
{
"path": "packages/core/src/components/calendarEvent/utils.ts",
"chars": 5835,
"preview": "import { RefObject } from 'preact';\n\nimport { Event, ViewType } from '@/types';\n\nexport type EventSegmentShape = 'full' "
},
{
"path": "packages/core/src/components/common/BlossomColorPicker.tsx",
"chars": 1165,
"preview": "import {\n BlossomColorPicker as VanillaBlossomColorPicker,\n BlossomColorPickerOptions,\n} from '@dayflow/blossom-color-"
},
{
"path": "packages/core/src/components/common/CalendarHeader.tsx",
"chars": 4093,
"preview": "import { JSX } from 'preact';\nimport { useCallback } from 'preact/hooks';\n\nimport { useResponsiveMonthConfig } from '@/h"
},
{
"path": "packages/core/src/components/common/CalendarPicker.tsx",
"chars": 6475,
"preview": "import { JSX } from 'preact';\nimport { createPortal } from 'preact/compat';\nimport { useState, useRef, useEffect } from "
},
{
"path": "packages/core/src/components/common/CreateCalendarDialog.tsx",
"chars": 10946,
"preview": "import {\n DEFAULT_COLORS,\n hslToHex,\n lightnessToSliderValue,\n} from '@dayflow/blossom-color-picker';\nimport { create"
},
{
"path": "packages/core/src/components/common/DefaultColorPicker.tsx",
"chars": 1077,
"preview": "import {\n hexToHsl,\n lightnessToSliderValue,\n} from '@dayflow/blossom-color-picker';\nimport { useMemo } from 'preact/h"
},
{
"path": "packages/core/src/components/common/DefaultEventDetailDialog.tsx",
"chars": 11124,
"preview": "import { RangePicker } from '@dayflow/ui-range-picker';\nimport { createPortal } from 'preact/compat';\nimport { useMemo, "
},
{
"path": "packages/core/src/components/common/DefaultEventDetailPanel.tsx",
"chars": 17593,
"preview": "import { RangePicker } from '@dayflow/ui-range-picker';\nimport { JSX } from 'preact';\nimport { createPortal } from 'prea"
},
{
"path": "packages/core/src/components/common/EventDetailPanelWithContent.tsx",
"chars": 6966,
"preview": "import { JSX } from 'preact';\nimport { createPortal } from 'preact/compat';\n\nimport { getCalendarContentElement } from '"
},
{
"path": "packages/core/src/components/common/Icons.tsx",
"chars": 10365,
"preview": "interface IconProps {\n className?: string;\n width?: number;\n height?: number;\n title?: string;\n}\n\nexport const Chevr"
},
{
"path": "packages/core/src/components/common/LoadingButton.tsx",
"chars": 2603,
"preview": "import { JSX, ComponentChildren } from 'preact';\nimport { useState } from 'preact/hooks';\n\ninterface ButtonProps extends"
},
{
"path": "packages/core/src/components/common/MiniCalendar.tsx",
"chars": 6383,
"preview": "import { useMemo } from 'preact/hooks';\nimport { Temporal } from 'temporal-polyfill';\n\nimport { CalendarRegistry } from "
},
{
"path": "packages/core/src/components/common/QuickCreateEventPopup.tsx",
"chars": 9320,
"preview": "import { RefObject } from 'preact';\nimport { createPortal } from 'preact/compat';\nimport {\n useState,\n useEffect,\n us"
},
{
"path": "packages/core/src/components/common/TodayBox.tsx",
"chars": 1034,
"preview": "import { useLocale } from '@/locale';\nimport { calendarNavButton, calendarTodayButton } from '@/styles/classNames';\n\nimp"
},
{
"path": "packages/core/src/components/common/ViewHeader.tsx",
"chars": 4281,
"preview": "import type { ComponentChild } from 'preact';\n\nimport { useLocale } from '@/locale';\nimport { headerTitle, headerSubtitl"
},
{
"path": "packages/core/src/components/common/ViewSwitcher.tsx",
"chars": 3723,
"preview": "import { useState, useRef, useEffect } from 'preact/hooks';\n\nimport { useLocale } from '@/locale';\nimport { TranslationK"
},
{
"path": "packages/core/src/components/common/__tests__/MiniCalendar.test.tsx",
"chars": 1911,
"preview": "import { render } from '@testing-library/preact';\nimport { Temporal } from 'temporal-polyfill';\n\nimport { MiniCalendar }"
},
{
"path": "packages/core/src/components/common/__tests__/QuickCreateEventPopup.test.tsx",
"chars": 1788,
"preview": "import { fireEvent, render, screen } from '@testing-library/preact';\n\nimport { QuickCreateEventPopup } from '@/component"
},
{
"path": "packages/core/src/components/contextMenu/__tests__/utils.test.ts",
"chars": 1757,
"preview": "import { Temporal } from 'temporal-polyfill';\n\nimport { handlePasteEvent } from '@/components/contextMenu/utils';\nimport"
},
{
"path": "packages/core/src/components/contextMenu/components/EventContextMenu.tsx",
"chars": 3755,
"preview": "import {\n ContextMenu,\n ContextMenuItem,\n ContextMenuSeparator,\n ContextMenuSub,\n ContextMenuSubTrigger,\n ContextM"
},
{
"path": "packages/core/src/components/contextMenu/components/GridContextMenu.tsx",
"chars": 1540,
"preview": "import { ContextMenu, ContextMenuItem } from '@dayflow/ui-context-menu';\n\nimport { handlePasteEvent } from '@/components"
},
{
"path": "packages/core/src/components/contextMenu/components/__tests__/readOnlyContextMenus.test.tsx",
"chars": 2134,
"preview": "import { render, screen } from '@testing-library/preact';\nimport { Temporal } from 'temporal-polyfill';\n\nimport EventCon"
},
{
"path": "packages/core/src/components/contextMenu/index.tsx",
"chars": 393,
"preview": "export {\n ContextMenu,\n ContextMenuItem,\n ContextMenuSeparator,\n ContextMenuLabel,\n ContextMenuSub,\n ContextMenuSu"
},
{
"path": "packages/core/src/components/contextMenu/utils.ts",
"chars": 3242,
"preview": "import { Event, ViewType, ICalendarApp } from '@/types';\nimport {\n generateUniKey,\n temporalToDate,\n dateToZonedDateT"
},
{
"path": "packages/core/src/components/dayView/DayContent.tsx",
"chars": 25095,
"preview": "import { RefObject } from 'preact';\nimport { useEffect, useRef, useState, useMemo } from 'preact/hooks';\n\nimport Calenda"
},
{
"path": "packages/core/src/components/dayView/RightPanel.tsx",
"chars": 4782,
"preview": "import { RefObject } from 'preact';\n\nimport { CalendarEvent } from '@/components/calendarEvent';\nimport { MiniCalendar }"
},
{
"path": "packages/core/src/components/dayView/__tests__/util.timezone.test.ts",
"chars": 1788,
"preview": "import { Temporal } from 'temporal-polyfill';\n\nimport {\n filterDayEvents,\n normalizeLayoutEvents,\n} from '@/components"
},
{
"path": "packages/core/src/components/dayView/util.ts",
"chars": 6588,
"preview": "import { EventLayoutCalculator } from '@/components/eventLayout';\nimport { Event, EventLayout } from '@/types';\nimport {"
},
{
"path": "packages/core/src/components/eventLayout/calculate/grouping.ts",
"chars": 2617,
"preview": "import { LAYOUT_CONFIG } from '@/components/eventLayout/constants';\nimport { LayoutWeekEvent, ParallelGroup } from '@/co"
},
{
"path": "packages/core/src/components/eventLayout/calculate/layout.ts",
"chars": 6670,
"preview": "import { LAYOUT_CONFIG } from '@/components/eventLayout/constants';\nimport {\n LayoutNode,\n LayoutCalculationParams,\n "
},
{
"path": "packages/core/src/components/eventLayout/calculate/rebalance.ts",
"chars": 3464,
"preview": "import {\n LayoutWeekEvent,\n ParallelGroup,\n LayoutNode,\n} from '@/components/eventLayout/types';\nimport { canEventCon"
},
{
"path": "packages/core/src/components/eventLayout/calculate/structure.ts",
"chars": 10607,
"preview": "import { LAYOUT_CONFIG } from '@/components/eventLayout/constants';\nimport {\n LayoutWeekEvent,\n ParallelGroup,\n Layou"
},
{
"path": "packages/core/src/components/eventLayout/constants.ts",
"chars": 454,
"preview": "export const LAYOUT_CONFIG = {\n PARALLEL_THRESHOLD: 0.25, // 15 minutes, parallel layout threshold\n NESTED_THRESHOLD: "
},
{
"path": "packages/core/src/components/eventLayout/index.tsx",
"chars": 3069,
"preview": "import { EventLayout, Event } from '@/types';\n\nimport {\n groupOverlappingEvents,\n analyzeParallelGroups,\n} from './cal"
},
{
"path": "packages/core/src/components/eventLayout/types.ts",
"chars": 806,
"preview": "import { Event } from '@/types';\n\nexport interface LayoutWeekEvent extends Event {\n parentId?: string;\n children: stri"
},
{
"path": "packages/core/src/components/eventLayout/utils.ts",
"chars": 4169,
"preview": "import { Event } from '@/types';\nimport { extractHourFromDate, getEventEndHour } from '@/utils/helpers';\n\nimport { Layou"
},
{
"path": "packages/core/src/components/mobileEventDrawer/DefaultMobileEventDrawer.tsx",
"chars": 19858,
"preview": "import { JSX } from 'preact';\nimport { createPortal } from 'preact/compat';\nimport { useState, useEffect, useMemo } from"
},
{
"path": "packages/core/src/components/mobileEventDrawer/__tests__/DefaultMobileEventDrawer.test.tsx",
"chars": 2676,
"preview": "import { fireEvent, render, screen } from '@testing-library/preact';\nimport { Temporal } from 'temporal-polyfill';\n\nimpo"
},
{
"path": "packages/core/src/components/mobileEventDrawer/components/Switch.tsx",
"chars": 500,
"preview": "interface SwitchProps {\n checked: boolean;\n onChange: (v: boolean) => void;\n disabled?: boolean;\n}\n\nexport const Swit"
},
{
"path": "packages/core/src/components/mobileEventDrawer/components/TimePickerWheel.tsx",
"chars": 6626,
"preview": "import { useState, useEffect, useRef } from 'preact/hooks';\n\ninterface TimePickerWheelProps {\n date: Date;\n onChange: "
},
{
"path": "packages/core/src/components/mobileEventDrawer/components/__tests__/Switch.test.tsx",
"chars": 692,
"preview": "import { fireEvent, render, screen } from '@testing-library/preact';\n\nimport { Switch } from '@/components/mobileEventDr"
},
{
"path": "packages/core/src/components/mobileEventDrawer/index.ts",
"chars": 127,
"preview": "export * from './DefaultMobileEventDrawer';\nexport * from './components/Switch';\nexport * from './components/TimePickerW"
},
{
"path": "packages/core/src/components/monthView/MultiDayEvent.tsx",
"chars": 14798,
"preview": "import { ComponentChildren } from 'preact';\nimport { memo } from 'preact/compat';\nimport { useState, useRef, useMemo } f"
},
{
"path": "packages/core/src/components/monthView/WeekComponent.tsx",
"chars": 23348,
"preview": "import { RefObject } from 'preact';\nimport { memo } from 'preact/compat';\nimport { useEffect, useMemo, useRef, useState "
},
{
"path": "packages/core/src/components/monthView/WeekDayCell.tsx",
"chars": 12075,
"preview": "import { ComponentChild, RefObject } from 'preact';\nimport { useRef } from 'preact/hooks';\n\nimport CalendarEvent from '@"
},
{
"path": "packages/core/src/components/monthView/__tests__/WeekComponent.test.tsx",
"chars": 15830,
"preview": "import { render, within } from '@testing-library/preact';\nimport { Temporal } from 'temporal-polyfill';\n\nimport WeekComp"
},
{
"path": "packages/core/src/components/monthView/util.tsx",
"chars": 18255,
"preview": "import { Temporal } from 'temporal-polyfill';\n\nimport {\n CalendarDays,\n Gift,\n Heart,\n MapPin,\n Star,\n} from '@/com"
},
{
"path": "packages/core/src/components/search/MobileSearchDialog.tsx",
"chars": 2830,
"preview": "import { createPortal } from 'preact/compat';\nimport { useRef, useEffect } from 'preact/hooks';\n\nimport { ArrowLeft, X }"
},
{
"path": "packages/core/src/components/search/SearchDrawer.tsx",
"chars": 839,
"preview": "import { CalendarSearchEvent } from '@/types/search';\n\nimport SearchResultsList from './SearchResultsList';\n\ninterface S"
},
{
"path": "packages/core/src/components/search/SearchResultsList.tsx",
"chars": 4497,
"preview": "import { useMemo } from 'preact/hooks';\n\nimport { Loader2 } from '@/components/common/Icons';\nimport { useLocale } from "
},
{
"path": "packages/core/src/components/weekView/AllDayRow.tsx",
"chars": 16928,
"preview": "import { RefObject, JSX } from 'preact';\nimport { useEffect, useState, useMemo } from 'preact/hooks';\n\nimport CalendarEv"
},
{
"path": "packages/core/src/components/weekView/CompactHeader.tsx",
"chars": 3178,
"preview": "import { ICalendarApp } from '@/types';\n\ninterface CompactHeaderProps {\n app: ICalendarApp;\n fullWeekDates?: Array<{\n "
},
{
"path": "packages/core/src/components/weekView/TimeGrid.tsx",
"chars": 26090,
"preview": "import { RefObject, CSSProperties, TargetedEvent } from 'preact';\nimport {\n useEffect,\n useState,\n useRef,\n useMemo,"
},
{
"path": "packages/core/src/components/weekView/__tests__/util.timezone.test.ts",
"chars": 919,
"preview": "import { Temporal } from 'temporal-polyfill';\n\nimport { filterWeekEvents } from '@/components/weekView/util';\nimport { E"
},
{
"path": "packages/core/src/components/weekView/util.ts",
"chars": 11625,
"preview": "import { EventLayoutCalculator } from '@/components/eventLayout';\nimport {\n analyzeMultiDayRegularEvent,\n analyzeMulti"
},
{
"path": "packages/core/src/components/yearView/DefaultYearView.tsx",
"chars": 17908,
"preview": "import { RefObject } from 'preact';\nimport {\n useMemo,\n useRef,\n useEffect,\n useLayoutEffect,\n useState,\n useCallb"
},
{
"path": "packages/core/src/components/yearView/FixedWeekMonthRow.tsx",
"chars": 9731,
"preview": "import { RefObject } from 'preact';\nimport { memo } from 'preact/compat';\nimport { useCallback, useMemo } from 'preact/h"
},
{
"path": "packages/core/src/components/yearView/FixedWeekYearView.tsx",
"chars": 19276,
"preview": "import { RefObject, JSX } from 'preact';\nimport {\n useMemo,\n useRef,\n useCallback,\n useState,\n useEffect,\n} from 'p"
},
{
"path": "packages/core/src/components/yearView/GridDayPopup.tsx",
"chars": 4066,
"preview": "import { ComponentChildren } from 'preact';\nimport { createPortal } from 'preact/compat';\nimport { useEffect, useRef } f"
},
{
"path": "packages/core/src/components/yearView/GridYearView.tsx",
"chars": 14255,
"preview": "import { useMemo, useState, useCallback, useEffect } from 'preact/hooks';\n\nimport ViewHeader from '@/components/common/V"
},
{
"path": "packages/core/src/components/yearView/YearDayCell.tsx",
"chars": 2183,
"preview": "import { memo } from 'preact/compat';\n\nimport { useLocale } from '@/locale';\n\ninterface YearDayCellProps {\n date: Date;"
},
{
"path": "packages/core/src/components/yearView/YearRowComponent.tsx",
"chars": 13772,
"preview": "import { RefObject } from 'preact';\nimport { memo } from 'preact/compat';\nimport { useCallback, useMemo } from 'preact/h"
},
{
"path": "packages/core/src/components/yearView/__tests__/DefaultYearView.test.tsx",
"chars": 4535,
"preview": "import { fireEvent, render, waitFor } from '@testing-library/preact';\n\nimport { DefaultYearView } from '@/components/yea"
},
{
"path": "packages/core/src/components/yearView/__tests__/utils.test.ts",
"chars": 3377,
"preview": "import { Temporal } from 'temporal-polyfill';\n\nimport { analyzeMultiDayEventsForRow } from '@/components/yearView/utils'"
},
{
"path": "packages/core/src/components/yearView/utils.ts",
"chars": 19962,
"preview": "import { Event } from '@/types';\nimport {\n dateToPlainDate,\n dateToZonedDateTime,\n temporalToVisualDate,\n} from '@/ut"
},
{
"path": "packages/core/src/contexts/ThemeContext.tsx",
"chars": 5187,
"preview": "import { h, createContext, ComponentChildren } from 'preact';\nimport {\n useContext,\n useEffect,\n useLayoutEffect,\n u"
},
{
"path": "packages/core/src/core/CalendarApp.ts",
"chars": 14625,
"preview": "import { Temporal } from 'temporal-polyfill';\n\nimport { Locale } from '@/locale/types';\nimport { isValidLocale } from '@"
},
{
"path": "packages/core/src/core/CalendarStore.ts",
"chars": 5032,
"preview": "import { EventChange } from '@/types/core';\nimport { Event } from '@/types/event';\n\n/**\n * CalendarStore\n *\n * Responsib"
},
{
"path": "packages/core/src/core/__tests__/CalendarApp.test.ts",
"chars": 17032,
"preview": "import { Temporal } from 'temporal-polyfill';\n\nimport { CalendarApp } from '@/core/CalendarApp';\nimport { createDayView "
},
{
"path": "packages/core/src/core/__tests__/WeekViewConfig.test.ts",
"chars": 226,
"preview": "import { createWeekView } from '@/factories/createWeekView';\n\ndescribe('WeekView Configuration', () => {\n it('should cr"
},
{
"path": "packages/core/src/core/__tests__/calendarRegistry.test.ts",
"chars": 2550,
"preview": "import { CalendarRegistry } from '@/core/calendarRegistry';\nimport { CalendarType } from '@/types/calendarTypes';\n\nconst"
},
{
"path": "packages/core/src/core/calendarRegistry.ts",
"chars": 14396,
"preview": "// Calendar Registry - Manages calendar types and color resolution\n\nimport { CalendarType, ThemeMode, CalendarColors } f"
},
{
"path": "packages/core/src/core/config.ts",
"chars": 4679,
"preview": "import { CalendarConfig } from '@/types';\nimport { getLineColor as resolveLineColor } from '@/utils/colorUtils';\n\nexport"
},
{
"path": "packages/core/src/core/events/EventManager.ts",
"chars": 9899,
"preview": "import { CalendarRegistry } from '@/core/calendarRegistry';\nimport { CalendarStore } from '@/core/CalendarStore';\nimport"
},
{
"path": "packages/core/src/core/index.ts",
"chars": 430,
"preview": "// Core module export file\nexport * from './useCalendarApp';\nexport * from './config';\nexport * from '@/renderer/Calenda"
},
{
"path": "packages/core/src/core/navigation/NavigationController.ts",
"chars": 6424,
"preview": "import { Temporal } from 'temporal-polyfill';\n\nimport {\n CalendarAppState,\n CalendarCallbacks,\n CalendarView,\n Calen"
},
{
"path": "packages/core/src/core/permissions/CalendarPermissions.ts",
"chars": 1953,
"preview": "import { CalendarRegistry } from '@/core/calendarRegistry';\nimport { Event, ReadOnlyConfig } from '@/types';\n\n/**\n * Com"
},
{
"path": "packages/core/src/core/plugins/PluginManager.ts",
"chars": 1143,
"preview": "import { CalendarAppState, CalendarPlugin, ICalendarApp } from '@/types';\nimport { logger } from '@/utils/logger';\n\nexpo"
},
{
"path": "packages/core/src/core/useCalendarApp.ts",
"chars": 9096,
"preview": "import {\n useState,\n useCallback,\n useMemo,\n useEffect,\n useRef,\n} from 'preact/hooks';\n\nimport {\n CalendarAppConf"
},
{
"path": "packages/core/src/factories/ViewAdapter.tsx",
"chars": 5189,
"preview": "import { useMemo, useCallback } from 'preact/hooks';\n\nimport {\n CalendarViewType,\n ViewType,\n ViewAdapterProps,\n Bas"
},
{
"path": "packages/core/src/factories/createAgendaView.ts",
"chars": 986,
"preview": "// Factory function for creating Agenda view\nimport { h } from 'preact';\n\nimport {\n AgendaViewConfig,\n AgendaViewProps"
},
{
"path": "packages/core/src/factories/createDayView.ts",
"chars": 992,
"preview": "// Factory function for creating Day view\nimport { h } from 'preact';\n\nimport {\n DayViewConfig,\n DayViewProps,\n ViewA"
},
{
"path": "packages/core/src/factories/createMonthView.ts",
"chars": 1120,
"preview": "// Factory function for creating Month view\nimport { h } from 'preact';\n\nimport {\n MonthViewConfig,\n MonthViewProps,\n "
},
{
"path": "packages/core/src/factories/createWeekView.ts",
"chars": 1043,
"preview": "// Factory function for creating Week view\nimport { h } from 'preact';\n\nimport {\n ViewAdapterProps,\n ViewFactory,\n Vi"
},
{
"path": "packages/core/src/factories/createYearView.ts",
"chars": 1015,
"preview": "// Factory function for creating Year view\nimport { h } from 'preact';\n\nimport {\n ViewAdapterProps,\n ViewFactory,\n Vi"
},
{
"path": "packages/core/src/factories/index.ts",
"chars": 967,
"preview": "// View factory module export file\nexport * from './createDayView';\nexport * from './createWeekView';\nexport * from './c"
},
{
"path": "packages/core/src/hooks/__tests__/useCalendarDrop.test.tsx",
"chars": 2157,
"preview": "import { act, renderHook } from '@testing-library/preact';\nimport { Temporal } from 'temporal-polyfill';\n\nimport { useCa"
},
{
"path": "packages/core/src/hooks/useCalendarDrop.ts",
"chars": 4445,
"preview": "import { useCallback } from 'preact/hooks';\nimport { Temporal } from 'temporal-polyfill';\n\nimport { useLocale } from '@/"
},
{
"path": "packages/core/src/hooks/useDebouncedValue.ts",
"chars": 399,
"preview": "import { useEffect, useState } from 'preact/hooks';\n\nexport const useDebouncedValue = <T>(value: T, delay: number): T =>"
},
{
"path": "packages/core/src/hooks/useWeekViewSwipe.ts",
"chars": 10285,
"preview": "import { JSX, RefObject } from 'preact';\nimport { useCallback, useEffect, useRef, useState } from 'preact/hooks';\n\nimpor"
},
{
"path": "packages/core/src/hooks/virtualScroll/index.ts",
"chars": 116,
"preview": "// Main entry for virtual scroll hooks\nexport * from './useVirtualScroll';\nexport * from './useVirtualMonthScroll';\n"
},
{
"path": "packages/core/src/hooks/virtualScroll/useVirtualMonthScroll.ts",
"chars": 25943,
"preview": "import { JSX } from 'preact';\nimport {\n useState,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useCallback,\n}"
},
{
"path": "packages/core/src/hooks/virtualScroll/useVirtualScroll.ts",
"chars": 10591,
"preview": "import { JSX } from 'preact';\nimport {\n useState,\n useEffect,\n useMemo,\n useRef,\n useCallback,\n} from 'preact/hooks"
},
{
"path": "packages/core/src/index.ts",
"chars": 3214,
"preview": "// Core library entry file\n\n// Calendar App and Registry\nexport { CalendarApp } from './core/CalendarApp';\nexport type {"
},
{
"path": "packages/core/src/locale/LocaleContext.tsx",
"chars": 688,
"preview": "import { createContext } from 'preact';\n\nimport type { LocaleCode, TranslationKey } from './types';\n\nexport interface Lo"
},
{
"path": "packages/core/src/locale/LocaleProvider.tsx",
"chars": 1967,
"preview": "import { ComponentChildren } from 'preact';\nimport { useMemo } from 'preact/hooks';\n\nimport { getWeekDaysLabels, getMont"
},
{
"path": "packages/core/src/locale/index.ts",
"chars": 227,
"preview": "export * from './types';\nexport * from './translator';\nexport * from './intl';\nexport * from './locales';\nexport * from "
},
{
"path": "packages/core/src/locale/intl.ts",
"chars": 2091,
"preview": "/**\n * Encapsulates Intl API calls for standard calendar terms.\n */\nexport function getIntlLabel(\n key: 'today' | 'day'"
},
{
"path": "packages/core/src/locale/locales/en.ts",
"chars": 3052,
"preview": "import type { Locale } from '@/locale/types';\n\nconst en: Locale = {\n code: 'en-US',\n messages: {\n allDay: 'All day'"
},
{
"path": "packages/core/src/locale/locales/index.ts",
"chars": 563,
"preview": "import { Locale } from '@/locale/types';\n\nimport en from './en';\n\nexport { en };\n\n/**\n * Global locale registry for the "
},
{
"path": "packages/core/src/locale/translator.ts",
"chars": 977,
"preview": "import { getIntlLabel, capitalize } from './intl';\nimport { LOCALES } from './locales';\nimport type { TranslationKey, Lo"
},
{
"path": "packages/core/src/locale/types.ts",
"chars": 1600,
"preview": "export type LocaleCode = string;\n\nexport type TranslationKey =\n | 'allDay'\n | 'noEvents'\n | 'more'\n | 'eventTitle'\n "
},
{
"path": "packages/core/src/locale/useLocale.ts",
"chars": 270,
"preview": "import { useContext } from 'preact/hooks';\n\nimport { LocaleContext, LocaleContextValue } from './LocaleContext';\n\n/**\n *"
},
{
"path": "packages/core/src/locale/utils.ts",
"chars": 587,
"preview": "import { LOCALES, SupportedLang } from './locales';\n\n/**\n * Normalizes a locale string to a supported language code.\n * "
},
{
"path": "packages/core/src/plugins/dragBridge.ts",
"chars": 825,
"preview": "import type { ICalendarApp, DragHookOptions, DragHookReturn } from '@/types';\n\ntype DragForViewFn = (\n app: ICalendarAp"
},
{
"path": "packages/core/src/plugins/eventsPlugin.ts",
"chars": 5454,
"preview": "// Event management plugin\nimport {\n CalendarPlugin,\n ICalendarApp,\n Event,\n EventsService,\n EventsPluginConfig,\n} "
},
{
"path": "packages/core/src/plugins/index.ts",
"chars": 355,
"preview": "// Plugin module export file\nimport { createEventsPlugin } from './eventsPlugin';\n\nexport * from './eventsPlugin';\nexpor"
},
{
"path": "packages/core/src/plugins/sidebarBridge.ts",
"chars": 855,
"preview": "import type { ICalendarApp, TNode } from '@/types';\n\nexport interface SidebarBridgeReturn {\n enabled: boolean;\n width:"
},
{
"path": "packages/core/src/renderer/CalendarRenderer.tsx",
"chars": 2308,
"preview": "import { render, h } from 'preact';\n\nimport { ICalendarApp } from '@/types';\nimport { isDeepEqual } from '@/utils/compar"
},
{
"path": "packages/core/src/renderer/CalendarRoot.tsx",
"chars": 13670,
"preview": "import { h, ComponentChildren } from 'preact';\nimport { createPortal } from 'preact/compat';\nimport {\n useCallback,\n u"
},
{
"path": "packages/core/src/renderer/ContentSlot.tsx",
"chars": 3022,
"preview": "import { ComponentChildren } from 'preact';\nimport {\n useRef,\n useEffect,\n useLayoutEffect,\n useContext,\n useState,"
},
{
"path": "packages/core/src/renderer/CustomRenderingContext.ts",
"chars": 195,
"preview": "import { createContext } from 'preact';\n\nimport { CustomRenderingStore } from './CustomRenderingStore';\n\nexport const Cu"
},
{
"path": "packages/core/src/renderer/CustomRenderingStore.ts",
"chars": 2455,
"preview": "export interface CustomRendering {\n id: string;\n containerEl: HTMLElement; // The placeholder div created by Preact\n "
},
{
"path": "packages/core/src/renderer/hooks/__tests__/useSearchController.test.ts",
"chars": 5060,
"preview": "import { renderHook, act } from '@testing-library/preact';\n\nimport { useSearchController } from '@/renderer/hooks/useSea"
},
{
"path": "packages/core/src/renderer/hooks/useAppSubscription.ts",
"chars": 1096,
"preview": "import { useState, useEffect } from 'preact/hooks';\n\nimport { ICalendarApp } from '@/types';\n\nexport interface AppSubscr"
},
{
"path": "packages/core/src/renderer/hooks/useEventDialogController.ts",
"chars": 3334,
"preview": "import {\n useState,\n useEffect,\n useCallback,\n useMemo,\n useRef,\n} from 'preact/hooks';\n\nimport { ICalendarApp, Eve"
},
{
"path": "packages/core/src/renderer/hooks/useQuickCreateController.ts",
"chars": 3240,
"preview": "import { JSX, RefObject } from 'preact';\nimport { useState, useCallback, useRef } from 'preact/hooks';\n\nimport { ICalend"
},
{
"path": "packages/core/src/renderer/hooks/useResponsive.ts",
"chars": 667,
"preview": "import { useState, useEffect } from 'preact/hooks';\n\nexport interface ResponsiveResult {\n isMobile: boolean;\n}\n\n/**\n * "
},
{
"path": "packages/core/src/renderer/hooks/useSearchController.ts",
"chars": 6391,
"preview": "import { useState, useEffect, useCallback, useRef } from 'preact/hooks';\nimport { Temporal } from 'temporal-polyfill';\n\n"
},
{
"path": "packages/core/src/setupTests.ts",
"chars": 373,
"preview": "import '@testing-library/jest-dom';\n\n// Mock ResizeObserver\nglobal.ResizeObserver = class ResizeObserver {\n // eslint-d"
},
{
"path": "packages/core/src/styles/__tests__/dist-css.test.ts",
"chars": 12348,
"preview": "/**\n * CSS dist output integrity tests\n *\n * These tests guard against the two recurring CSS issues:\n *\n * Issue #69 / h"
},
{
"path": "packages/core/src/styles/classNames.ts",
"chars": 7890,
"preview": "/**\n * Shared DayFlow semantic class constants used across core components.\n * All exports use df-* semantic classes; at"
},
{
"path": "packages/core/src/styles/core/common/forms-dialogs.css",
"chars": 10179,
"preview": "@layer components {\n /* ===================================================================\n * Shared form elements "
},
{
"path": "packages/core/src/styles/core/common/header-controls.css",
"chars": 12373,
"preview": "@layer components {\n /* ===================================================================\n * CalendarHeader (.df-h"
},
{
"path": "packages/core/src/styles/core/events/calendar-event.css",
"chars": 12841,
"preview": "@layer components {\n /* ===================================================================\n * Calendar event root co"
},
{
"path": "packages/core/src/styles/core/overlays/mobile-event-drawer.css",
"chars": 7840,
"preview": "@layer components {\n .df-mobile-event-drawer {\n position: fixed;\n inset: 0;\n z-index: 10000;\n display: flex"
},
{
"path": "packages/core/src/styles/core/overlays/quick-create.css",
"chars": 3352,
"preview": "@layer components {\n /* ===================================================================\n * QuickCreateEventPopup "
},
{
"path": "packages/core/src/styles/core/search/search.css",
"chars": 7038,
"preview": "@layer components {\n /* ===================================================================\n * Search group (always v"
},
{
"path": "packages/core/src/styles/core/views/layout.css",
"chars": 41424,
"preview": "@layer components {\n /* ===================================================================\n * View layout overrides\n"
},
{
"path": "packages/core/src/styles/core-components.css",
"chars": 459,
"preview": "/**\n * core-components.css\n *\n * Semantic CSS classes for DayFlow core components.\n * This file acts as the single impor"
}
]
// ... and 415 more files (download for full content)
About this extraction
This page contains the full source code of the dayflow-js/calendar GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 615 files (3.0 MB), approximately 812.1k tokens, and a symbol index with 874 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.