@redvars/peacock 3.5.1 → 3.6.1

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.
Files changed (225) hide show
  1. package/dist/{BaseButton-DuASuVth.js → BaseButton-BNFAYn-S.js} +2 -2
  2. package/dist/{BaseButton-DuASuVth.js.map → BaseButton-BNFAYn-S.js.map} +1 -1
  3. package/dist/BaseInput-14YmcfK7.js +27 -0
  4. package/dist/BaseInput-14YmcfK7.js.map +1 -0
  5. package/dist/banner.js +2 -3
  6. package/dist/banner.js.map +1 -1
  7. package/dist/{button-DouvOfEU.js → button-colors-Ccys3hvS.js} +5 -294
  8. package/dist/button-colors-Ccys3hvS.js.map +1 -0
  9. package/dist/button-group.js +226 -6
  10. package/dist/button-group.js.map +1 -1
  11. package/dist/button.js +294 -8
  12. package/dist/button.js.map +1 -1
  13. package/dist/calendar-column-view.js +634 -0
  14. package/dist/calendar-column-view.js.map +1 -0
  15. package/dist/calendar-event-BrQ_SEKD.js +199 -0
  16. package/dist/calendar-event-BrQ_SEKD.js.map +1 -0
  17. package/dist/calendar-month-view.js +376 -0
  18. package/dist/calendar-month-view.js.map +1 -0
  19. package/dist/calendar.js +339 -0
  20. package/dist/calendar.js.map +1 -0
  21. package/dist/canvas.js +361 -0
  22. package/dist/canvas.js.map +1 -0
  23. package/dist/cb-compound-expression.js +125 -0
  24. package/dist/cb-compound-expression.js.map +1 -0
  25. package/dist/cb-divider.js +150 -0
  26. package/dist/cb-divider.js.map +1 -0
  27. package/dist/cb-expression.js +75 -0
  28. package/dist/cb-expression.js.map +1 -0
  29. package/dist/cb-predicate.js +137 -0
  30. package/dist/cb-predicate.js.map +1 -0
  31. package/dist/code-editor.js +2 -1
  32. package/dist/code-editor.js.map +1 -1
  33. package/dist/code-highlighter.js +1 -1
  34. package/dist/code-highlighter.js.map +1 -1
  35. package/dist/condition-builder.js +58 -0
  36. package/dist/condition-builder.js.map +1 -0
  37. package/dist/custom-elements-jsdocs.json +8479 -3965
  38. package/dist/custom-elements.json +15228 -7544
  39. package/dist/dropdown-button.js +216 -0
  40. package/dist/dropdown-button.js.map +1 -0
  41. package/dist/event-manager-D-QCmUgR.js +113 -0
  42. package/dist/event-manager-D-QCmUgR.js.map +1 -0
  43. package/dist/fab.js +1 -1
  44. package/dist/flow-designer-DvTUrDp5.js +1656 -0
  45. package/dist/flow-designer-DvTUrDp5.js.map +1 -0
  46. package/dist/flow-designer-node-BWrPuxAR.js +548 -0
  47. package/dist/flow-designer-node-BWrPuxAR.js.map +1 -0
  48. package/dist/flow-designer-node.js +4 -0
  49. package/dist/flow-designer-node.js.map +1 -0
  50. package/dist/flow-designer.js +16 -0
  51. package/dist/flow-designer.js.map +1 -0
  52. package/dist/html-editor.js +27516 -0
  53. package/dist/html-editor.js.map +1 -0
  54. package/dist/icon-button-CK1ZuE-2.js +247 -0
  55. package/dist/icon-button-CK1ZuE-2.js.map +1 -0
  56. package/dist/index.js +29 -6
  57. package/dist/index.js.map +1 -1
  58. package/dist/{is-dark-mode-DicqGkCJ.js → is-dark-mode-DOcaw4Yq.js} +2 -27
  59. package/dist/is-dark-mode-DOcaw4Yq.js.map +1 -0
  60. package/dist/modal.js +412 -0
  61. package/dist/modal.js.map +1 -0
  62. package/dist/{navigation-rail-Lxetd5-Z.js → navigation-rail-DTTkqohi.js} +1049 -2391
  63. package/dist/navigation-rail-DTTkqohi.js.map +1 -0
  64. package/dist/notification-manager.js +268 -0
  65. package/dist/notification-manager.js.map +1 -0
  66. package/dist/peacock-loader.js +93 -8
  67. package/dist/peacock-loader.js.map +1 -1
  68. package/dist/popover-NC7b1lTq.js +1971 -0
  69. package/dist/popover-NC7b1lTq.js.map +1 -0
  70. package/dist/popover-content.js +125 -0
  71. package/dist/popover-content.js.map +1 -0
  72. package/dist/popover.js +4 -0
  73. package/dist/popover.js.map +1 -0
  74. package/dist/split-button.js +388 -0
  75. package/dist/split-button.js.map +1 -0
  76. package/dist/src/__controllers/floating-controller.d.ts +35 -0
  77. package/dist/src/calendar/base-event.d.ts +10 -0
  78. package/dist/src/calendar/calendar-column-view.d.ts +41 -0
  79. package/dist/src/calendar/calendar-event.d.ts +7 -0
  80. package/dist/src/calendar/calendar-month-view.d.ts +31 -0
  81. package/dist/src/calendar/calendar.d.ts +65 -0
  82. package/dist/src/calendar/event-manager.d.ts +17 -0
  83. package/dist/src/calendar/index.d.ts +4 -0
  84. package/dist/src/calendar/types.d.ts +13 -0
  85. package/dist/src/calendar/utils.d.ts +31 -0
  86. package/dist/src/canvas/canvas.d.ts +92 -0
  87. package/dist/src/canvas/index.d.ts +2 -0
  88. package/dist/src/condition-builder/cb-compound-expression.d.ts +31 -0
  89. package/dist/src/condition-builder/cb-divider.d.ts +26 -0
  90. package/dist/src/condition-builder/cb-expression.d.ts +31 -0
  91. package/dist/src/condition-builder/cb-predicate.d.ts +30 -0
  92. package/dist/src/condition-builder/condition-builder.d.ts +27 -0
  93. package/dist/src/condition-builder/index.d.ts +5 -0
  94. package/dist/src/dropdown-button/dropdown-button.d.ts +68 -0
  95. package/dist/src/dropdown-button/index.d.ts +1 -0
  96. package/dist/src/flow-designer/commands.d.ts +66 -0
  97. package/dist/src/flow-designer/flow-designer-node.d.ts +46 -0
  98. package/dist/src/flow-designer/flow-designer.d.ts +133 -0
  99. package/dist/src/flow-designer/index.d.ts +7 -0
  100. package/dist/src/flow-designer/layout.d.ts +30 -0
  101. package/dist/src/flow-designer/types.d.ts +142 -0
  102. package/dist/src/flow-designer/validation.d.ts +43 -0
  103. package/dist/src/flow-designer/workflow-utils.d.ts +40 -0
  104. package/dist/src/html-editor/html-editor.d.ts +89 -0
  105. package/dist/src/html-editor/index.d.ts +2 -0
  106. package/dist/src/index.d.ts +15 -0
  107. package/dist/src/list/index.d.ts +2 -0
  108. package/dist/src/list/list-item.d.ts +35 -0
  109. package/dist/src/list/list.d.ts +28 -0
  110. package/dist/src/menu/menu/menu.d.ts +5 -7
  111. package/dist/src/menu/menu-item/menu-item.d.ts +14 -13
  112. package/dist/src/modal/index.d.ts +1 -0
  113. package/dist/src/modal/modal.d.ts +57 -0
  114. package/dist/src/navigation-rail/navigation-rail.d.ts +3 -7
  115. package/dist/src/notification-manager/index.d.ts +1 -0
  116. package/dist/src/notification-manager/notification-manager.d.ts +44 -0
  117. package/dist/src/number-field/number-field.d.ts +2 -2
  118. package/dist/src/popover/index.d.ts +2 -0
  119. package/dist/src/popover/popover-content.d.ts +29 -0
  120. package/dist/src/popover/popover.d.ts +62 -0
  121. package/dist/src/split-button/index.d.ts +1 -0
  122. package/dist/src/split-button/split-button.d.ts +72 -0
  123. package/dist/src/svg/index.d.ts +1 -0
  124. package/dist/src/svg/svg.d.ts +38 -0
  125. package/dist/src/toolbar/toolbar.d.ts +3 -3
  126. package/dist/src/tooltip/tooltip.d.ts +2 -15
  127. package/dist/test/flow-designer.test.d.ts +1 -0
  128. package/dist/toolbar.js +3 -3
  129. package/dist/toolbar.js.map +1 -1
  130. package/dist/tsconfig.tsbuildinfo +1 -1
  131. package/package.json +10 -2
  132. package/readme.md +3 -3
  133. package/src/__controllers/floating-controller.ts +237 -0
  134. package/src/banner/banner.scss +2 -3
  135. package/src/button/button/button.ts +1 -0
  136. package/src/calendar/base-event.ts +49 -0
  137. package/src/calendar/calendar-column-view.scss +326 -0
  138. package/src/calendar/calendar-column-view.ts +392 -0
  139. package/src/calendar/calendar-event.ts +20 -0
  140. package/src/calendar/calendar-month-view.scss +192 -0
  141. package/src/calendar/calendar-month-view.ts +244 -0
  142. package/src/calendar/calendar.scss +71 -0
  143. package/src/calendar/calendar.ts +298 -0
  144. package/src/calendar/event-manager.ts +117 -0
  145. package/src/calendar/index.ts +4 -0
  146. package/src/calendar/types.ts +14 -0
  147. package/src/calendar/utils.ts +180 -0
  148. package/src/canvas/canvas.scss +60 -0
  149. package/src/canvas/canvas.ts +391 -0
  150. package/src/canvas/index.ts +2 -0
  151. package/src/code-highlighter/code-highlighter.ts +1 -1
  152. package/src/condition-builder/cb-compound-expression.scss +37 -0
  153. package/src/condition-builder/cb-compound-expression.ts +80 -0
  154. package/src/condition-builder/cb-divider.scss +93 -0
  155. package/src/condition-builder/cb-divider.ts +56 -0
  156. package/src/condition-builder/cb-expression.scss +14 -0
  157. package/src/condition-builder/cb-expression.ts +49 -0
  158. package/src/condition-builder/cb-predicate.scss +35 -0
  159. package/src/condition-builder/cb-predicate.ts +102 -0
  160. package/src/condition-builder/condition-builder.scss +13 -0
  161. package/src/condition-builder/condition-builder.ts +38 -0
  162. package/src/condition-builder/index.ts +5 -0
  163. package/src/dropdown-button/demo/index.html +110 -0
  164. package/src/dropdown-button/dropdown-button.scss +22 -0
  165. package/src/dropdown-button/dropdown-button.ts +206 -0
  166. package/src/dropdown-button/index.ts +1 -0
  167. package/src/flow-designer/DEMO.md +239 -0
  168. package/src/flow-designer/commands.ts +278 -0
  169. package/src/flow-designer/flow-designer-node.ts +172 -0
  170. package/src/flow-designer/flow-designer.scss +457 -0
  171. package/src/flow-designer/flow-designer.ts +611 -0
  172. package/src/flow-designer/index.ts +41 -0
  173. package/src/flow-designer/layout.ts +357 -0
  174. package/src/flow-designer/types.ts +166 -0
  175. package/src/flow-designer/validation.ts +284 -0
  176. package/src/flow-designer/workflow-utils.ts +282 -0
  177. package/src/html-editor/html-editor.scss +188 -0
  178. package/src/html-editor/html-editor.ts +491 -0
  179. package/src/html-editor/index.ts +3 -0
  180. package/src/index.ts +27 -1
  181. package/src/list/index.ts +2 -0
  182. package/src/list/list-item.scss +111 -0
  183. package/src/list/list-item.ts +175 -0
  184. package/src/list/list.scss +24 -0
  185. package/src/list/list.ts +51 -0
  186. package/src/menu/menu/menu.scss +2 -2
  187. package/src/menu/menu/menu.ts +91 -101
  188. package/src/menu/menu-item/menu-item.scss +4 -0
  189. package/src/menu/menu-item/menu-item.ts +82 -78
  190. package/src/modal/index.ts +1 -0
  191. package/src/modal/modal.scss +206 -0
  192. package/src/modal/modal.ts +195 -0
  193. package/src/navigation-rail/navigation-rail-item.scss +7 -38
  194. package/src/navigation-rail/navigation-rail-item.ts +1 -2
  195. package/src/navigation-rail/navigation-rail.scss +17 -21
  196. package/src/navigation-rail/navigation-rail.ts +6 -9
  197. package/src/notification-manager/index.ts +1 -0
  198. package/src/notification-manager/notification-manager.scss +113 -0
  199. package/src/notification-manager/notification-manager.ts +199 -0
  200. package/src/number-field/number-field.ts +2 -2
  201. package/src/peacock-loader.ts +83 -0
  202. package/src/popover/index.ts +2 -0
  203. package/src/popover/popover-content.scss +69 -0
  204. package/src/popover/popover-content.ts +51 -0
  205. package/src/popover/popover.scss +7 -0
  206. package/src/popover/popover.ts +170 -0
  207. package/src/split-button/index.ts +1 -0
  208. package/src/split-button/split-button-colors.scss +56 -0
  209. package/src/split-button/split-button-sizes.scss +28 -0
  210. package/src/split-button/split-button.scss +79 -0
  211. package/src/split-button/split-button.ts +236 -0
  212. package/src/svg/index.ts +1 -0
  213. package/src/svg/svg.scss +91 -0
  214. package/src/svg/svg.ts +160 -0
  215. package/src/table/table.ts +2 -2
  216. package/src/toolbar/toolbar.ts +3 -3
  217. package/src/tooltip/tooltip.scss +4 -3
  218. package/src/tooltip/tooltip.ts +46 -104
  219. package/dist/button-DouvOfEU.js.map +0 -1
  220. package/dist/button-group-CEdMwvJJ.js +0 -464
  221. package/dist/button-group-CEdMwvJJ.js.map +0 -1
  222. package/dist/is-dark-mode-DicqGkCJ.js.map +0 -1
  223. package/dist/navigation-rail-Lxetd5-Z.js.map +0 -1
  224. package/dist/src/menu/menu/MenuSurfaceController.d.ts +0 -18
  225. package/src/menu/menu/MenuSurfaceController.ts +0 -61
@@ -0,0 +1,392 @@
1
+ import { LitElement, html, nothing } from 'lit';
2
+ import { property, state } from 'lit/decorators.js';
3
+ import {
4
+ addDays,
5
+ addHours,
6
+ differenceInDays,
7
+ startOfDay,
8
+ endOfDay,
9
+ calculateDateRange,
10
+ formatDate,
11
+ getTimePercent,
12
+ LONG_EVENT_PADDING,
13
+ } from './utils.js';
14
+ import { BaseEvent } from './base-event.js';
15
+ import { CalendarEvent } from './calendar-event.js';
16
+ import { EventManager } from './event-manager.js';
17
+ import type { ColumnEvent } from './event-manager.js';
18
+ import IndividualComponent from '@/IndividualComponent.js';
19
+ import styles from './calendar-column-view.scss';
20
+
21
+ /**
22
+ * @label Calendar Column View
23
+ * @tag wc-calendar-column-view
24
+ * @rawTag calendar-column-view
25
+ * @parentRawTag calendar
26
+ * @summary Internal column view component for the calendar (day/week views).
27
+ */
28
+ @IndividualComponent
29
+ export class CalendarColumnView extends LitElement {
30
+ static styles = [styles];
31
+
32
+ @property({ type: Array })
33
+ events: CalendarEvent[] = [];
34
+
35
+ @property({ type: String })
36
+ view: string = 'week';
37
+
38
+ @property({ type: Number })
39
+ days: number = 7;
40
+
41
+ @property({ type: Boolean, attribute: 'event-clickable' })
42
+ eventClickable: boolean = true;
43
+
44
+ @property({ type: Object, attribute: false })
45
+ currentTime: Date = new Date();
46
+
47
+ @property({ type: Object, attribute: false })
48
+ contextDate: Date = new Date();
49
+
50
+ @state()
51
+ private dateRange: any = {};
52
+
53
+ @state()
54
+ private singleDayEvents: Record<string, ColumnEvent[][]> = {};
55
+
56
+ @state()
57
+ private multiDayEvents: ColumnEvent[][] = [];
58
+
59
+ override connectedCallback() {
60
+ super.connectedCallback();
61
+ this._processEvents();
62
+ }
63
+
64
+ override willUpdate(changedProperties: Map<string, unknown>) {
65
+ if (
66
+ changedProperties.has('events') ||
67
+ changedProperties.has('contextDate') ||
68
+ changedProperties.has('view') ||
69
+ changedProperties.has('days')
70
+ ) {
71
+ this._processEvents();
72
+ }
73
+ }
74
+
75
+ override firstUpdated() {
76
+ const viewBody = this.renderRoot.querySelector('.view-body');
77
+ if (viewBody) {
78
+ const viewBodyHeight = viewBody.scrollHeight;
79
+ viewBody.scrollTo({
80
+ top:
81
+ (getTimePercent(this.currentTime) / 100) * viewBodyHeight - 150,
82
+ });
83
+ }
84
+ }
85
+
86
+ private _processEvents() {
87
+ this.dateRange = calculateDateRange(this.view, this.contextDate, this.days);
88
+ this.singleDayEvents = {};
89
+
90
+ this._forEachDayInRange(i => {
91
+ const manager = new EventManager();
92
+ manager.addEvents(
93
+ this.events.filter(
94
+ event =>
95
+ event.isOverlapping(new BaseEvent(startOfDay(i), endOfDay(i))) &&
96
+ event.length() < 86400000,
97
+ ),
98
+ );
99
+ manager.process();
100
+ this.singleDayEvents[this._getDateOnly(i)] = manager.columns;
101
+ });
102
+
103
+ const multiManager = new EventManager();
104
+ multiManager.addEvents(
105
+ this.events.filter(
106
+ event =>
107
+ event.isOverlapping(
108
+ new BaseEvent(this.dateRange.startDate, this.dateRange.endDate),
109
+ ) && event.length() >= 86400000,
110
+ ),
111
+ );
112
+ multiManager.process();
113
+ this.multiDayEvents = multiManager.columns;
114
+ }
115
+
116
+ private _forEachDayInRange(callback: (d: Date) => void) {
117
+ for (
118
+ let i = new Date(this.dateRange.startDate);
119
+ differenceInDays(startOfDay(this.dateRange.endDate), i) >= 0;
120
+ i = addDays(i, 1)
121
+ ) {
122
+ callback(i);
123
+ }
124
+ }
125
+
126
+ private _getDateOnly(date: Date): string {
127
+ return formatDate(date, 'dd-MM-yyyy');
128
+ }
129
+
130
+ private _getDatePercent(date: Date): number {
131
+ const currentDay = differenceInDays(
132
+ startOfDay(date),
133
+ this.dateRange.startDate,
134
+ );
135
+ const percent = (currentDay / this.dateRange.totalDays) * 100;
136
+ if (percent < 0) return 0;
137
+ if (percent > 100) return 100;
138
+ return percent;
139
+ }
140
+
141
+ private _getDayClass(date: Date): string {
142
+ const diff = differenceInDays(startOfDay(date), startOfDay(this.currentTime));
143
+ if (diff === 0) return 'column today';
144
+ if (diff < 0) return 'column past';
145
+ return 'column future';
146
+ }
147
+
148
+ private _populateColorVars(
149
+ styles: Record<string, string>,
150
+ color: string,
151
+ ) {
152
+ styles['--calendar-event-bg-color'] = `var(--color-${color}-container)`;
153
+ styles['--calendar-event-bg-color--hover'] = `var(--color-inverse-${color})`;
154
+ styles['--calendar-event-border-color'] = `var(--color-${color})`;
155
+ styles['--calendar-event-text-color'] = `var(--color-on-${color}-container)`;
156
+ styles['--calendar-event-text-color--hover'] = `var(--color-on-${color})`;
157
+ }
158
+
159
+ private _emitDateClick(date: Date) {
160
+ this.dispatchEvent(
161
+ new CustomEvent('column-view-date-click', {
162
+ detail: { date },
163
+ bubbles: true,
164
+ composed: true,
165
+ }),
166
+ );
167
+ }
168
+
169
+ private _emitEventClick(event: any) {
170
+ this.dispatchEvent(
171
+ new CustomEvent('column-view-event-click', {
172
+ detail: { event },
173
+ bubbles: true,
174
+ composed: true,
175
+ }),
176
+ );
177
+ }
178
+
179
+ private _renderHeader() {
180
+ const columns: any[] = [];
181
+ this._forEachDayInRange(i => {
182
+ columns.push(html`
183
+ <div class=${this._getDayClass(i)}>
184
+ <div class="column-content">
185
+ <div
186
+ class="date"
187
+ @click=${() => this._emitDateClick(i)}
188
+ >
189
+ ${formatDate(i, 'dd')}
190
+ </div>
191
+ <div class="day">${formatDate(i, 'E')}</div>
192
+ </div>
193
+ </div>
194
+ `);
195
+ });
196
+ return columns;
197
+ }
198
+
199
+ private _renderMultiDayBackground() {
200
+ const columns: any[] = [];
201
+ this._forEachDayInRange(i => {
202
+ columns.push(html`<div class=${this._getDayClass(i)}></div>`);
203
+ });
204
+ return columns;
205
+ }
206
+
207
+ private _renderScale() {
208
+ const rows: any[] = [];
209
+ for (let i = 0; i < 48; i++) {
210
+ const cls = i % 2 ? 'row hour' : 'row';
211
+ const sd = startOfDay(new Date());
212
+ rows.push(html`
213
+ <div class=${cls}>
214
+ ${i % 2 === 0 && i
215
+ ? html`<div class="time">${formatDate(addHours(sd, i / 2), 'hh a')}</div>`
216
+ : nothing}
217
+ </div>
218
+ `);
219
+ }
220
+ return html`<div class="background">${rows}</div>`;
221
+ }
222
+
223
+ private _renderBackgroundGrid() {
224
+ const rows: any[] = [];
225
+ for (let i = 0; i < 48; i++) {
226
+ const cls = i % 2 ? 'row hour' : 'row';
227
+ const columns: any[] = [];
228
+ this._forEachDayInRange(d => {
229
+ columns.push(html`<div class=${this._getDayClass(d)}></div>`);
230
+ });
231
+ rows.push(html`<div class=${cls}>${columns}</div>`);
232
+ }
233
+ return html`<div class="background">${rows}</div>`;
234
+ }
235
+
236
+ private _renderEvents() {
237
+ const columns: any[] = [];
238
+ this._forEachDayInRange(i => {
239
+ const cls = this._getDayClass(i);
240
+ const eventDay = this.singleDayEvents[this._getDateOnly(i)];
241
+ columns.push(html`
242
+ <div class=${cls}>
243
+ <div class="column-content">
244
+ ${eventDay
245
+ ? eventDay.map((nodes, columnIndex) =>
246
+ nodes.map(node => {
247
+ const evtCls = this.eventClickable
248
+ ? 'event clickable'
249
+ : 'event';
250
+ const evtStyles: Record<string, string> = {
251
+ top: `${getTimePercent(node.start, startOfDay(i))}%`,
252
+ height: `${getTimePercent(node.end, startOfDay(i)) - getTimePercent(node.start, startOfDay(i))}%`,
253
+ left: `${(columnIndex / eventDay.length) * 100}%`,
254
+ width: `calc(${((1 * node.width) / eventDay.length) * 100}% - 1px)`,
255
+ };
256
+ if (node.color) {
257
+ this._populateColorVars(evtStyles, node.color);
258
+ }
259
+ return html`
260
+ <div
261
+ class=${evtCls}
262
+ style=${this._styleMap(evtStyles)}
263
+ @click=${() => {
264
+ if (this.eventClickable) this._emitEventClick(node.data);
265
+ }}
266
+ >
267
+ <div class="event-title">
268
+ ${node.title || '(no title)'}
269
+ </div>
270
+ </div>
271
+ `;
272
+ }),
273
+ )
274
+ : nothing}
275
+ </div>
276
+ </div>
277
+ `);
278
+ });
279
+ return html`<div class="events-container">${columns}</div>`;
280
+ }
281
+
282
+ private _renderMultiDayEvents() {
283
+ if (!this.multiDayEvents || !this.multiDayEvents.length) return nothing;
284
+ return html`
285
+ <div class="row-content">
286
+ ${this.multiDayEvents.map(
287
+ nodes => html`
288
+ <div class="row">
289
+ ${nodes.map(node => {
290
+ const evtCls = this.eventClickable
291
+ ? 'event clickable'
292
+ : 'event';
293
+ const evtStyles: Record<string, string> = {
294
+ left: `${this._getDatePercent(node.start) + LONG_EVENT_PADDING}%`,
295
+ width: `${this._getDatePercent(addDays(node.end, 1)) - this._getDatePercent(node.start) - 2 * LONG_EVENT_PADDING}%`,
296
+ };
297
+ if (node.color) {
298
+ this._populateColorVars(evtStyles, node.color);
299
+ }
300
+ return html`
301
+ <div
302
+ class=${evtCls}
303
+ style=${this._styleMap(evtStyles)}
304
+ @click=${() => {
305
+ if (this.eventClickable) this._emitEventClick(node.data);
306
+ }}
307
+ >
308
+ <div class="event-title">
309
+ ${node.title || '(no title)'}
310
+ </div>
311
+ </div>
312
+ `;
313
+ })}
314
+ </div>
315
+ `,
316
+ )}
317
+ <div class="row-spacer"></div>
318
+ </div>
319
+ `;
320
+ }
321
+
322
+ private _renderCurrentTime() {
323
+ if (
324
+ this.currentTime.valueOf() < this.dateRange.startDate?.valueOf() - 1 ||
325
+ this.currentTime.valueOf() > this.dateRange.endDate?.valueOf() + 1
326
+ ) {
327
+ return nothing;
328
+ }
329
+ return html`
330
+ <div
331
+ class="current-time-line"
332
+ style="top: calc(${getTimePercent(this.currentTime)}% - 1px)"
333
+ >
334
+ <div class="time">${formatDate(this.currentTime, 'hh:mm a')}</div>
335
+ <div
336
+ class="dash-line"
337
+ style="width: ${this._getDatePercent(this.currentTime)}%"
338
+ ></div>
339
+ <div
340
+ class="dot"
341
+ style="left: calc(${this._getDatePercent(this.currentTime)}% - 0.25rem)"
342
+ ></div>
343
+ <div
344
+ class="line"
345
+ style="left: ${this._getDatePercent(this.currentTime)}%; width: ${(1 / this.dateRange.totalDays) * 100}%"
346
+ ></div>
347
+ </div>
348
+ `;
349
+ }
350
+
351
+ private _styleMap(styles: Record<string, string>): string {
352
+ return Object.entries(styles)
353
+ .map(([k, v]) => `${k}:${v}`)
354
+ .join(';');
355
+ }
356
+
357
+ render() {
358
+ return html`
359
+ <div class="calendar-column-view">
360
+ <div class="view-header">
361
+ <div class="scale"></div>
362
+ <div class="columns">${this._renderHeader()}</div>
363
+ <div class="scrollbar-placeholder"></div>
364
+ </div>
365
+ <div class="multi-day-section-wrapper">
366
+ <div class="multi-day-section-scroll">
367
+ <div class="multi-day-section">
368
+ <div class="multi-day-background">
369
+ <div class="scale"></div>
370
+ <div class="columns">
371
+ ${this._renderMultiDayBackground()}
372
+ </div>
373
+ </div>
374
+ <div class="multi-events">
375
+ ${this._renderMultiDayEvents()}
376
+ </div>
377
+ </div>
378
+ </div>
379
+ </div>
380
+ <div class="view-body">
381
+ <div class="view-body-scroll">
382
+ <div class="scale">${this._renderScale()}</div>
383
+ <div class="drawing-area">
384
+ ${this._renderBackgroundGrid()} ${this._renderEvents()}
385
+ </div>
386
+ ${this._renderCurrentTime()}
387
+ </div>
388
+ </div>
389
+ </div>
390
+ `;
391
+ }
392
+ }
@@ -0,0 +1,20 @@
1
+ import { BaseEvent } from './base-event.js';
2
+
3
+ export class CalendarEvent extends BaseEvent {
4
+ data: any;
5
+ title: string;
6
+ color?: string;
7
+
8
+ constructor(
9
+ start: Date,
10
+ end: Date,
11
+ title: string,
12
+ color: string | undefined,
13
+ data: any,
14
+ ) {
15
+ super(start, end);
16
+ this.data = data;
17
+ if (color) this.color = color;
18
+ this.title = title;
19
+ }
20
+ }
@@ -0,0 +1,192 @@
1
+ @use '../../scss/mixin';
2
+
3
+ @include mixin.base-styles;
4
+
5
+ :host {
6
+ display: block;
7
+ height: 100%;
8
+ --calendar-border-color: var(--color-outline-variant);
9
+ --calendar-scale-color: var(--color-outline-variant);
10
+ --scale-size: 3rem;
11
+ }
12
+
13
+ .scale {
14
+ width: var(--scale-size);
15
+ flex-shrink: 0;
16
+ }
17
+
18
+ .calendar-month-view {
19
+ display: flex;
20
+ flex-direction: column;
21
+ height: 100%;
22
+ }
23
+
24
+ /* ── Header ── */
25
+ .view-header {
26
+ background: var(--color-surface-container);
27
+ display: flex;
28
+ border-bottom: 1px solid var(--calendar-border-color);
29
+
30
+ .columns {
31
+ display: flex;
32
+ flex: 1;
33
+
34
+ .column {
35
+ flex: 1;
36
+ border-inline-start: 1px solid var(--calendar-border-color);
37
+
38
+ &:first-child {
39
+ border-inline-start: 0;
40
+ }
41
+
42
+ .column-content {
43
+ display: flex;
44
+ align-items: center;
45
+ padding: 0.5rem 0.75rem;
46
+ gap: 0.5rem;
47
+ }
48
+
49
+ .day {
50
+ font-size: 0.875rem;
51
+ font-weight: 500;
52
+ color: var(--color-on-surface-variant);
53
+ }
54
+ }
55
+ }
56
+
57
+ .scrollbar-placeholder {
58
+ width: var(--scrollbar-width, 0px);
59
+ }
60
+ }
61
+
62
+ /* ── View body ── */
63
+ .view-body {
64
+ height: 100%;
65
+ overflow-y: auto;
66
+
67
+ .view-body-scroll {
68
+ display: flex;
69
+ position: relative;
70
+ min-height: 100%;
71
+
72
+ .drawing-area {
73
+ flex: 1;
74
+
75
+ .multi-day-section {
76
+ border-bottom: 1px solid var(--calendar-scale-color);
77
+ min-height: 8rem;
78
+
79
+ .multi-day-body-scroll {
80
+ position: relative;
81
+ height: 100%;
82
+ }
83
+
84
+ .multi-day-background {
85
+ display: flex;
86
+ height: 100%;
87
+ position: absolute;
88
+ width: 100%;
89
+
90
+ .columns {
91
+ display: flex;
92
+ flex: 1;
93
+
94
+ .column {
95
+ min-height: 8rem;
96
+ flex: 1;
97
+ border-inline-start: 1px solid var(--calendar-scale-color);
98
+
99
+ &:first-child {
100
+ border-inline-start: 0;
101
+ }
102
+
103
+ .column-header {
104
+ font-size: 0.75rem;
105
+ color: var(--color-on-surface-variant);
106
+ padding-inline-start: 0.5rem;
107
+ padding-top: 0.375rem;
108
+ border-top: 3px solid transparent;
109
+ }
110
+
111
+ &.today {
112
+ background: color-mix(in srgb, var(--color-primary) 6%, transparent);
113
+
114
+ .column-header {
115
+ border-top-color: var(--color-primary);
116
+ }
117
+ }
118
+ }
119
+ }
120
+ }
121
+
122
+ .multi-events {
123
+ min-height: 4rem;
124
+ padding-top: 2rem;
125
+ height: 100%;
126
+
127
+ .row {
128
+ height: 1.8rem;
129
+ box-sizing: content-box;
130
+ position: relative;
131
+ padding-bottom: 0.25rem;
132
+
133
+ &:last-child {
134
+ padding-bottom: 0;
135
+ }
136
+ }
137
+
138
+ .row-spacer {
139
+ height: 0.75rem;
140
+ }
141
+
142
+ .event {
143
+ position: absolute;
144
+ height: 1.8rem;
145
+ text-overflow: ellipsis;
146
+ overflow: hidden;
147
+
148
+ .event-title {
149
+ padding: 0.25rem 0.375rem;
150
+ font-size: 0.75rem;
151
+ font-weight: 500;
152
+ white-space: nowrap;
153
+ overflow: hidden;
154
+ text-overflow: ellipsis;
155
+ }
156
+
157
+ &.clickable {
158
+ cursor: pointer;
159
+ }
160
+ }
161
+ }
162
+ }
163
+ }
164
+ }
165
+ }
166
+
167
+ /* ── Event styles ── */
168
+ .event {
169
+ background: var(--calendar-event-bg-color);
170
+ border-inline-start: 0.25rem solid var(--calendar-event-border-color);
171
+ border-radius: var(--shape-corner-extra-small);
172
+ color: var(--calendar-event-text-color);
173
+ transition: background 150ms ease;
174
+
175
+ &.clickable {
176
+ &:hover {
177
+ background: var(--calendar-event-bg-color--hover);
178
+ color: var(--calendar-event-text-color--hover);
179
+ }
180
+ }
181
+ }
182
+
183
+ /* ── Today highlighting ── */
184
+ .calendar-month-view .view-body .view-body-scroll .drawing-area .multi-day-section .multi-day-background .columns .column {
185
+ &.today {
186
+ background: color-mix(in srgb, var(--color-primary) 6%, transparent);
187
+
188
+ .column-header {
189
+ border-top-color: var(--color-primary);
190
+ }
191
+ }
192
+ }