@dayflow/plugin-sidebar 1.2.5 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -8,6 +8,7 @@ interface CalendarSidebarRenderProps {
8
8
  toggleAll: (visible: boolean) => void;
9
9
  isCollapsed: boolean;
10
10
  setCollapsed: (collapsed: boolean) => void;
11
+ showEventDots?: boolean;
11
12
  renderCalendarContextMenu?: (calendar: CalendarType, onClose: () => void) => TNode;
12
13
  renderSidebarHeader?: (args: SidebarHeaderSlotArgs) => TNode;
13
14
  createCalendarMode?: 'inline' | 'modal';
@@ -22,6 +23,7 @@ interface SidebarPluginConfig {
22
23
  width?: number | string;
23
24
  miniWidth?: string;
24
25
  initialCollapsed?: boolean;
26
+ showEventDots?: boolean;
25
27
  createCalendarMode?: 'inline' | 'modal';
26
28
  render?: (props: CalendarSidebarRenderProps) => TNode;
27
29
  renderCalendarContextMenu?: (calendar: CalendarType, onClose: () => void) => TNode;
@@ -29,7 +31,6 @@ interface SidebarPluginConfig {
29
31
  renderCreateCalendarDialog?: (props: CreateCalendarDialogProps) => TNode;
30
32
  onSubscribeCalendar?: (calendar: CalendarType, events: Event[]) => Promise<void>;
31
33
  onLoadSubscription?: (calendar: CalendarType) => Promise<void>;
32
- [key: string]: unknown;
33
34
  }
34
35
  declare function createSidebarPlugin(config?: SidebarPluginConfig): CalendarPlugin;
35
36
 
package/dist/index.esm.js CHANGED
@@ -53,9 +53,8 @@ const CalendarItem = ({ calendar, isDraggable, isEditable: _isEditable, editingI
53
53
  const isActive = activeContextMenuCalendarId === calendar.id || editingId === calendar.id;
54
54
  return (u("li", { className: 'df-calendar-list-item relative', onDragOver: e => onDragOver(e, calendar.id), onDragLeave: onDragLeave, onDrop: () => onDrop(calendar), onContextMenu: e => onContextMenu(e, calendar.id), children: [isDropTarget && dropTarget.position === 'top' && (u("div", { className: 'pointer-events-none absolute top-0 right-0 left-0 z-10 h-0.5 bg-[var(--df-color-primary)]' })), u("div", { draggable: isDraggable && !editingId, onDragStart: e => onDragStart(calendar, e), onDragEnd: onDragEnd, className: `rounded transition ${draggedCalendarId === calendar.id ? 'opacity-50' : ''} ${isDraggable ? 'cursor-grab' : 'cursor-default'}`, children: u("div", { className: `group flex items-center rounded px-2 py-2 transition hover:bg-gray-100 dark:hover:bg-slate-800 ${isActive ? 'bg-gray-100 dark:bg-slate-800' : ''}`, title: calendar.name, children: [u("input", { type: 'checkbox', className: 'df-calendar-checkbox shrink-0 cursor-pointer', style: {
55
55
  '--checkbox-color': calendarColor,
56
- }, checked: isVisible, onChange: event => onToggleVisibility(calendar.id, event.target.checked) }), showIcon && (u("span", { className: 'ml-2 flex h-5 w-5 shrink-0 items-center justify-center text-xs font-semibold text-white', "aria-hidden": 'true', children: getCalendarInitials(calendar) })), editingId === calendar.id ? (u("input", { ref: editInputRef, type: 'text', value: editingName, onChange: e => setEditingName(e.target.value), onBlur: onRenameSave, onKeyDown: onRenameKeyDown, className: 'ml-2 h-5 min-w-0 flex-1 rounded bg-white px-0 py-0 text-sm text-gray-900 focus:outline-none dark:bg-slate-700 dark:text-gray-100', onClick: e => e.stopPropagation() })) : (u(Fragment, { children: [u("span", { className: 'ml-2 flex-1 truncate pl-1 text-sm text-gray-700 group-hover:text-gray-900 dark:text-gray-200 dark:group-hover:text-white', onDblClick: () => onRenameStart(calendar), children: calendar.name || calendar.id }), ((_b = calendar.subscription) === null || _b === void 0 ? void 0 : _b.status) === 'error' && (u(AlertCircle, { width: 13, height: 13, className: 'ml-1 shrink-0 text-red-500', title: 'Failed to load subscription' })), calendar.subscribed &&
57
- (!calendar.subscription ||
58
- calendar.subscription.status === 'ready') && (u(AudioLines, { width: 13, height: 13, className: 'ml-1 shrink-0 text-gray-400 dark:text-gray-500' }))] }))] }) }), isDropTarget && dropTarget.position === 'bottom' && (u("div", { className: 'pointer-events-none absolute right-0 bottom-0 left-0 z-10 h-0.5 bg-[var(--df-color-primary)]' }))] }, calendar.id));
56
+ }, checked: isVisible, onChange: event => onToggleVisibility(calendar.id, event.target.checked) }), showIcon && (u("span", { className: 'ml-2 flex h-5 w-5 shrink-0 items-center justify-center text-xs font-semibold text-white', "aria-hidden": 'true', children: getCalendarInitials(calendar) })), editingId === calendar.id ? (u("input", { ref: editInputRef, type: 'text', value: editingName, onChange: e => setEditingName(e.target.value), onBlur: onRenameSave, onKeyDown: onRenameKeyDown, className: 'ml-2 h-5 min-w-0 flex-1 rounded bg-white px-0 py-0 text-sm text-gray-900 focus:outline-none dark:bg-slate-700 dark:text-gray-100', onClick: e => e.stopPropagation() })) : (u(Fragment, { children: [u("span", { className: 'ml-2 flex-1 truncate pl-1 text-sm text-gray-700 group-hover:text-gray-900 dark:text-gray-200 dark:group-hover:text-white', onDblClick: () => onRenameStart(calendar), children: calendar.name || calendar.id }), ((_b = calendar.subscription) === null || _b === void 0 ? void 0 : _b.status) === 'error' && (u(AlertCircle, { width: 13, height: 13, className: 'ml-1 shrink-0 text-red-500', title: 'Failed to load subscription' })), calendar.subscription &&
57
+ calendar.subscription.status === 'ready' && (u(AudioLines, { width: 13, height: 13, className: 'ml-1 shrink-0 text-gray-400 dark:text-gray-500' }))] }))] }) }), isDropTarget && dropTarget.position === 'bottom' && (u("div", { className: 'pointer-events-none absolute right-0 bottom-0 left-0 z-10 h-0.5 bg-[var(--df-color-primary)]' }))] }, calendar.id));
59
58
  };
60
59
  const CalendarList = ({ calendars, onToggleVisibility, onReorder, onRename, onContextMenu, editingId, setEditingId, activeContextMenuCalendarId, isDraggable = true, isEditable = true, }) => {
61
60
  var _a;
@@ -279,7 +278,7 @@ const DeleteCalendarDialog = ({ calendarId, calendarName, calendars, step, onSte
279
278
  handleMergeSelect(calendar.id);
280
279
  }, children: [u("div", { className: 'mr-2 h-3 w-3 shrink-0 rounded-sm', style: {
281
280
  backgroundColor: calendar.colors.lineColor,
282
- } }), u("span", { className: 'whitespace-nowrap', children: calendar.name || calendar.id })] }, calendar.id))) }))] }), u("div", { className: 'flex gap-3', children: [u("button", { type: 'button', onClick: onCancel, disabled: isLoading, className: `${cancelButton} disabled:opacity-50`, children: t('cancel') }), u("button", { type: 'button', onClick: () => onStepChange('confirm_delete'), disabled: isLoading, className: 'rounded-md bg-destructive px-4 py-2 text-xs font-medium text-destructive-foreground hover:bg-destructive/90 disabled:opacity-50', children: t('delete') })] })] })] })) : (u(Fragment, { children: [u("h2", { className: 'text-lg font-semibold text-gray-900 dark:text-white', children: t('confirmDeleteTitle', { calendarName }) }), u("p", { className: 'mt-3 text-sm text-gray-600 dark:text-gray-300', children: t('confirmDeleteMessage') }), u("div", { className: 'mt-6 flex justify-end gap-3', children: [u("button", { type: 'button', onClick: onCancel, disabled: isLoading, className: 'rounded-md border border-border bg-background px-3 py-2 text-xs font-medium text-gray-700 hover:bg-gray-100 disabled:opacity-50 dark:text-gray-300 dark:hover:bg-slate-700', children: t('cancel') }), u(LoadingButton, { type: 'button', onClick: handleConfirmDelete, loading: isLoading, className: 'rounded-md bg-destructive px-3 py-2 text-xs font-medium text-destructive-foreground hover:bg-destructive/90', children: t('delete') })] })] })) }) }), document.body);
281
+ } }), u("span", { className: 'whitespace-nowrap', children: calendar.name || calendar.id })] }, calendar.id))) }))] }), u("div", { className: 'flex gap-3', children: [u("button", { type: 'button', onClick: onCancel, disabled: isLoading, className: `${cancelButton} disabled:opacity-50`, children: t('cancel') }), u("button", { type: 'button', onClick: () => onStepChange('confirm_delete'), disabled: isLoading, className: 'df-fill-destructive df-hover-destructive rounded-md px-4 py-2 text-xs font-medium disabled:opacity-50', children: t('delete') })] })] })] })) : (u(Fragment, { children: [u("h2", { className: 'text-lg font-semibold text-gray-900 dark:text-white', children: t('confirmDeleteTitle', { calendarName }) }), u("p", { className: 'mt-3 text-sm text-gray-600 dark:text-gray-300', children: t('confirmDeleteMessage') }), u("div", { className: 'mt-6 flex justify-end gap-3', children: [u("button", { type: 'button', onClick: onCancel, disabled: isLoading, className: 'rounded-md border border-border bg-background px-3 py-2 text-xs font-medium text-gray-700 hover:bg-gray-100 disabled:opacity-50 dark:text-gray-300 dark:hover:bg-slate-700', children: t('cancel') }), u(LoadingButton, { type: 'button', onClick: handleConfirmDelete, loading: isLoading, className: 'df-fill-destructive df-hover-destructive rounded-md px-3 py-2 text-xs font-medium', children: t('delete') })] })] })) }) }), document.body);
283
282
  };
284
283
 
285
284
  const NEW_CALENDAR_ID = 'new-calendar';
@@ -337,17 +336,17 @@ const ImportCalendarDialog = ({ calendars, filename, onConfirm, onCancel, }) =>
337
336
  const rect = (_a = triggerRef.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
338
337
  if (!rect)
339
338
  return null;
340
- return createPortal(u("div", { ref: dropdownRef, className: `fixed z-110 mt-1 max-h-60 origin-top overflow-y-auto rounded-md border border-gray-200 bg-white shadow-lg transition-all duration-200 dark:border-slate-700 dark:bg-slate-800 ${isOpen ? 'scale-100 opacity-100' : 'scale-95 opacity-0'}`, style: {
339
+ return createPortal(u("div", { ref: dropdownRef, className: `df-portal fixed z-110 mt-1 max-h-60 origin-top overflow-y-auto rounded-md border border-gray-200 bg-white shadow-lg transition-all duration-200 dark:border-slate-700 dark:bg-slate-800 ${isOpen ? 'scale-100 opacity-100' : 'scale-95 opacity-0'}`, style: {
341
340
  top: rect.bottom,
342
341
  left: rect.left,
343
342
  width: rect.width,
344
343
  overscrollBehavior: 'none',
345
- }, children: u("div", { className: 'py-1', children: [calendars.map(calendar => (u("div", { className: `flex cursor-pointer items-center px-3 py-2 hover:bg-gray-100 dark:hover:bg-slate-700 ${selectedCalendarId === calendar.id ? 'bg-primary/10' : ''}`, onClick: () => handleSelect(calendar.id), children: [u("div", { className: 'mr-3 h-3 w-3 shrink-0 rounded-sm', style: { backgroundColor: calendar.colors.lineColor } }), u("span", { className: `flex-1 truncate text-sm ${selectedCalendarId === calendar.id ? 'font-medium text-primary' : 'text-gray-700 dark:text-gray-200'}`, children: calendar.name || calendar.id }), selectedCalendarId === calendar.id && (u(Check, { className: 'ml-2 h-4 w-4 shrink-0 text-primary' }))] }, calendar.id))), u("div", { className: 'my-1 border-t border-gray-100 dark:border-slate-700' }), u("div", { className: `flex cursor-pointer items-center px-3 py-2 hover:bg-gray-100 dark:hover:bg-slate-700 ${isNewSelected ? 'bg-primary/10' : ''}`, onClick: () => handleSelect(NEW_CALENDAR_ID), children: [u("span", { className: `flex-1 truncate text-sm ${isNewSelected ? 'font-medium text-primary' : 'pl-6 text-gray-700 dark:text-gray-200'}`, children: [t('newCalendar') || 'New Calendar', ": ", filename] }), isNewSelected && (u(Check, { className: 'ml-2 h-4 w-4 shrink-0 text-primary' }))] })] }) }), document.body);
344
+ }, children: u("div", { className: 'py-1', children: [calendars.map(calendar => (u("div", { className: `flex cursor-pointer items-center px-3 py-2 hover:bg-gray-100 dark:hover:bg-slate-700 ${selectedCalendarId === calendar.id ? 'df-tint-primary' : ''}`, onClick: () => handleSelect(calendar.id), children: [u("div", { className: 'mr-3 h-3 w-3 shrink-0 rounded-sm', style: { backgroundColor: calendar.colors.lineColor } }), u("span", { className: `flex-1 truncate text-sm ${selectedCalendarId === calendar.id ? 'df-text-primary font-medium' : 'text-gray-700 dark:text-gray-200'}`, children: calendar.name || calendar.id }), selectedCalendarId === calendar.id && (u(Check, { className: 'df-text-primary ml-2 h-4 w-4 shrink-0' }))] }, calendar.id))), u("div", { className: 'my-1 border-t border-gray-100 dark:border-slate-700' }), u("div", { className: `flex cursor-pointer items-center px-3 py-2 hover:bg-gray-100 dark:hover:bg-slate-700 ${isNewSelected ? 'df-tint-primary' : ''}`, onClick: () => handleSelect(NEW_CALENDAR_ID), children: [u("span", { className: `flex-1 truncate text-sm ${isNewSelected ? 'df-text-primary font-medium' : 'pl-6 text-gray-700 dark:text-gray-200'}`, children: [t('newCalendar') || 'New Calendar', ": ", filename] }), isNewSelected && (u(Check, { className: 'df-text-primary ml-2 h-4 w-4 shrink-0' }))] })] }) }), document.body);
346
345
  };
347
346
  return (u("div", { className: 'df-portal fixed inset-0 z-100 flex items-center justify-center bg-black/50', children: u("div", { className: 'w-full max-w-md rounded-lg bg-white p-6 shadow-xl dark:bg-gray-900', children: [u("h2", { className: 'mb-4 text-lg font-semibold text-gray-900 dark:text-white', children: t('addSchedule') || 'Add Schedule' }), u("p", { className: 'mb-4 text-sm text-gray-600 dark:text-gray-300', children: t('importCalendarMessage') ||
348
347
  'This calendar contains new events. Please select a target calendar.' }), u("div", { className: 'relative', children: [u("button", { ref: triggerRef, type: 'button', disabled: isLoading, className: 'flex w-full items-center rounded-md border border-gray-300 px-3 py-2 shadow-sm transition-colors hover:bg-gray-50 disabled:opacity-50 dark:border-gray-600 dark:hover:bg-gray-800', onClick: () => setIsOpen(!isOpen), children: [!isNewSelected && selectedCalendar && (u("div", { className: 'mr-3 h-3 w-3 shrink-0 rounded-sm', style: { backgroundColor: selectedCalendar.colors.lineColor } })), u("span", { className: `flex-1 truncate text-left text-sm font-medium text-gray-700 dark:text-gray-200 ${isNewSelected ? 'pl-0' : ''}`, children: isNewSelected
349
348
  ? `${t('newCalendar')}: ${filename}`
350
- : (selectedCalendar === null || selectedCalendar === void 0 ? void 0 : selectedCalendar.name) || (selectedCalendar === null || selectedCalendar === void 0 ? void 0 : selectedCalendar.id) }), u(ChevronsUpDown, { className: 'ml-2 h-4 w-4 shrink-0 text-gray-400' })] }), renderDropdown()] }), u("div", { className: 'mt-8 flex justify-end gap-3', children: [u("button", { type: 'button', onClick: onCancel, disabled: isLoading, className: `${cancelButton} disabled:opacity-50`, children: t('cancel') || 'Cancel' }), u(LoadingButton, { type: 'button', onClick: handleConfirm, loading: isLoading, className: 'rounded-md bg-primary px-6 py-2 text-sm font-medium text-primary-foreground shadow-sm transition-colors hover:bg-primary/90', children: t('ok') || 'OK' })] })] }) }));
349
+ : (selectedCalendar === null || selectedCalendar === void 0 ? void 0 : selectedCalendar.name) || (selectedCalendar === null || selectedCalendar === void 0 ? void 0 : selectedCalendar.id) }), u(ChevronsUpDown, { className: 'ml-2 h-4 w-4 shrink-0 text-gray-400' })] }), renderDropdown()] }), u("div", { className: 'mt-8 flex justify-end gap-3', children: [u("button", { type: 'button', onClick: onCancel, disabled: isLoading, className: `${cancelButton} disabled:opacity-50`, children: t('cancel') || 'Cancel' }), u(LoadingButton, { type: 'button', onClick: handleConfirm, loading: isLoading, className: 'df-fill-primary df-hover-primary-solid rounded-md px-6 py-2 text-sm font-medium shadow-sm transition-colors', children: t('ok') || 'OK' })] })] }) }));
351
350
  };
352
351
 
353
352
  const SOURCE_SENTINEL = '\u0001S\u0001';
@@ -384,7 +383,7 @@ const MergeCalendarDialog = ({ sourceName, sourceColor, targetName, targetColor,
384
383
  setIsLoading(false);
385
384
  }
386
385
  });
387
- return (u("div", { className: 'df-portal fixed inset-0 z-[9999] flex items-center justify-center bg-black/50', children: u("div", { className: 'rounded-lg bg-white p-6 shadow-xl dark:bg-gray-800', children: [u("h2", { className: 'text-lg font-semibold text-gray-900 dark:text-white', children: t('mergeConfirmTitle', { sourceName, targetName }) }), u("div", { className: 'mt-3 space-y-1 text-sm text-gray-600 dark:text-gray-300', children: messageLines.map((line, i) => (u("p", { className: 'flex flex-wrap items-center gap-y-0.5', children: renderLine(line, source, target) }, i))) }), u("div", { className: 'mt-6 flex justify-end gap-3', children: [u("button", { type: 'button', onClick: onCancel, disabled: isLoading, className: `${cancelButton} disabled:opacity-50`, children: t('cancel') }), u(LoadingButton, { type: 'button', onClick: handleConfirm, loading: isLoading, className: 'rounded-md bg-destructive px-3 py-2 text-xs font-medium text-destructive-foreground hover:bg-destructive/90', children: t('merge') })] })] }) }));
386
+ return (u("div", { className: 'df-portal fixed inset-0 z-[9999] flex items-center justify-center bg-black/50', children: u("div", { className: 'rounded-lg bg-white p-6 shadow-xl dark:bg-gray-800', children: [u("h2", { className: 'text-lg font-semibold text-gray-900 dark:text-white', children: t('mergeConfirmTitle', { sourceName, targetName }) }), u("div", { className: 'mt-3 space-y-1 text-sm text-gray-600 dark:text-gray-300', children: messageLines.map((line, i) => (u("p", { className: 'flex flex-wrap items-center gap-y-0.5', children: renderLine(line, source, target) }, i))) }), u("div", { className: 'mt-6 flex justify-end gap-3', children: [u("button", { type: 'button', onClick: onCancel, disabled: isLoading, className: `${cancelButton} disabled:opacity-50`, children: t('cancel') }), u(LoadingButton, { type: 'button', onClick: handleConfirm, loading: isLoading, className: 'df-fill-destructive df-hover-destructive rounded-md px-3 py-2 text-xs font-medium', children: t('merge') })] })] }) }));
388
387
  };
389
388
 
390
389
  const stopPropagation = (e) => e.stopPropagation();
@@ -465,11 +464,11 @@ const SubscribeCalendarDialog = ({ onSubscribe, onCancel, }) => {
465
464
  if (e.key === 'Escape')
466
465
  onCancel();
467
466
  };
468
- return (u("div", { className: 'df-portal fixed inset-0 z-[9999] flex items-center justify-center bg-black/50', children: u("div", { className: 'w-full max-w-xl rounded-lg bg-white p-6 shadow-xl dark:bg-gray-800', children: [u("h2", { className: 'text-lg font-semibold text-gray-900 dark:text-white', children: t('subscribeCalendarTitle') }), u("div", { className: 'mt-4', children: [u("div", { className: 'flex items-center gap-3', children: [u("label", { className: 'shrink-0 text-sm font-medium text-gray-700 dark:text-gray-300', children: t('calendarUrl') }), u("input", { type: 'url', value: url, onInput: e => setUrl(e.target.value), onKeyDown: handleKeyDown, placeholder: t('calendarUrlPlaceholder'), disabled: loading, autoFocus: true, className: 'flex-1 rounded-md border border-gray-300 bg-white px-3 py-2 text-sm text-gray-900 placeholder-gray-400 focus:border-primary focus:ring-1 focus:ring-primary focus:outline-none disabled:opacity-50 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:placeholder-gray-400' })] }), error && (u("p", { className: 'mt-2 text-xs text-red-500 dark:text-red-400', children: error }))] }), u("div", { className: 'mt-6 flex justify-end gap-3', children: [u("button", { type: 'button', onClick: onCancel, disabled: loading, className: cancelButton, children: t('cancel') }), u("button", { type: 'button', onClick: handleSubmit, disabled: loading || !url.trim(), className: 'rounded-md bg-primary px-4 py-2 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:cursor-not-allowed disabled:opacity-50', children: loading ? t('fetchingCalendar') : t('subscribe') })] })] }) }));
467
+ return (u("div", { className: 'df-portal fixed inset-0 z-[9999] flex items-center justify-center bg-black/50', children: u("div", { className: 'w-full max-w-xl rounded-lg bg-white p-6 shadow-xl dark:bg-gray-800', children: [u("h2", { className: 'text-lg font-semibold text-gray-900 dark:text-white', children: t('subscribeCalendarTitle') }), u("div", { className: 'mt-4', children: [u("div", { className: 'flex items-center gap-3', children: [u("label", { className: 'shrink-0 text-sm font-medium text-gray-700 dark:text-gray-300', children: t('calendarUrl') }), u("input", { type: 'url', value: url, onInput: e => setUrl(e.target.value), onKeyDown: handleKeyDown, placeholder: t('calendarUrlPlaceholder'), disabled: loading, autoFocus: true, className: 'df-focus-ring flex-1 rounded-md border border-gray-300 bg-white px-3 py-2 text-sm text-gray-900 placeholder-gray-400 focus:ring-1 focus:outline-none disabled:opacity-50 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:placeholder-gray-400' })] }), error && (u("p", { className: 'mt-2 text-xs text-red-500 dark:text-red-400', children: error }))] }), u("div", { className: 'mt-6 flex justify-end gap-3', children: [u("button", { type: 'button', onClick: onCancel, disabled: loading, className: cancelButton, children: t('cancel') }), u("button", { type: 'button', onClick: handleSubmit, disabled: loading || !url.trim(), className: 'df-fill-primary df-hover-primary-solid rounded-md px-4 py-2 text-xs font-medium disabled:cursor-not-allowed disabled:opacity-50', children: loading ? t('fetchingCalendar') : t('subscribe') })] })] }) }));
469
468
  };
470
469
 
471
- const DefaultCalendarSidebar = ({ app, calendars, toggleCalendarVisibility, isCollapsed, setCollapsed, renderCalendarContextMenu, renderSidebarHeader, editingCalendarId: propEditingCalendarId, setEditingCalendarId: propSetEditingCalendarId, onCreateCalendar, onSubscribeCalendar, onLoadSubscription, }) => {
472
- var _a, _b;
470
+ const DefaultCalendarSidebar = ({ app, calendars, toggleCalendarVisibility, isCollapsed, setCollapsed, showEventDots, renderCalendarContextMenu, renderSidebarHeader, editingCalendarId: propEditingCalendarId, setEditingCalendarId: propSetEditingCalendarId, onCreateCalendar, onSubscribeCalendar, onLoadSubscription, }) => {
471
+ var _a, _b, _c;
473
472
  const { t } = useLocale();
474
473
  // Detect if custom color picker slot is provided
475
474
  const hasCustomPicker = app.state.overrides.includes('colorPicker');
@@ -798,10 +797,10 @@ const DefaultCalendarSidebar = ({ app, calendars, toggleCalendarVisibility, isCo
798
797
  ? handleContextMenu
799
798
  : () => {
800
799
  /* noop */
801
- }, editingId: editingCalendarId, setEditingId: setEditingCalendarId, activeContextMenuCalendarId: contextMenu === null || contextMenu === void 0 ? void 0 : contextMenu.calendarId, isDraggable: isDraggable, isEditable: isEditable }), u("div", { className: 'border-t border-gray-200 dark:border-slate-800', children: u(MiniCalendar, { visibleMonth: app.getVisibleMonth(), currentDate: app.getCurrentDate(), showHeader: true, onMonthChange: handleMonthChange, onDateSelect: date => app.setCurrentDate(date) }) })] })), isEditable && contextMenu && (u(ContextMenu, { ref: contextMenuRef, x: contextMenu.x, y: contextMenu.y, onClose: handleCloseContextMenu, className: 'w-64 p-2', children: u(ContentSlot, { generatorName: 'calendarContextMenu', generatorArgs: {
800
+ }, editingId: editingCalendarId, setEditingId: setEditingCalendarId, activeContextMenuCalendarId: contextMenu === null || contextMenu === void 0 ? void 0 : contextMenu.calendarId, isDraggable: isDraggable, isEditable: isEditable }), u("div", { className: 'border-t border-gray-200 dark:border-slate-800', children: u(MiniCalendar, { visibleMonth: app.getVisibleMonth(), currentDate: app.getCurrentDate(), showHeader: true, onMonthChange: handleMonthChange, onDateSelect: date => app.setCurrentDate(date), events: app.getEvents(), showEventDots: showEventDots, calendarRegistry: app.getCalendarRegistry(), timeZone: ((_b = app.getViewConfig(app.state.currentView)) === null || _b === void 0 ? void 0 : _b.secondaryTimeZone) || undefined }) })] })), contextMenu && app.canMutateFromUI(contextMenu.calendarId) && (u(ContextMenu, { ref: contextMenuRef, x: contextMenu.x, y: contextMenu.y, onClose: handleCloseContextMenu, className: 'w-64 p-2', children: u(ContentSlot, { generatorName: 'calendarContextMenu', generatorArgs: {
802
801
  calendar: calendars.find(c => c.id === contextMenu.calendarId),
803
802
  onClose: handleCloseContextMenu,
804
- }, defaultContent: renderCalendarContextMenu ? (renderCalendarContextMenu(calendars.find(c => c.id === contextMenu.calendarId), handleCloseContextMenu)) : (u(Fragment, { children: [u(ContextMenuLabel, { children: t('calendarOptions') }), u(MergeMenuItem, { calendars: calendars, currentCalendarId: contextMenu.calendarId, onMergeSelect: handleMergeSelect }), u(ContextMenuItem, { onClick: handleDeleteCalendar, children: t('delete') }), u(ContextMenuItem, { onClick: handleExportCalendar, children: t('exportCalendar') || 'Export Calendar' }), u(ContextMenuSeparator, {}), u(ContextMenuColorPicker, { selectedColor: (_b = calendars.find(c => c.id === contextMenu.calendarId)) === null || _b === void 0 ? void 0 : _b.colors.lineColor, onSelect: handleColorSelect, onCustomColor: handleCustomColor })] })) }) })), isEditable &&
803
+ }, defaultContent: renderCalendarContextMenu ? (renderCalendarContextMenu(calendars.find(c => c.id === contextMenu.calendarId), handleCloseContextMenu)) : (u(Fragment, { children: [u(ContextMenuLabel, { children: t('calendarOptions') }), u(MergeMenuItem, { calendars: calendars, currentCalendarId: contextMenu.calendarId, onMergeSelect: handleMergeSelect }), u(ContextMenuItem, { onClick: handleDeleteCalendar, children: t('delete') }), u(ContextMenuItem, { onClick: handleExportCalendar, children: t('exportCalendar') || 'Export Calendar' }), u(ContextMenuSeparator, {}), u(ContextMenuColorPicker, { selectedColor: (_c = calendars.find(c => c.id === contextMenu.calendarId)) === null || _c === void 0 ? void 0 : _c.colors.lineColor, onSelect: handleColorSelect, onCustomColor: handleCustomColor })] })) }) })), isEditable &&
805
804
  sidebarContextMenu &&
806
805
  createPortal(u(ContextMenu, { x: sidebarContextMenu.x, y: sidebarContextMenu.y, onClose: handleCloseSidebarContextMenu, className: 'w-max p-2', children: [u(ContextMenuItem, { onClick: () => {
807
806
  onCreateCalendar === null || onCreateCalendar === void 0 ? void 0 : onCreateCalendar();
@@ -941,6 +940,7 @@ function createSidebarPlugin(config = {}) {
941
940
  toggleAll: handleToggleAllCalendars,
942
941
  isCollapsed,
943
942
  setCollapsed: setIsCollapsed,
943
+ showEventDots: config.showEventDots,
944
944
  renderCalendarContextMenu: config.renderCalendarContextMenu,
945
945
  renderSidebarHeader: config.renderSidebarHeader,
946
946
  createCalendarMode: config.createCalendarMode,
package/dist/index.js CHANGED
@@ -55,9 +55,8 @@ const CalendarItem = ({ calendar, isDraggable, isEditable: _isEditable, editingI
55
55
  const isActive = activeContextMenuCalendarId === calendar.id || editingId === calendar.id;
56
56
  return (u("li", { className: 'df-calendar-list-item relative', onDragOver: e => onDragOver(e, calendar.id), onDragLeave: onDragLeave, onDrop: () => onDrop(calendar), onContextMenu: e => onContextMenu(e, calendar.id), children: [isDropTarget && dropTarget.position === 'top' && (u("div", { className: 'pointer-events-none absolute top-0 right-0 left-0 z-10 h-0.5 bg-[var(--df-color-primary)]' })), u("div", { draggable: isDraggable && !editingId, onDragStart: e => onDragStart(calendar, e), onDragEnd: onDragEnd, className: `rounded transition ${draggedCalendarId === calendar.id ? 'opacity-50' : ''} ${isDraggable ? 'cursor-grab' : 'cursor-default'}`, children: u("div", { className: `group flex items-center rounded px-2 py-2 transition hover:bg-gray-100 dark:hover:bg-slate-800 ${isActive ? 'bg-gray-100 dark:bg-slate-800' : ''}`, title: calendar.name, children: [u("input", { type: 'checkbox', className: 'df-calendar-checkbox shrink-0 cursor-pointer', style: {
57
57
  '--checkbox-color': calendarColor,
58
- }, checked: isVisible, onChange: event => onToggleVisibility(calendar.id, event.target.checked) }), showIcon && (u("span", { className: 'ml-2 flex h-5 w-5 shrink-0 items-center justify-center text-xs font-semibold text-white', "aria-hidden": 'true', children: getCalendarInitials(calendar) })), editingId === calendar.id ? (u("input", { ref: editInputRef, type: 'text', value: editingName, onChange: e => setEditingName(e.target.value), onBlur: onRenameSave, onKeyDown: onRenameKeyDown, className: 'ml-2 h-5 min-w-0 flex-1 rounded bg-white px-0 py-0 text-sm text-gray-900 focus:outline-none dark:bg-slate-700 dark:text-gray-100', onClick: e => e.stopPropagation() })) : (u(preact.Fragment, { children: [u("span", { className: 'ml-2 flex-1 truncate pl-1 text-sm text-gray-700 group-hover:text-gray-900 dark:text-gray-200 dark:group-hover:text-white', onDblClick: () => onRenameStart(calendar), children: calendar.name || calendar.id }), ((_b = calendar.subscription) === null || _b === void 0 ? void 0 : _b.status) === 'error' && (u(core.AlertCircle, { width: 13, height: 13, className: 'ml-1 shrink-0 text-red-500', title: 'Failed to load subscription' })), calendar.subscribed &&
59
- (!calendar.subscription ||
60
- calendar.subscription.status === 'ready') && (u(core.AudioLines, { width: 13, height: 13, className: 'ml-1 shrink-0 text-gray-400 dark:text-gray-500' }))] }))] }) }), isDropTarget && dropTarget.position === 'bottom' && (u("div", { className: 'pointer-events-none absolute right-0 bottom-0 left-0 z-10 h-0.5 bg-[var(--df-color-primary)]' }))] }, calendar.id));
58
+ }, checked: isVisible, onChange: event => onToggleVisibility(calendar.id, event.target.checked) }), showIcon && (u("span", { className: 'ml-2 flex h-5 w-5 shrink-0 items-center justify-center text-xs font-semibold text-white', "aria-hidden": 'true', children: getCalendarInitials(calendar) })), editingId === calendar.id ? (u("input", { ref: editInputRef, type: 'text', value: editingName, onChange: e => setEditingName(e.target.value), onBlur: onRenameSave, onKeyDown: onRenameKeyDown, className: 'ml-2 h-5 min-w-0 flex-1 rounded bg-white px-0 py-0 text-sm text-gray-900 focus:outline-none dark:bg-slate-700 dark:text-gray-100', onClick: e => e.stopPropagation() })) : (u(preact.Fragment, { children: [u("span", { className: 'ml-2 flex-1 truncate pl-1 text-sm text-gray-700 group-hover:text-gray-900 dark:text-gray-200 dark:group-hover:text-white', onDblClick: () => onRenameStart(calendar), children: calendar.name || calendar.id }), ((_b = calendar.subscription) === null || _b === void 0 ? void 0 : _b.status) === 'error' && (u(core.AlertCircle, { width: 13, height: 13, className: 'ml-1 shrink-0 text-red-500', title: 'Failed to load subscription' })), calendar.subscription &&
59
+ calendar.subscription.status === 'ready' && (u(core.AudioLines, { width: 13, height: 13, className: 'ml-1 shrink-0 text-gray-400 dark:text-gray-500' }))] }))] }) }), isDropTarget && dropTarget.position === 'bottom' && (u("div", { className: 'pointer-events-none absolute right-0 bottom-0 left-0 z-10 h-0.5 bg-[var(--df-color-primary)]' }))] }, calendar.id));
61
60
  };
62
61
  const CalendarList = ({ calendars, onToggleVisibility, onReorder, onRename, onContextMenu, editingId, setEditingId, activeContextMenuCalendarId, isDraggable = true, isEditable = true, }) => {
63
62
  var _a;
@@ -281,7 +280,7 @@ const DeleteCalendarDialog = ({ calendarId, calendarName, calendars, step, onSte
281
280
  handleMergeSelect(calendar.id);
282
281
  }, children: [u("div", { className: 'mr-2 h-3 w-3 shrink-0 rounded-sm', style: {
283
282
  backgroundColor: calendar.colors.lineColor,
284
- } }), u("span", { className: 'whitespace-nowrap', children: calendar.name || calendar.id })] }, calendar.id))) }))] }), u("div", { className: 'flex gap-3', children: [u("button", { type: 'button', onClick: onCancel, disabled: isLoading, className: `${core.cancelButton} disabled:opacity-50`, children: t('cancel') }), u("button", { type: 'button', onClick: () => onStepChange('confirm_delete'), disabled: isLoading, className: 'rounded-md bg-destructive px-4 py-2 text-xs font-medium text-destructive-foreground hover:bg-destructive/90 disabled:opacity-50', children: t('delete') })] })] })] })) : (u(preact.Fragment, { children: [u("h2", { className: 'text-lg font-semibold text-gray-900 dark:text-white', children: t('confirmDeleteTitle', { calendarName }) }), u("p", { className: 'mt-3 text-sm text-gray-600 dark:text-gray-300', children: t('confirmDeleteMessage') }), u("div", { className: 'mt-6 flex justify-end gap-3', children: [u("button", { type: 'button', onClick: onCancel, disabled: isLoading, className: 'rounded-md border border-border bg-background px-3 py-2 text-xs font-medium text-gray-700 hover:bg-gray-100 disabled:opacity-50 dark:text-gray-300 dark:hover:bg-slate-700', children: t('cancel') }), u(core.LoadingButton, { type: 'button', onClick: handleConfirmDelete, loading: isLoading, className: 'rounded-md bg-destructive px-3 py-2 text-xs font-medium text-destructive-foreground hover:bg-destructive/90', children: t('delete') })] })] })) }) }), document.body);
283
+ } }), u("span", { className: 'whitespace-nowrap', children: calendar.name || calendar.id })] }, calendar.id))) }))] }), u("div", { className: 'flex gap-3', children: [u("button", { type: 'button', onClick: onCancel, disabled: isLoading, className: `${core.cancelButton} disabled:opacity-50`, children: t('cancel') }), u("button", { type: 'button', onClick: () => onStepChange('confirm_delete'), disabled: isLoading, className: 'df-fill-destructive df-hover-destructive rounded-md px-4 py-2 text-xs font-medium disabled:opacity-50', children: t('delete') })] })] })] })) : (u(preact.Fragment, { children: [u("h2", { className: 'text-lg font-semibold text-gray-900 dark:text-white', children: t('confirmDeleteTitle', { calendarName }) }), u("p", { className: 'mt-3 text-sm text-gray-600 dark:text-gray-300', children: t('confirmDeleteMessage') }), u("div", { className: 'mt-6 flex justify-end gap-3', children: [u("button", { type: 'button', onClick: onCancel, disabled: isLoading, className: 'rounded-md border border-border bg-background px-3 py-2 text-xs font-medium text-gray-700 hover:bg-gray-100 disabled:opacity-50 dark:text-gray-300 dark:hover:bg-slate-700', children: t('cancel') }), u(core.LoadingButton, { type: 'button', onClick: handleConfirmDelete, loading: isLoading, className: 'df-fill-destructive df-hover-destructive rounded-md px-3 py-2 text-xs font-medium', children: t('delete') })] })] })) }) }), document.body);
285
284
  };
286
285
 
287
286
  const NEW_CALENDAR_ID = 'new-calendar';
@@ -339,17 +338,17 @@ const ImportCalendarDialog = ({ calendars, filename, onConfirm, onCancel, }) =>
339
338
  const rect = (_a = triggerRef.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
340
339
  if (!rect)
341
340
  return null;
342
- return core.createPortal(u("div", { ref: dropdownRef, className: `fixed z-110 mt-1 max-h-60 origin-top overflow-y-auto rounded-md border border-gray-200 bg-white shadow-lg transition-all duration-200 dark:border-slate-700 dark:bg-slate-800 ${isOpen ? 'scale-100 opacity-100' : 'scale-95 opacity-0'}`, style: {
341
+ return core.createPortal(u("div", { ref: dropdownRef, className: `df-portal fixed z-110 mt-1 max-h-60 origin-top overflow-y-auto rounded-md border border-gray-200 bg-white shadow-lg transition-all duration-200 dark:border-slate-700 dark:bg-slate-800 ${isOpen ? 'scale-100 opacity-100' : 'scale-95 opacity-0'}`, style: {
343
342
  top: rect.bottom,
344
343
  left: rect.left,
345
344
  width: rect.width,
346
345
  overscrollBehavior: 'none',
347
- }, children: u("div", { className: 'py-1', children: [calendars.map(calendar => (u("div", { className: `flex cursor-pointer items-center px-3 py-2 hover:bg-gray-100 dark:hover:bg-slate-700 ${selectedCalendarId === calendar.id ? 'bg-primary/10' : ''}`, onClick: () => handleSelect(calendar.id), children: [u("div", { className: 'mr-3 h-3 w-3 shrink-0 rounded-sm', style: { backgroundColor: calendar.colors.lineColor } }), u("span", { className: `flex-1 truncate text-sm ${selectedCalendarId === calendar.id ? 'font-medium text-primary' : 'text-gray-700 dark:text-gray-200'}`, children: calendar.name || calendar.id }), selectedCalendarId === calendar.id && (u(core.Check, { className: 'ml-2 h-4 w-4 shrink-0 text-primary' }))] }, calendar.id))), u("div", { className: 'my-1 border-t border-gray-100 dark:border-slate-700' }), u("div", { className: `flex cursor-pointer items-center px-3 py-2 hover:bg-gray-100 dark:hover:bg-slate-700 ${isNewSelected ? 'bg-primary/10' : ''}`, onClick: () => handleSelect(NEW_CALENDAR_ID), children: [u("span", { className: `flex-1 truncate text-sm ${isNewSelected ? 'font-medium text-primary' : 'pl-6 text-gray-700 dark:text-gray-200'}`, children: [t('newCalendar') || 'New Calendar', ": ", filename] }), isNewSelected && (u(core.Check, { className: 'ml-2 h-4 w-4 shrink-0 text-primary' }))] })] }) }), document.body);
346
+ }, children: u("div", { className: 'py-1', children: [calendars.map(calendar => (u("div", { className: `flex cursor-pointer items-center px-3 py-2 hover:bg-gray-100 dark:hover:bg-slate-700 ${selectedCalendarId === calendar.id ? 'df-tint-primary' : ''}`, onClick: () => handleSelect(calendar.id), children: [u("div", { className: 'mr-3 h-3 w-3 shrink-0 rounded-sm', style: { backgroundColor: calendar.colors.lineColor } }), u("span", { className: `flex-1 truncate text-sm ${selectedCalendarId === calendar.id ? 'df-text-primary font-medium' : 'text-gray-700 dark:text-gray-200'}`, children: calendar.name || calendar.id }), selectedCalendarId === calendar.id && (u(core.Check, { className: 'df-text-primary ml-2 h-4 w-4 shrink-0' }))] }, calendar.id))), u("div", { className: 'my-1 border-t border-gray-100 dark:border-slate-700' }), u("div", { className: `flex cursor-pointer items-center px-3 py-2 hover:bg-gray-100 dark:hover:bg-slate-700 ${isNewSelected ? 'df-tint-primary' : ''}`, onClick: () => handleSelect(NEW_CALENDAR_ID), children: [u("span", { className: `flex-1 truncate text-sm ${isNewSelected ? 'df-text-primary font-medium' : 'pl-6 text-gray-700 dark:text-gray-200'}`, children: [t('newCalendar') || 'New Calendar', ": ", filename] }), isNewSelected && (u(core.Check, { className: 'df-text-primary ml-2 h-4 w-4 shrink-0' }))] })] }) }), document.body);
348
347
  };
349
348
  return (u("div", { className: 'df-portal fixed inset-0 z-100 flex items-center justify-center bg-black/50', children: u("div", { className: 'w-full max-w-md rounded-lg bg-white p-6 shadow-xl dark:bg-gray-900', children: [u("h2", { className: 'mb-4 text-lg font-semibold text-gray-900 dark:text-white', children: t('addSchedule') || 'Add Schedule' }), u("p", { className: 'mb-4 text-sm text-gray-600 dark:text-gray-300', children: t('importCalendarMessage') ||
350
349
  'This calendar contains new events. Please select a target calendar.' }), u("div", { className: 'relative', children: [u("button", { ref: triggerRef, type: 'button', disabled: isLoading, className: 'flex w-full items-center rounded-md border border-gray-300 px-3 py-2 shadow-sm transition-colors hover:bg-gray-50 disabled:opacity-50 dark:border-gray-600 dark:hover:bg-gray-800', onClick: () => setIsOpen(!isOpen), children: [!isNewSelected && selectedCalendar && (u("div", { className: 'mr-3 h-3 w-3 shrink-0 rounded-sm', style: { backgroundColor: selectedCalendar.colors.lineColor } })), u("span", { className: `flex-1 truncate text-left text-sm font-medium text-gray-700 dark:text-gray-200 ${isNewSelected ? 'pl-0' : ''}`, children: isNewSelected
351
350
  ? `${t('newCalendar')}: ${filename}`
352
- : (selectedCalendar === null || selectedCalendar === void 0 ? void 0 : selectedCalendar.name) || (selectedCalendar === null || selectedCalendar === void 0 ? void 0 : selectedCalendar.id) }), u(core.ChevronsUpDown, { className: 'ml-2 h-4 w-4 shrink-0 text-gray-400' })] }), renderDropdown()] }), u("div", { className: 'mt-8 flex justify-end gap-3', children: [u("button", { type: 'button', onClick: onCancel, disabled: isLoading, className: `${core.cancelButton} disabled:opacity-50`, children: t('cancel') || 'Cancel' }), u(core.LoadingButton, { type: 'button', onClick: handleConfirm, loading: isLoading, className: 'rounded-md bg-primary px-6 py-2 text-sm font-medium text-primary-foreground shadow-sm transition-colors hover:bg-primary/90', children: t('ok') || 'OK' })] })] }) }));
351
+ : (selectedCalendar === null || selectedCalendar === void 0 ? void 0 : selectedCalendar.name) || (selectedCalendar === null || selectedCalendar === void 0 ? void 0 : selectedCalendar.id) }), u(core.ChevronsUpDown, { className: 'ml-2 h-4 w-4 shrink-0 text-gray-400' })] }), renderDropdown()] }), u("div", { className: 'mt-8 flex justify-end gap-3', children: [u("button", { type: 'button', onClick: onCancel, disabled: isLoading, className: `${core.cancelButton} disabled:opacity-50`, children: t('cancel') || 'Cancel' }), u(core.LoadingButton, { type: 'button', onClick: handleConfirm, loading: isLoading, className: 'df-fill-primary df-hover-primary-solid rounded-md px-6 py-2 text-sm font-medium shadow-sm transition-colors', children: t('ok') || 'OK' })] })] }) }));
353
352
  };
354
353
 
355
354
  const SOURCE_SENTINEL = '\u0001S\u0001';
@@ -386,7 +385,7 @@ const MergeCalendarDialog = ({ sourceName, sourceColor, targetName, targetColor,
386
385
  setIsLoading(false);
387
386
  }
388
387
  });
389
- return (u("div", { className: 'df-portal fixed inset-0 z-[9999] flex items-center justify-center bg-black/50', children: u("div", { className: 'rounded-lg bg-white p-6 shadow-xl dark:bg-gray-800', children: [u("h2", { className: 'text-lg font-semibold text-gray-900 dark:text-white', children: t('mergeConfirmTitle', { sourceName, targetName }) }), u("div", { className: 'mt-3 space-y-1 text-sm text-gray-600 dark:text-gray-300', children: messageLines.map((line, i) => (u("p", { className: 'flex flex-wrap items-center gap-y-0.5', children: renderLine(line, source, target) }, i))) }), u("div", { className: 'mt-6 flex justify-end gap-3', children: [u("button", { type: 'button', onClick: onCancel, disabled: isLoading, className: `${core.cancelButton} disabled:opacity-50`, children: t('cancel') }), u(core.LoadingButton, { type: 'button', onClick: handleConfirm, loading: isLoading, className: 'rounded-md bg-destructive px-3 py-2 text-xs font-medium text-destructive-foreground hover:bg-destructive/90', children: t('merge') })] })] }) }));
388
+ return (u("div", { className: 'df-portal fixed inset-0 z-[9999] flex items-center justify-center bg-black/50', children: u("div", { className: 'rounded-lg bg-white p-6 shadow-xl dark:bg-gray-800', children: [u("h2", { className: 'text-lg font-semibold text-gray-900 dark:text-white', children: t('mergeConfirmTitle', { sourceName, targetName }) }), u("div", { className: 'mt-3 space-y-1 text-sm text-gray-600 dark:text-gray-300', children: messageLines.map((line, i) => (u("p", { className: 'flex flex-wrap items-center gap-y-0.5', children: renderLine(line, source, target) }, i))) }), u("div", { className: 'mt-6 flex justify-end gap-3', children: [u("button", { type: 'button', onClick: onCancel, disabled: isLoading, className: `${core.cancelButton} disabled:opacity-50`, children: t('cancel') }), u(core.LoadingButton, { type: 'button', onClick: handleConfirm, loading: isLoading, className: 'df-fill-destructive df-hover-destructive rounded-md px-3 py-2 text-xs font-medium', children: t('merge') })] })] }) }));
390
389
  };
391
390
 
392
391
  const stopPropagation = (e) => e.stopPropagation();
@@ -467,11 +466,11 @@ const SubscribeCalendarDialog = ({ onSubscribe, onCancel, }) => {
467
466
  if (e.key === 'Escape')
468
467
  onCancel();
469
468
  };
470
- return (u("div", { className: 'df-portal fixed inset-0 z-[9999] flex items-center justify-center bg-black/50', children: u("div", { className: 'w-full max-w-xl rounded-lg bg-white p-6 shadow-xl dark:bg-gray-800', children: [u("h2", { className: 'text-lg font-semibold text-gray-900 dark:text-white', children: t('subscribeCalendarTitle') }), u("div", { className: 'mt-4', children: [u("div", { className: 'flex items-center gap-3', children: [u("label", { className: 'shrink-0 text-sm font-medium text-gray-700 dark:text-gray-300', children: t('calendarUrl') }), u("input", { type: 'url', value: url, onInput: e => setUrl(e.target.value), onKeyDown: handleKeyDown, placeholder: t('calendarUrlPlaceholder'), disabled: loading, autoFocus: true, className: 'flex-1 rounded-md border border-gray-300 bg-white px-3 py-2 text-sm text-gray-900 placeholder-gray-400 focus:border-primary focus:ring-1 focus:ring-primary focus:outline-none disabled:opacity-50 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:placeholder-gray-400' })] }), error && (u("p", { className: 'mt-2 text-xs text-red-500 dark:text-red-400', children: error }))] }), u("div", { className: 'mt-6 flex justify-end gap-3', children: [u("button", { type: 'button', onClick: onCancel, disabled: loading, className: core.cancelButton, children: t('cancel') }), u("button", { type: 'button', onClick: handleSubmit, disabled: loading || !url.trim(), className: 'rounded-md bg-primary px-4 py-2 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:cursor-not-allowed disabled:opacity-50', children: loading ? t('fetchingCalendar') : t('subscribe') })] })] }) }));
469
+ return (u("div", { className: 'df-portal fixed inset-0 z-[9999] flex items-center justify-center bg-black/50', children: u("div", { className: 'w-full max-w-xl rounded-lg bg-white p-6 shadow-xl dark:bg-gray-800', children: [u("h2", { className: 'text-lg font-semibold text-gray-900 dark:text-white', children: t('subscribeCalendarTitle') }), u("div", { className: 'mt-4', children: [u("div", { className: 'flex items-center gap-3', children: [u("label", { className: 'shrink-0 text-sm font-medium text-gray-700 dark:text-gray-300', children: t('calendarUrl') }), u("input", { type: 'url', value: url, onInput: e => setUrl(e.target.value), onKeyDown: handleKeyDown, placeholder: t('calendarUrlPlaceholder'), disabled: loading, autoFocus: true, className: 'df-focus-ring flex-1 rounded-md border border-gray-300 bg-white px-3 py-2 text-sm text-gray-900 placeholder-gray-400 focus:ring-1 focus:outline-none disabled:opacity-50 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:placeholder-gray-400' })] }), error && (u("p", { className: 'mt-2 text-xs text-red-500 dark:text-red-400', children: error }))] }), u("div", { className: 'mt-6 flex justify-end gap-3', children: [u("button", { type: 'button', onClick: onCancel, disabled: loading, className: core.cancelButton, children: t('cancel') }), u("button", { type: 'button', onClick: handleSubmit, disabled: loading || !url.trim(), className: 'df-fill-primary df-hover-primary-solid rounded-md px-4 py-2 text-xs font-medium disabled:cursor-not-allowed disabled:opacity-50', children: loading ? t('fetchingCalendar') : t('subscribe') })] })] }) }));
471
470
  };
472
471
 
473
- const DefaultCalendarSidebar = ({ app, calendars, toggleCalendarVisibility, isCollapsed, setCollapsed, renderCalendarContextMenu, renderSidebarHeader, editingCalendarId: propEditingCalendarId, setEditingCalendarId: propSetEditingCalendarId, onCreateCalendar, onSubscribeCalendar, onLoadSubscription, }) => {
474
- var _a, _b;
472
+ const DefaultCalendarSidebar = ({ app, calendars, toggleCalendarVisibility, isCollapsed, setCollapsed, showEventDots, renderCalendarContextMenu, renderSidebarHeader, editingCalendarId: propEditingCalendarId, setEditingCalendarId: propSetEditingCalendarId, onCreateCalendar, onSubscribeCalendar, onLoadSubscription, }) => {
473
+ var _a, _b, _c;
475
474
  const { t } = core.useLocale();
476
475
  // Detect if custom color picker slot is provided
477
476
  const hasCustomPicker = app.state.overrides.includes('colorPicker');
@@ -800,10 +799,10 @@ const DefaultCalendarSidebar = ({ app, calendars, toggleCalendarVisibility, isCo
800
799
  ? handleContextMenu
801
800
  : () => {
802
801
  /* noop */
803
- }, editingId: editingCalendarId, setEditingId: setEditingCalendarId, activeContextMenuCalendarId: contextMenu === null || contextMenu === void 0 ? void 0 : contextMenu.calendarId, isDraggable: isDraggable, isEditable: isEditable }), u("div", { className: 'border-t border-gray-200 dark:border-slate-800', children: u(core.MiniCalendar, { visibleMonth: app.getVisibleMonth(), currentDate: app.getCurrentDate(), showHeader: true, onMonthChange: handleMonthChange, onDateSelect: date => app.setCurrentDate(date) }) })] })), isEditable && contextMenu && (u(core.ContextMenu, { ref: contextMenuRef, x: contextMenu.x, y: contextMenu.y, onClose: handleCloseContextMenu, className: 'w-64 p-2', children: u(core.ContentSlot, { generatorName: 'calendarContextMenu', generatorArgs: {
802
+ }, editingId: editingCalendarId, setEditingId: setEditingCalendarId, activeContextMenuCalendarId: contextMenu === null || contextMenu === void 0 ? void 0 : contextMenu.calendarId, isDraggable: isDraggable, isEditable: isEditable }), u("div", { className: 'border-t border-gray-200 dark:border-slate-800', children: u(core.MiniCalendar, { visibleMonth: app.getVisibleMonth(), currentDate: app.getCurrentDate(), showHeader: true, onMonthChange: handleMonthChange, onDateSelect: date => app.setCurrentDate(date), events: app.getEvents(), showEventDots: showEventDots, calendarRegistry: app.getCalendarRegistry(), timeZone: ((_b = app.getViewConfig(app.state.currentView)) === null || _b === void 0 ? void 0 : _b.secondaryTimeZone) || undefined }) })] })), contextMenu && app.canMutateFromUI(contextMenu.calendarId) && (u(core.ContextMenu, { ref: contextMenuRef, x: contextMenu.x, y: contextMenu.y, onClose: handleCloseContextMenu, className: 'w-64 p-2', children: u(core.ContentSlot, { generatorName: 'calendarContextMenu', generatorArgs: {
804
803
  calendar: calendars.find(c => c.id === contextMenu.calendarId),
805
804
  onClose: handleCloseContextMenu,
806
- }, defaultContent: renderCalendarContextMenu ? (renderCalendarContextMenu(calendars.find(c => c.id === contextMenu.calendarId), handleCloseContextMenu)) : (u(preact.Fragment, { children: [u(core.ContextMenuLabel, { children: t('calendarOptions') }), u(MergeMenuItem, { calendars: calendars, currentCalendarId: contextMenu.calendarId, onMergeSelect: handleMergeSelect }), u(core.ContextMenuItem, { onClick: handleDeleteCalendar, children: t('delete') }), u(core.ContextMenuItem, { onClick: handleExportCalendar, children: t('exportCalendar') || 'Export Calendar' }), u(core.ContextMenuSeparator, {}), u(core.ContextMenuColorPicker, { selectedColor: (_b = calendars.find(c => c.id === contextMenu.calendarId)) === null || _b === void 0 ? void 0 : _b.colors.lineColor, onSelect: handleColorSelect, onCustomColor: handleCustomColor })] })) }) })), isEditable &&
805
+ }, defaultContent: renderCalendarContextMenu ? (renderCalendarContextMenu(calendars.find(c => c.id === contextMenu.calendarId), handleCloseContextMenu)) : (u(preact.Fragment, { children: [u(core.ContextMenuLabel, { children: t('calendarOptions') }), u(MergeMenuItem, { calendars: calendars, currentCalendarId: contextMenu.calendarId, onMergeSelect: handleMergeSelect }), u(core.ContextMenuItem, { onClick: handleDeleteCalendar, children: t('delete') }), u(core.ContextMenuItem, { onClick: handleExportCalendar, children: t('exportCalendar') || 'Export Calendar' }), u(core.ContextMenuSeparator, {}), u(core.ContextMenuColorPicker, { selectedColor: (_c = calendars.find(c => c.id === contextMenu.calendarId)) === null || _c === void 0 ? void 0 : _c.colors.lineColor, onSelect: handleColorSelect, onCustomColor: handleCustomColor })] })) }) })), isEditable &&
807
806
  sidebarContextMenu &&
808
807
  core.createPortal(u(core.ContextMenu, { x: sidebarContextMenu.x, y: sidebarContextMenu.y, onClose: handleCloseSidebarContextMenu, className: 'w-max p-2', children: [u(core.ContextMenuItem, { onClick: () => {
809
808
  onCreateCalendar === null || onCreateCalendar === void 0 ? void 0 : onCreateCalendar();
@@ -943,6 +942,7 @@ function createSidebarPlugin(config = {}) {
943
942
  toggleAll: handleToggleAllCalendars,
944
943
  isCollapsed,
945
944
  setCollapsed: setIsCollapsed,
945
+ showEventDots: config.showEventDots,
946
946
  renderCalendarContextMenu: config.renderCalendarContextMenu,
947
947
  renderSidebarHeader: config.renderSidebarHeader,
948
948
  createCalendarMode: config.createCalendarMode,
@@ -1,4 +1,4 @@
1
1
  import { JSX } from 'preact';
2
2
  import type { CalendarSidebarRenderProps } from './plugin';
3
- declare const DefaultCalendarSidebar: ({ app, calendars, toggleCalendarVisibility, isCollapsed, setCollapsed, renderCalendarContextMenu, renderSidebarHeader, editingCalendarId: propEditingCalendarId, setEditingCalendarId: propSetEditingCalendarId, onCreateCalendar, onSubscribeCalendar, onLoadSubscription, }: CalendarSidebarRenderProps) => JSX.Element;
3
+ declare const DefaultCalendarSidebar: ({ app, calendars, toggleCalendarVisibility, isCollapsed, setCollapsed, showEventDots, renderCalendarContextMenu, renderSidebarHeader, editingCalendarId: propEditingCalendarId, setEditingCalendarId: propSetEditingCalendarId, onCreateCalendar, onSubscribeCalendar, onLoadSubscription, }: CalendarSidebarRenderProps) => JSX.Element;
4
4
  export default DefaultCalendarSidebar;
@@ -7,6 +7,7 @@ export interface CalendarSidebarRenderProps {
7
7
  toggleAll: (visible: boolean) => void;
8
8
  isCollapsed: boolean;
9
9
  setCollapsed: (collapsed: boolean) => void;
10
+ showEventDots?: boolean;
10
11
  renderCalendarContextMenu?: (calendar: CalendarType, onClose: () => void) => TNode;
11
12
  renderSidebarHeader?: (args: SidebarHeaderSlotArgs) => TNode;
12
13
  createCalendarMode?: 'inline' | 'modal';
@@ -21,6 +22,7 @@ export interface SidebarPluginConfig {
21
22
  width?: number | string;
22
23
  miniWidth?: string;
23
24
  initialCollapsed?: boolean;
25
+ showEventDots?: boolean;
24
26
  createCalendarMode?: 'inline' | 'modal';
25
27
  render?: (props: CalendarSidebarRenderProps) => TNode;
26
28
  renderCalendarContextMenu?: (calendar: CalendarType, onClose: () => void) => TNode;
@@ -28,6 +30,5 @@ export interface SidebarPluginConfig {
28
30
  renderCreateCalendarDialog?: (props: CreateCalendarDialogProps) => TNode;
29
31
  onSubscribeCalendar?: (calendar: CalendarType, events: Event[]) => Promise<void>;
30
32
  onLoadSubscription?: (calendar: CalendarType) => Promise<void>;
31
- [key: string]: unknown;
32
33
  }
33
34
  export declare function createSidebarPlugin(config?: SidebarPluginConfig): CalendarPlugin;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dayflow/plugin-sidebar",
3
- "version": "1.2.5",
3
+ "version": "1.3.0",
4
4
  "description": "Sidebar plugin for DayFlow calendar",
5
5
  "keywords": [
6
6
  "calendar",
@@ -37,10 +37,10 @@
37
37
  "rollup-plugin-dts": "^6.3.0",
38
38
  "temporal-polyfill": "^0.3.0",
39
39
  "typescript": "^5.9.3",
40
- "@dayflow/core": "3.3.5"
40
+ "@dayflow/core": "3.4.0"
41
41
  },
42
42
  "peerDependencies": {
43
- "@dayflow/core": "3.3.5"
43
+ "@dayflow/core": "3.4.0"
44
44
  },
45
45
  "scripts": {
46
46
  "build": "tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json && rollup -c",