@ziix/calendar 0.1.1 → 0.1.3

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
@@ -2,6 +2,13 @@ import { Dayjs } from 'dayjs';
2
2
 
3
3
  export declare function buildAxis(slot?: SlotConfig): SlotAxis;
4
4
 
5
+ /** A business-hours window: which weekdays (0 = Sunday) and the open time range. */
6
+ declare interface BusinessHours {
7
+ daysOfWeek?: number[];
8
+ startTime?: string;
9
+ endTime?: string;
10
+ }
11
+
5
12
  /**
6
13
  * The public, framework-agnostic calendar. Construct with a host element and
7
14
  * options, then `render()`. Mirrors the imperative surface hosts rely on
@@ -35,6 +42,8 @@ export declare class Calendar {
35
42
  activeStart: Dayjs;
36
43
  activeEnd: Dayjs;
37
44
  };
45
+ /** Default business hours (normalised to an array). */
46
+ get businessHours(): BusinessHours[];
38
47
  private isDayClosed;
39
48
  get editable(): boolean;
40
49
  get selectable(): boolean;
@@ -57,6 +66,14 @@ export declare class Calendar {
57
66
  getEvents(): CalEvent[];
58
67
  getResources(): CalResource[];
59
68
  getResourceById(id: string | number): ResourceHandle | null;
69
+ private resourceRenderScheduled;
70
+ /**
71
+ * Coalesce resource-area re-renders: many setExtendedProp calls in a row (e.g.
72
+ * pushing work hours / punch-ins for every resource) collapse into a single
73
+ * cell update on the next microtask, and event bars are never rebuilt — so the
74
+ * timeline doesn't flicker.
75
+ */
76
+ private scheduleResourceRender;
60
77
  private resourceHandle;
61
78
  private handle;
62
79
  /** Build the inner body of an event, honouring the `renderEvent` hook. */
@@ -100,6 +117,11 @@ export declare interface CalendarOptions {
100
117
  * the current date (re-evaluated on navigation).
101
118
  */
102
119
  dayClosed?: boolean | ((date: Dayjs) => boolean);
120
+ /**
121
+ * Default open hours used to shade non-business time when a resource has none
122
+ * of its own. Resource-level `businessHours` take precedence.
123
+ */
124
+ businessHours?: BusinessHours | BusinessHours[];
103
125
  editable?: boolean;
104
126
  selectable?: boolean;
105
127
  height?: number | string;
@@ -157,6 +179,8 @@ export declare interface CalResource {
157
179
  title: string;
158
180
  group: string | null;
159
181
  order: number;
182
+ /** Open hours for this resource (empty = none defined). */
183
+ businessHours: BusinessHours[];
160
184
  /** Arbitrary domain data, mutable via the resource handle's setExtendedProp. */
161
185
  extendedProps: Record<string, unknown>;
162
186
  raw: ResourceInput;
@@ -346,6 +370,8 @@ export declare interface ResourceInput {
346
370
  title?: string;
347
371
  group?: string;
348
372
  order?: number;
373
+ /** Open hours for this resource; time outside these is shaded non-business. */
374
+ businessHours?: BusinessHours[];
349
375
  /** Arbitrary domain data (e.g. workHours, punchinout, badges). */
350
376
  extendedProps?: Record<string, unknown>;
351
377
  [key: string]: unknown;
@@ -1 +1 @@
1
- .zc{--zc-border: #e2e2e2;--zc-bg: #ffffff;--zc-muted-bg: #f6f6f6;--zc-fg: #1a1a1a;--zc-muted-fg: #6b7280;--zc-today-bg: #f0f6ff;--zc-now: #ef4444;--zc-btn-bg: transparent;--zc-btn-fg: var(--zc-fg);--zc-btn-border: var(--zc-border);--zc-btn-hover-bg: var(--zc-muted-bg);--zc-btn-active-bg: #e7efff;--zc-event-bg: #c7dbff;--zc-event-border: #a9c6ff;--zc-event-fg: #1e3a5f;--zc-nonbusiness: oklch(0 0 0 / .045);--zc-radius: 6px;--zc-font: inherit;display:flex;flex-direction:column;box-sizing:border-box;font-family:var(--zc-font);color:var(--zc-fg);background:var(--zc-bg)}.zc *,.zc *:before,.zc *:after{box-sizing:border-box}.zc-toolbar{display:flex;align-items:center;justify-content:space-between;gap:.5rem;padding:.5rem .75rem;flex:0 0 auto}.zc-toolbar-section{display:flex;align-items:center;gap:.375rem}.zc-btn-group{display:inline-flex}.zc-btn-group .zc-btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0;margin-left:-1px}.zc-btn-group .zc-btn:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.zc-toolbar-center{flex:1 1 auto;justify-content:center}.zc-title{margin:0;font-size:1rem;font-weight:600;text-transform:capitalize}.zc-btn{-webkit-appearance:none;-moz-appearance:none;appearance:none;cursor:pointer;font:inherit;font-size:.875rem;line-height:1.2;padding:.375rem .75rem;border-radius:var(--zc-radius);border:1px solid var(--zc-btn-border);background:var(--zc-btn-bg);color:var(--zc-btn-fg)}.zc-btn:hover{background:var(--zc-btn-hover-bg)}.zc-btn:active{background:var(--zc-btn-active-bg)}.zc-body{flex:1 1 auto;overflow:auto;position:relative;border-top:1px solid var(--zc-border)}.zc-timegrid{display:flex;align-items:stretch;position:relative;min-height:100%}.zc-axis{position:relative;flex:0 0 56px;border-right:1px solid var(--zc-border)}.zc-axis-label{position:absolute;right:6px;transform:translateY(-50%);font-size:.6875rem;color:var(--zc-muted-fg);white-space:nowrap}.zc-col{position:relative;flex:1 1 auto}.zc-slot-line{position:absolute;left:0;right:0;border-top:1px solid var(--zc-border);opacity:.4}.zc-slot-line.zc-slot-major{opacity:1}.zc-event{position:absolute;overflow:hidden;border-radius:var(--zc-radius);border:1px solid var(--zc-event-border);background:var(--zc-event-bg);color:var(--zc-event-fg);font-size:.75rem;cursor:pointer}.zc-event-main{padding:2px 4px;height:100%}.zc-event-default{display:flex;flex-direction:column;gap:1px;line-height:1.2}.zc-event-time{font-variant-numeric:tabular-nums;opacity:.85}.zc-event-title{font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.zc-timeline{position:absolute;top:0;right:0;bottom:0;left:0;display:flex;align-items:stretch}.zc-tl-resource-area{display:flex;flex-direction:column;overflow:hidden;border-right:1px solid var(--zc-border);background:var(--zc-bg)}.zc-tl-resource-head,.zc-tl-resource-row{display:flex;align-items:stretch;flex:0 0 auto}.zc-tl-resource-head{border-bottom:1px solid var(--zc-border);background:var(--zc-muted-bg);font-weight:600;font-size:.75rem}.zc-tl-col-head{display:flex;align-items:center;padding:0 .5rem;overflow:hidden;white-space:nowrap}.zc-tl-resource-body{flex:1 1 auto;overflow:hidden}.zc-tl-resource-row{border-bottom:1px solid var(--zc-border)}.zc-tl-col-cell{display:flex;flex-direction:column;justify-content:center;padding:.25rem .5rem;overflow:hidden;font-size:.8125rem;min-width:0}.zc-tl-group-row{display:flex;align-items:center;padding:0 .5rem;background:var(--zc-muted-bg);color:var(--zc-muted-fg);font-size:.6875rem;font-weight:700;text-transform:uppercase;letter-spacing:.03em}.zc-tl-time-area{display:flex;flex-direction:column;flex:1 1 auto;min-width:0;overflow:hidden}.zc-tl-time-head{flex:0 0 auto;overflow:hidden;position:relative;border-bottom:1px solid var(--zc-border);background:var(--zc-muted-bg)}.zc-tl-axis{position:relative;height:100%}.zc-tl-axis-label{position:absolute;top:0;bottom:0;display:flex;align-items:center;padding-left:4px;font-size:.6875rem;color:var(--zc-muted-fg);white-space:nowrap;border-left:1px solid var(--zc-border)}.zc-tl-time-body{flex:1 1 auto;overflow:auto;position:relative}.zc-tl-time-canvas{position:relative;min-height:100%}.zc-tl-overlay{position:absolute;top:0;right:0;bottom:0;left:0;pointer-events:none;z-index:0}.zc-tl-vline{position:absolute;top:0;bottom:0;border-left:1px solid var(--zc-border);opacity:.6}.zc-tl-now{position:absolute;top:0;bottom:0;border-left:2px solid var(--zc-now);z-index:3}.zc-tl-rows{position:relative;z-index:1}.zc-tl-row{position:relative;border-bottom:1px solid var(--zc-border)}.zc-tl-group-spacer{background:var(--zc-muted-bg);opacity:.5}.zc-tl-event{display:flex;align-items:stretch}.zc-tl-event .zc-event-main{padding:3px 6px}.zc-rg{position:absolute;top:0;right:0;bottom:0;left:0;overflow-y:auto;overflow-x:hidden}.zc-rg-head{position:sticky;top:0;z-index:5;display:flex;align-items:stretch;background:var(--zc-muted-bg);border-bottom:1px solid var(--zc-border)}.zc-rg-corner{flex:0 0 56px;width:56px;border-right:1px solid var(--zc-border)}.zc-rg-head-cols{flex:1 1 auto;display:flex;flex-direction:column;min-width:0}.zc-rg-group-row,.zc-rg-label-row{display:flex;align-items:stretch}.zc-rg-group-band{display:flex;align-items:center;justify-content:center;padding:2px 4px;border-left:1px solid var(--zc-border);font-size:.625rem;font-weight:700;text-transform:uppercase;letter-spacing:.03em;color:var(--zc-muted-fg);overflow:hidden;white-space:nowrap}.zc-rg-label{flex:1 1 0;display:flex;align-items:center;justify-content:center;padding:4px 6px;border-left:1px solid var(--zc-border);font-size:.8125rem;font-weight:600;min-width:0;overflow:hidden;text-align:center}.zc-rg-canvas{display:flex;align-items:stretch}.zc-rg-cols{position:relative;flex:1 1 auto;display:flex;align-items:stretch;min-width:0}.zc-rg-col{position:relative;flex:1 1 0;border-left:1px solid var(--zc-border);min-width:0}.zc-rg-col>.zc-select-box{left:2px;right:2px}.zc-rg-now{z-index:4}.zc-body.zc-closed .zc-col,.zc-body.zc-closed .zc-tl-time-canvas,.zc-body.zc-closed .zc-rg-cols{background:var(--zc-nonbusiness)}.zc-event.zc-dragging{z-index:6;opacity:.9;box-shadow:0 2px 8px #0000002e}.zc-resize-handle{position:absolute;z-index:2}.zc-resize-s{left:0;right:0;bottom:0;height:6px;cursor:ns-resize}.zc-resize-e,.zc-resize-w{top:0;bottom:0;width:6px;cursor:ew-resize}.zc-resize-e{right:0}.zc-resize-w{left:0}.zc-select-box{position:absolute;z-index:5;background:var(--zc-event-bg);border:1px solid var(--zc-event-border);opacity:.45;pointer-events:none;border-radius:var(--zc-radius)}.zc-col>.zc-select-box{left:2px;right:2px}.zc-tl-select{top:2px;bottom:2px}.zc-tl-row.zc-drop-target{background:var(--zc-today-bg)}.zc-now-indicator{position:absolute;left:0;right:0;height:0;border-top:2px solid var(--zc-now);z-index:4;pointer-events:none}.zc-now-indicator:before{content:"";position:absolute;left:-1px;top:-4px;width:7px;height:7px;border-radius:50%;background:var(--zc-now)}
1
+ .zc{--zc-border: #e2e2e2;--zc-bg: #ffffff;--zc-muted-bg: #f6f6f6;--zc-fg: #1a1a1a;--zc-muted-fg: #6b7280;--zc-today-bg: #f0f6ff;--zc-now: #ef4444;--zc-btn-bg: transparent;--zc-btn-fg: var(--zc-fg);--zc-btn-border: var(--zc-border);--zc-btn-hover-bg: var(--zc-muted-bg);--zc-btn-active-bg: #e7efff;--zc-event-bg: #c7dbff;--zc-event-border: #a9c6ff;--zc-event-fg: #1e3a5f;--zc-nonbusiness: oklch(0 0 0 / .045);--zc-radius: 6px;--zc-font: inherit;display:flex;flex-direction:column;box-sizing:border-box;font-family:var(--zc-font);color:var(--zc-fg);background:var(--zc-bg)}.zc *,.zc *:before,.zc *:after{box-sizing:border-box}.zc-toolbar{display:flex;align-items:center;justify-content:space-between;gap:.5rem;padding:.5rem .75rem;flex:0 0 auto}.zc-toolbar-section{display:flex;align-items:center;gap:.375rem}.zc-btn-group{display:inline-flex}.zc-btn-group .zc-btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0;margin-left:-1px}.zc-btn-group .zc-btn:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.zc-toolbar-center{flex:1 1 auto;justify-content:center}.zc-title{margin:0;font-size:1rem;font-weight:600;text-transform:capitalize}.zc-btn{-webkit-appearance:none;-moz-appearance:none;appearance:none;cursor:pointer;font:inherit;font-size:.875rem;line-height:1.2;padding:.375rem .75rem;border-radius:var(--zc-radius);border:1px solid var(--zc-btn-border);background:var(--zc-btn-bg);color:var(--zc-btn-fg)}.zc-btn:hover{background:var(--zc-btn-hover-bg)}.zc-btn:active{background:var(--zc-btn-active-bg)}.zc-body{flex:1 1 auto;overflow:auto;position:relative;border-top:1px solid var(--zc-border)}.zc-timegrid{display:flex;align-items:stretch;position:relative;min-height:100%}.zc-axis{position:relative;flex:0 0 56px;border-right:1px solid var(--zc-border)}.zc-axis-label{position:absolute;right:6px;transform:translateY(-50%);font-size:.6875rem;color:var(--zc-muted-fg);white-space:nowrap}.zc-col{position:relative;flex:1 1 auto}.zc-slot-line{position:absolute;left:0;right:0;border-top:1px solid var(--zc-border);opacity:.4}.zc-slot-line.zc-slot-major{opacity:1}.zc-event{position:absolute;overflow:hidden;border-radius:var(--zc-radius);border:1px solid var(--zc-event-border);background:var(--zc-event-bg);color:var(--zc-event-fg);font-size:.75rem;cursor:pointer}.zc-event-main{padding:2px 4px;height:100%}.zc-event-default{display:flex;flex-direction:column;gap:1px;line-height:1.2}.zc-event-time{font-variant-numeric:tabular-nums;opacity:.85}.zc-event-title{font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.zc-timeline{position:absolute;top:0;right:0;bottom:0;left:0;display:flex;align-items:stretch}.zc-tl-resource-area{display:flex;flex-direction:column;overflow:hidden;border-right:1px solid var(--zc-border);background:var(--zc-bg)}.zc-tl-resource-head,.zc-tl-resource-row{display:flex;align-items:stretch;flex:0 0 auto}.zc-tl-resource-head{border-bottom:1px solid var(--zc-border);background:var(--zc-muted-bg);font-weight:600;font-size:.75rem}.zc-tl-col-head{display:flex;align-items:center;padding:0 .5rem;overflow:hidden;white-space:nowrap}.zc-tl-resource-body{flex:1 1 auto;overflow:hidden}.zc-tl-resource-row{border-bottom:1px solid var(--zc-border)}.zc-tl-col-cell{display:flex;flex-direction:column;justify-content:center;gap:2px;padding:.5rem;overflow:hidden;font-size:.8125rem;min-width:0}.zc-tl-group-row{display:flex;align-items:center;padding:0 .5rem;background:var(--zc-muted-bg);color:var(--zc-muted-fg);font-size:.6875rem;font-weight:700;text-transform:uppercase;letter-spacing:.03em}.zc-tl-time-area{display:flex;flex-direction:column;flex:1 1 auto;min-width:0;overflow:hidden}.zc-tl-time-head{flex:0 0 auto;overflow:hidden;position:relative;border-bottom:1px solid var(--zc-border);background:var(--zc-muted-bg)}.zc-tl-axis{position:relative;height:100%}.zc-tl-axis-label{position:absolute;top:0;bottom:0;display:flex;align-items:center;padding-left:4px;font-size:.6875rem;color:var(--zc-muted-fg);white-space:nowrap;border-left:1px solid var(--zc-border)}.zc-tl-time-body{flex:1 1 auto;overflow:auto;position:relative}.zc-tl-time-canvas{position:relative;min-height:100%}.zc-tl-overlay{position:absolute;top:0;right:0;bottom:0;left:0;pointer-events:none;z-index:0}.zc-tl-vline{position:absolute;top:0;bottom:0;border-left:1px solid var(--zc-border);opacity:.6}.zc-tl-now{position:absolute;top:0;bottom:0;border-left:2px solid var(--zc-now);z-index:3}.zc-tl-rows{position:relative;z-index:1}.zc-tl-row{position:relative;border-bottom:1px solid var(--zc-border)}.zc-tl-group-spacer{background:var(--zc-muted-bg);opacity:.5}.zc-tl-event{display:flex;align-items:stretch}.zc-tl-event .zc-event-main{padding:3px 6px}.zc-rg{position:absolute;top:0;right:0;bottom:0;left:0;overflow-y:auto;overflow-x:hidden}.zc-rg-head{position:sticky;top:0;z-index:5;display:flex;align-items:stretch;background:var(--zc-muted-bg);border-bottom:1px solid var(--zc-border)}.zc-rg-corner{flex:0 0 56px;width:56px;border-right:1px solid var(--zc-border)}.zc-rg-head-cols{flex:1 1 auto;display:flex;flex-direction:column;min-width:0}.zc-rg-group-row,.zc-rg-label-row{display:flex;align-items:stretch}.zc-rg-group-band{display:flex;align-items:center;justify-content:center;padding:2px 4px;border-left:1px solid var(--zc-border);font-size:.625rem;font-weight:700;text-transform:uppercase;letter-spacing:.03em;color:var(--zc-muted-fg);overflow:hidden;white-space:nowrap}.zc-rg-label{flex:1 1 0;display:flex;align-items:center;justify-content:center;padding:4px 6px;border-left:1px solid var(--zc-border);font-size:.8125rem;font-weight:600;min-width:0;overflow:hidden;text-align:center}.zc-rg-canvas{display:flex;align-items:stretch}.zc-rg-cols{position:relative;flex:1 1 auto;display:flex;align-items:stretch;min-width:0}.zc-rg-col{position:relative;flex:1 1 0;border-left:1px solid var(--zc-border);min-width:0}.zc-rg-col>.zc-select-box{left:2px;right:2px}.zc-rg-now{z-index:4}.zc-body.zc-closed .zc-col,.zc-body.zc-closed .zc-tl-time-canvas,.zc-body.zc-closed .zc-rg-cols{background:var(--zc-nonbusiness)}.zc-nonbusiness-fill{position:absolute;background:var(--zc-nonbusiness);pointer-events:none}.zc-tl-row>.zc-nonbusiness-fill{top:0;bottom:0}.zc-col>.zc-nonbusiness-fill,.zc-rg-col>.zc-nonbusiness-fill{left:0;right:0}.zc-event.zc-dragging{z-index:6;opacity:.9;box-shadow:0 2px 8px #0000002e}.zc-resize-handle{position:absolute;z-index:2}.zc-resize-s{left:0;right:0;bottom:0;height:6px;cursor:ns-resize}.zc-resize-e,.zc-resize-w{top:0;bottom:0;width:6px;cursor:ew-resize}.zc-resize-e{right:0}.zc-resize-w{left:0}.zc-select-box{position:absolute;z-index:5;background:var(--zc-event-bg);border:1px solid var(--zc-event-border);opacity:.45;pointer-events:none;border-radius:var(--zc-radius)}.zc-col>.zc-select-box{left:2px;right:2px}.zc-tl-select{top:2px;bottom:2px}.zc-tl-row.zc-drop-target,.zc-rg-col.zc-drop-target{background:var(--zc-today-bg);outline:2px dashed var(--zc-event-border);outline-offset:-2px}.zc-now-indicator{position:absolute;left:0;right:0;height:0;border-top:2px solid var(--zc-now);z-index:4;pointer-events:none}.zc-now-indicator:before{content:"";position:absolute;left:-1px;top:-4px;width:7px;height:7px;border-radius:50%;background:var(--zc-now)}