@tasknotes/calendar 0.1.7 → 0.1.10

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/esm/index.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  TIMELINE_UNIT_DAYS,
8
8
  defaultOptions,
9
9
  localeFirstDay
10
- } from "./chunk-EDRCVOY7.js";
10
+ } from "./chunk-5PHSJK36.js";
11
11
  import {
12
12
  DAY_MS,
13
13
  ItemStore,
@@ -91,6 +91,8 @@ var BASES_CALENDAR_DEFAULTS = {
91
91
  slotDuration: "00:30:00",
92
92
  snapDuration: "00:30:00",
93
93
  scrollTime: "08:00:00",
94
+ slotHeight: 24,
95
+ pinchZoom: true,
94
96
  nowIndicator: true,
95
97
  showTimeGrid: true,
96
98
  selectMirror: true,
@@ -155,6 +157,8 @@ function basesLayoutOptions(s, context = {}) {
155
157
  slotDuration,
156
158
  snapDuration: time("snapDuration") ?? slotDuration,
157
159
  scrollTime: time("scrollTime", 48) ?? d.scrollTime,
160
+ slotHeight: clamp(Math.round(num(s.slotHeight, d.slotHeight)), 5, 96),
161
+ pinchZoom: pick("pinchZoom") !== false,
158
162
  nowIndicator: pick("nowIndicator") !== false,
159
163
  timeGrid: showTimeGrid,
160
164
  selectMirror: pick("selectMirror") !== false,
package/dist/esm/react.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Calendar
3
- } from "./chunk-EDRCVOY7.js";
3
+ } from "./chunk-5PHSJK36.js";
4
4
  import "./chunk-66A6EMCU.js";
5
5
 
6
6
  // src/react/index.tsx
@@ -25,6 +25,7 @@ export interface CalendarItem<D = unknown> {
25
25
  backgroundColor?: string;
26
26
  borderColor?: string;
27
27
  textColor?: string;
28
+ timeDisplay?: "start" | "range";
28
29
  className?: string | string[];
29
30
  /** Host-managed temporary placement: inert, mirror-styled and never hidden by event limits. */
30
31
  preview?: boolean;
@@ -25,6 +25,7 @@ export interface CalendarItem<D = unknown> {
25
25
  backgroundColor?: string;
26
26
  borderColor?: string;
27
27
  textColor?: string;
28
+ timeDisplay?: "start" | "range";
28
29
  className?: string | string[];
29
30
  /** Host-managed temporary placement: inert, mirror-styled and never hidden by event limits. */
30
31
  preview?: boolean;
@@ -37,6 +37,13 @@ export declare class Calendar<D = unknown> implements ViewContext<D> {
37
37
  scroll: number;
38
38
  };
39
39
  draggingId: string | null;
40
+ private listDragPreview;
41
+ private dragSources;
42
+ private dragWidth;
43
+ private dragScrollFrame;
44
+ private readonly dragScrollOrigins;
45
+ private readonly dragScrollEdges;
46
+ private readonly itemWriteStates;
40
47
  dragRow: {
41
48
  id: string;
42
49
  rowId: string;
@@ -44,6 +51,7 @@ export declare class Calendar<D = unknown> implements ViewContext<D> {
44
51
  strip: DateStrip<D> | null;
45
52
  private stripSize;
46
53
  private rebuilding;
54
+ private pinch;
47
55
  private readonly toolbarEl;
48
56
  private readonly viewHost;
49
57
  private current;
@@ -53,6 +61,7 @@ export declare class Calendar<D = unknown> implements ViewContext<D> {
53
61
  private session;
54
62
  private selection;
55
63
  private suppressClick;
64
+ private cancelledPointerId;
56
65
  private selectedIds;
57
66
  private popover;
58
67
  private timer;
@@ -136,7 +145,7 @@ export declare class Calendar<D = unknown> implements ViewContext<D> {
136
145
  suppressNextClick(): void;
137
146
  dayArg(day: Day): DayArg;
138
147
  dayClasses(day: Day): string[];
139
- isEditable(n: NormalizedItem<D>, what: "start" | "duration"): boolean;
148
+ isEditable(n: NormalizedItem<D>, what: "start" | "duration", presentation?: boolean): boolean;
140
149
  navLink(day: Day, label: Node | string, cls: string): HTMLElement;
141
150
  navigate(day: Day, jsEvent: MouseEvent | KeyboardEvent, view?: "day" | "month"): void;
142
151
  createItemEl(meta: ElMeta<D>): HTMLElement;
@@ -197,13 +206,20 @@ export declare class Calendar<D = unknown> implements ViewContext<D> {
197
206
  private readonly onDocPointerDown;
198
207
  private readonly onPointerDown;
199
208
  private activate;
209
+ private startDragScroll;
210
+ private readonly onTouchStart;
200
211
  private readonly onTouchMove;
212
+ private readonly onTouchEnd;
213
+ /** Rescales the grid, keeping the anchored time under the fingers. */
214
+ private pinchTo;
215
+ private endPinch;
201
216
  private readonly onPointerMove;
202
217
  private readonly onPointerUp;
203
218
  private readonly onPointerCancel;
204
219
  private readonly onDocKeyDown;
205
220
  /** Proposal for the current pointer position. */
206
221
  private track;
222
+ private invalidateProposal;
207
223
  private trackExternal;
208
224
  private externalItem;
209
225
  private timelineSnap;
@@ -222,6 +238,7 @@ export declare class Calendar<D = unknown> implements ViewContext<D> {
222
238
  /** Ends the current pointer session, committing unless `cancel`. */
223
239
  private endSession;
224
240
  private commit;
241
+ private applyItemWriteState;
225
242
  /** Runs in the capture phase so the click ending a drag never reaches content inside the calendar, React portals included. */
226
243
  private readonly onClickCapture;
227
244
  private readonly onClick;
@@ -37,6 +37,13 @@ export declare class Calendar<D = unknown> implements ViewContext<D> {
37
37
  scroll: number;
38
38
  };
39
39
  draggingId: string | null;
40
+ private listDragPreview;
41
+ private dragSources;
42
+ private dragWidth;
43
+ private dragScrollFrame;
44
+ private readonly dragScrollOrigins;
45
+ private readonly dragScrollEdges;
46
+ private readonly itemWriteStates;
40
47
  dragRow: {
41
48
  id: string;
42
49
  rowId: string;
@@ -44,6 +51,7 @@ export declare class Calendar<D = unknown> implements ViewContext<D> {
44
51
  strip: DateStrip<D> | null;
45
52
  private stripSize;
46
53
  private rebuilding;
54
+ private pinch;
47
55
  private readonly toolbarEl;
48
56
  private readonly viewHost;
49
57
  private current;
@@ -53,6 +61,7 @@ export declare class Calendar<D = unknown> implements ViewContext<D> {
53
61
  private session;
54
62
  private selection;
55
63
  private suppressClick;
64
+ private cancelledPointerId;
56
65
  private selectedIds;
57
66
  private popover;
58
67
  private timer;
@@ -136,7 +145,7 @@ export declare class Calendar<D = unknown> implements ViewContext<D> {
136
145
  suppressNextClick(): void;
137
146
  dayArg(day: Day): DayArg;
138
147
  dayClasses(day: Day): string[];
139
- isEditable(n: NormalizedItem<D>, what: "start" | "duration"): boolean;
148
+ isEditable(n: NormalizedItem<D>, what: "start" | "duration", presentation?: boolean): boolean;
140
149
  navLink(day: Day, label: Node | string, cls: string): HTMLElement;
141
150
  navigate(day: Day, jsEvent: MouseEvent | KeyboardEvent, view?: "day" | "month"): void;
142
151
  createItemEl(meta: ElMeta<D>): HTMLElement;
@@ -197,13 +206,20 @@ export declare class Calendar<D = unknown> implements ViewContext<D> {
197
206
  private readonly onDocPointerDown;
198
207
  private readonly onPointerDown;
199
208
  private activate;
209
+ private startDragScroll;
210
+ private readonly onTouchStart;
200
211
  private readonly onTouchMove;
212
+ private readonly onTouchEnd;
213
+ /** Rescales the grid, keeping the anchored time under the fingers. */
214
+ private pinchTo;
215
+ private endPinch;
201
216
  private readonly onPointerMove;
202
217
  private readonly onPointerUp;
203
218
  private readonly onPointerCancel;
204
219
  private readonly onDocKeyDown;
205
220
  /** Proposal for the current pointer position. */
206
221
  private track;
222
+ private invalidateProposal;
207
223
  private trackExternal;
208
224
  private externalItem;
209
225
  private timelineSnap;
@@ -222,6 +238,7 @@ export declare class Calendar<D = unknown> implements ViewContext<D> {
222
238
  /** Ends the current pointer session, committing unless `cancel`. */
223
239
  private endSession;
224
240
  private commit;
241
+ private applyItemWriteState;
225
242
  /** Runs in the capture phase so the click ending a drag never reaches content inside the calendar, React portals included. */
226
243
  private readonly onClickCapture;
227
244
  private readonly onClick;
@@ -1,10 +1,11 @@
1
1
  import { type Day } from "../core/date.cjs";
2
2
  /** Locale-aware labels. Formatting happens on UTC dates built from civil days, so zones never shift them. */
3
3
  export declare class Formatter {
4
+ private readonly formatTime?;
4
5
  private readonly cache;
5
6
  readonly locale: string | undefined;
6
7
  readonly hour12: boolean;
7
- constructor(locale: string | undefined, hour12: boolean | undefined);
8
+ constructor(locale: string | undefined, hour12: boolean | undefined, formatTime?: ((minute: number) => string) | undefined);
8
9
  private fmt;
9
10
  private d;
10
11
  weekdayShort(day: Day): string;
@@ -1,10 +1,11 @@
1
1
  import { type Day } from "../core/date.js";
2
2
  /** Locale-aware labels. Formatting happens on UTC dates built from civil days, so zones never shift them. */
3
3
  export declare class Formatter {
4
+ private readonly formatTime?;
4
5
  private readonly cache;
5
6
  readonly locale: string | undefined;
6
7
  readonly hour12: boolean;
7
- constructor(locale: string | undefined, hour12: boolean | undefined);
8
+ constructor(locale: string | undefined, hour12: boolean | undefined, formatTime?: ((minute: number) => string) | undefined);
8
9
  private fmt;
9
10
  private d;
10
11
  weekdayShort(day: Day): string;
@@ -16,7 +16,7 @@ export interface ViewInfo {
16
16
  title: string;
17
17
  /**
18
18
  * The days whose items the calendar can show: `range`, extended to the
19
- * end of the days a date strip is showing so their dots are right. Load
19
+ * full window of days a date strip is showing so their dots are right. Load
20
20
  * items for this range; `onRangeChange` fires when it changes too.
21
21
  */
22
22
  dataRange: DateRange;
@@ -332,7 +332,7 @@ export interface CalendarOptions<D = unknown> {
332
332
  * the tap target: dots ignore the pointer and are hidden from assistive
333
333
  * technology, and the cell is labelled with its item count.
334
334
  */
335
- monthDisplay: "full" | "dots";
335
+ monthDisplay: "full" | "dots" | "chips";
336
336
  /** "local" or an IANA name. */
337
337
  timeZone: string;
338
338
  locale: string | undefined;
@@ -340,6 +340,7 @@ export interface CalendarOptions<D = unknown> {
340
340
  firstDay: number | undefined;
341
341
  /** undefined = locale default. */
342
342
  hour12: boolean | undefined;
343
+ formatTime?: (minute: number) => string;
343
344
  weekNumbers: boolean;
344
345
  weekends: boolean;
345
346
  hiddenDays: number[];
@@ -356,11 +357,14 @@ export interface CalendarOptions<D = unknown> {
356
357
  scrollTime: string | number;
357
358
  /** Pixel height of one slot. */
358
359
  slotHeight: number;
360
+ /** A two-finger pinch on a time grid rescales `slotHeight`. False leaves the pinch to the browser. */
361
+ pinchZoom: boolean;
359
362
  /** Stretch slots to fill the available height ("fill" mode only). */
360
363
  expandRows: boolean;
361
364
  nowIndicator: boolean;
362
365
  selectMirror: boolean;
363
366
  slotEventOverlap: boolean;
367
+ overlapStackThreshold?: number;
364
368
  /** Minimum item height in px in time grids. */
365
369
  eventMinHeight: number;
366
370
  /** Max side-by-side items in a time-grid cluster before "+N". 0 = unlimited. */
@@ -392,6 +396,8 @@ export interface CalendarOptions<D = unknown> {
392
396
  selected: string | readonly string[] | null;
393
397
  onRangeChange?: (view: ViewInfo) => void;
394
398
  onViewChange?: (view: ViewInfo) => void;
399
+ /** A pinch settled on a new `slotHeight`, whole pixels. Store it to keep the scale across reloads. */
400
+ onSlotHeightChange?: (slotHeight: number) => void;
395
401
  onItemClick?: (arg: ItemPointerArg<D>) => void;
396
402
  onItemDoubleClick?: (arg: ItemPointerArg<D>) => void;
397
403
  onItemContextMenu?: (arg: ItemPointerArg<D>) => void;
@@ -16,7 +16,7 @@ export interface ViewInfo {
16
16
  title: string;
17
17
  /**
18
18
  * The days whose items the calendar can show: `range`, extended to the
19
- * end of the days a date strip is showing so their dots are right. Load
19
+ * full window of days a date strip is showing so their dots are right. Load
20
20
  * items for this range; `onRangeChange` fires when it changes too.
21
21
  */
22
22
  dataRange: DateRange;
@@ -332,7 +332,7 @@ export interface CalendarOptions<D = unknown> {
332
332
  * the tap target: dots ignore the pointer and are hidden from assistive
333
333
  * technology, and the cell is labelled with its item count.
334
334
  */
335
- monthDisplay: "full" | "dots";
335
+ monthDisplay: "full" | "dots" | "chips";
336
336
  /** "local" or an IANA name. */
337
337
  timeZone: string;
338
338
  locale: string | undefined;
@@ -340,6 +340,7 @@ export interface CalendarOptions<D = unknown> {
340
340
  firstDay: number | undefined;
341
341
  /** undefined = locale default. */
342
342
  hour12: boolean | undefined;
343
+ formatTime?: (minute: number) => string;
343
344
  weekNumbers: boolean;
344
345
  weekends: boolean;
345
346
  hiddenDays: number[];
@@ -356,11 +357,14 @@ export interface CalendarOptions<D = unknown> {
356
357
  scrollTime: string | number;
357
358
  /** Pixel height of one slot. */
358
359
  slotHeight: number;
360
+ /** A two-finger pinch on a time grid rescales `slotHeight`. False leaves the pinch to the browser. */
361
+ pinchZoom: boolean;
359
362
  /** Stretch slots to fill the available height ("fill" mode only). */
360
363
  expandRows: boolean;
361
364
  nowIndicator: boolean;
362
365
  selectMirror: boolean;
363
366
  slotEventOverlap: boolean;
367
+ overlapStackThreshold?: number;
364
368
  /** Minimum item height in px in time grids. */
365
369
  eventMinHeight: number;
366
370
  /** Max side-by-side items in a time-grid cluster before "+N". 0 = unlimited. */
@@ -392,6 +396,8 @@ export interface CalendarOptions<D = unknown> {
392
396
  selected: string | readonly string[] | null;
393
397
  onRangeChange?: (view: ViewInfo) => void;
394
398
  onViewChange?: (view: ViewInfo) => void;
399
+ /** A pinch settled on a new `slotHeight`, whole pixels. Store it to keep the scale across reloads. */
400
+ onSlotHeightChange?: (slotHeight: number) => void;
395
401
  onItemClick?: (arg: ItemPointerArg<D>) => void;
396
402
  onItemDoubleClick?: (arg: ItemPointerArg<D>) => void;
397
403
  onItemContextMenu?: (arg: ItemPointerArg<D>) => void;
@@ -13,11 +13,13 @@ export declare class DayGridView<D> implements View {
13
13
  private morePx;
14
14
  private topPx;
15
15
  private lastHeights;
16
- private readonly dotsMode;
16
+ private dotsMode;
17
+ private dragPreviews;
17
18
  constructor(ctx: ViewContext<D>);
18
19
  private daysPerWeek;
19
20
  private sizeKey;
20
21
  render(_change: StoreChange | null): void;
22
+ private clearDragPreviews;
21
23
  /** Height of a "+N more" link as the host styles it (`--tnc-more-h`, or a taller min-height). */
22
24
  private measureMore;
23
25
  private limitFor;
@@ -13,11 +13,13 @@ export declare class DayGridView<D> implements View {
13
13
  private morePx;
14
14
  private topPx;
15
15
  private lastHeights;
16
- private readonly dotsMode;
16
+ private dotsMode;
17
+ private dragPreviews;
17
18
  constructor(ctx: ViewContext<D>);
18
19
  private daysPerWeek;
19
20
  private sizeKey;
20
21
  render(_change: StoreChange | null): void;
22
+ private clearDragPreviews;
21
23
  /** Height of a "+N more" link as the host styles it (`--tnc-more-h`, or a taller min-height). */
22
24
  private measureMore;
23
25
  private limitFor;
@@ -22,6 +22,7 @@ export declare class ListView<D> implements View {
22
22
  private frame;
23
23
  /** A picked day stays marked until the list is scrolled by hand. */
24
24
  private pinned;
25
+ private pinnedTop;
25
26
  constructor(ctx: ViewContext<D>);
26
27
  private itemsOn;
27
28
  render(_change: StoreChange | null): void;
@@ -22,6 +22,7 @@ export declare class ListView<D> implements View {
22
22
  private frame;
23
23
  /** A picked day stays marked until the list is scrolled by hand. */
24
24
  private pinned;
25
+ private pinnedTop;
25
26
  constructor(ctx: ViewContext<D>);
26
27
  private itemsOn;
27
28
  render(_change: StoreChange | null): void;
@@ -12,6 +12,7 @@ export declare class DateStrip<D> {
12
12
  private readonly pick;
13
13
  /** Called when the days on show change, so their items can be loaded. */
14
14
  private readonly onShown;
15
+ private readonly onPage?;
15
16
  readonly el: HTMLElement;
16
17
  private readonly title;
17
18
  private readonly dows;
@@ -31,7 +32,7 @@ export declare class DateStrip<D> {
31
32
  expanded: boolean;
32
33
  constructor(ctx: ViewContext<D>, pick: (day: Day, ev: MouseEvent | KeyboardEvent) => void, focus: Day,
33
34
  /** Called when the days on show change, so their items can be loaded. */
34
- onShown: () => void);
35
+ onShown: () => void, onPage?: ((day: Day) => void) | undefined);
35
36
  /** The list scrolled or the grid moved: mark the day and keep it in view. */
36
37
  setFocus(day: Day, range?: {
37
38
  start: Day;
@@ -55,6 +56,7 @@ export declare class DateStrip<D> {
55
56
  private readonly onClick;
56
57
  private readonly onKeyDown;
57
58
  private readonly onPointerDown;
59
+ private readonly ownTouch;
58
60
  private readonly onPointerUp;
59
61
  private readonly onPointerCancel;
60
62
  /** A swipe that ends on a day is not a pick. */
@@ -12,6 +12,7 @@ export declare class DateStrip<D> {
12
12
  private readonly pick;
13
13
  /** Called when the days on show change, so their items can be loaded. */
14
14
  private readonly onShown;
15
+ private readonly onPage?;
15
16
  readonly el: HTMLElement;
16
17
  private readonly title;
17
18
  private readonly dows;
@@ -31,7 +32,7 @@ export declare class DateStrip<D> {
31
32
  expanded: boolean;
32
33
  constructor(ctx: ViewContext<D>, pick: (day: Day, ev: MouseEvent | KeyboardEvent) => void, focus: Day,
33
34
  /** Called when the days on show change, so their items can be loaded. */
34
- onShown: () => void);
35
+ onShown: () => void, onPage?: ((day: Day) => void) | undefined);
35
36
  /** The list scrolled or the grid moved: mark the day and keep it in view. */
36
37
  setFocus(day: Day, range?: {
37
38
  start: Day;
@@ -55,6 +56,7 @@ export declare class DateStrip<D> {
55
56
  private readonly onClick;
56
57
  private readonly onKeyDown;
57
58
  private readonly onPointerDown;
59
+ private readonly ownTouch;
58
60
  private readonly onPointerUp;
59
61
  private readonly onPointerCancel;
60
62
  /** A swipe that ends on a day is not a pick. */
@@ -26,7 +26,10 @@ export declare class TimeGridView<D> implements View {
26
26
  private get minutes();
27
27
  private build;
28
28
  private buildGutter;
29
- private applyScale;
29
+ /** Slot height as drawn, which `expandRows` can stretch past the option. */
30
+ get drawnSlotHeight(): number;
31
+ /** Applies `slotHeight`. Items are placed in percentages, so they follow without a render. */
32
+ applyScale(): void;
30
33
  /** In fill mode with expandRows, stretches slots so the grid fills the height. */
31
34
  private fitRows;
32
35
  render(change: StoreChange | null): void;
@@ -26,7 +26,10 @@ export declare class TimeGridView<D> implements View {
26
26
  private get minutes();
27
27
  private build;
28
28
  private buildGutter;
29
- private applyScale;
29
+ /** Slot height as drawn, which `expandRows` can stretch past the option. */
30
+ get drawnSlotHeight(): number;
31
+ /** Applies `slotHeight`. Items are placed in percentages, so they follow without a render. */
32
+ applyScale(): void;
30
33
  /** In fill mode with expandRows, stretches slots so the grid fills the height. */
31
34
  private fitRows;
32
35
  render(change: StoreChange | null): void;
@@ -21,6 +21,7 @@ export declare class YearView<D> implements View {
21
21
  top: number;
22
22
  left: number;
23
23
  }): void;
24
+ revealDay(day: Day): void;
24
25
  elementsFor(_id: string): HTMLElement[];
25
26
  destroy(): void;
26
27
  }
@@ -21,6 +21,7 @@ export declare class YearView<D> implements View {
21
21
  top: number;
22
22
  left: number;
23
23
  }): void;
24
+ revealDay(day: Day): void;
24
25
  elementsFor(_id: string): HTMLElement[];
25
26
  destroy(): void;
26
27
  }
@@ -24,6 +24,8 @@ export interface BasesCalendarLayout {
24
24
  slotDuration?: string | null;
25
25
  snapDuration?: string | null;
26
26
  scrollTime?: string | null;
27
+ slotHeight?: number | null;
28
+ pinchZoom?: boolean | null;
27
29
  nowIndicator?: boolean | null;
28
30
  showTimeGrid?: boolean | null;
29
31
  selectMirror?: boolean | null;
@@ -24,6 +24,8 @@ export interface BasesCalendarLayout {
24
24
  slotDuration?: string | null;
25
25
  snapDuration?: string | null;
26
26
  scrollTime?: string | null;
27
+ slotHeight?: number | null;
28
+ pinchZoom?: boolean | null;
27
29
  nowIndicator?: boolean | null;
28
30
  showTimeGrid?: boolean | null;
29
31
  selectMirror?: boolean | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tasknotes/calendar",
3
- "version": "0.1.7",
3
+ "version": "0.1.10",
4
4
  "description": "Task-native calendar engine for TaskNotes: incremental layout, time grid, month, list, year and timeline views.",
5
5
  "license": "MIT",
6
6
  "type": "module",