@redvars/peacock 3.5.0 → 3.6.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.
Files changed (314) hide show
  1. package/dist/BaseButton-BNFAYn-S.js +219 -0
  2. package/dist/BaseButton-BNFAYn-S.js.map +1 -0
  3. package/dist/BaseHyperlinkMixin-BNuwbiEf.js +65 -0
  4. package/dist/BaseHyperlinkMixin-BNuwbiEf.js.map +1 -0
  5. package/dist/BaseInput-14YmcfK7.js +27 -0
  6. package/dist/BaseInput-14YmcfK7.js.map +1 -0
  7. package/dist/assets/components.css +1 -1
  8. package/dist/assets/components.css.map +1 -1
  9. package/dist/assets/styles.css +1 -1
  10. package/dist/assets/styles.css.map +1 -1
  11. package/dist/banner.js +14 -30
  12. package/dist/banner.js.map +1 -1
  13. package/dist/{button-DMN1dPAg.js → button-colors-Ccys3hvS.js} +5 -468
  14. package/dist/button-colors-Ccys3hvS.js.map +1 -0
  15. package/dist/button-group.js +228 -8
  16. package/dist/button-group.js.map +1 -1
  17. package/dist/button.js +294 -8
  18. package/dist/button.js.map +1 -1
  19. package/dist/calendar-column-view.js +634 -0
  20. package/dist/calendar-column-view.js.map +1 -0
  21. package/dist/calendar-event-BrQ_SEKD.js +199 -0
  22. package/dist/calendar-event-BrQ_SEKD.js.map +1 -0
  23. package/dist/calendar-month-view.js +376 -0
  24. package/dist/calendar-month-view.js.map +1 -0
  25. package/dist/calendar.js +339 -0
  26. package/dist/calendar.js.map +1 -0
  27. package/dist/canvas.js +361 -0
  28. package/dist/canvas.js.map +1 -0
  29. package/dist/card.js +18 -73
  30. package/dist/card.js.map +1 -1
  31. package/dist/cb-compound-expression.js +125 -0
  32. package/dist/cb-compound-expression.js.map +1 -0
  33. package/dist/cb-divider.js +150 -0
  34. package/dist/cb-divider.js.map +1 -0
  35. package/dist/cb-expression.js +75 -0
  36. package/dist/cb-expression.js.map +1 -0
  37. package/dist/cb-predicate.js +137 -0
  38. package/dist/cb-predicate.js.map +1 -0
  39. package/dist/chart-bar.js.map +1 -1
  40. package/dist/chart-doughnut.js +2 -2
  41. package/dist/chart-doughnut.js.map +1 -1
  42. package/dist/chart-pie.js +2 -2
  43. package/dist/chart-pie.js.map +1 -1
  44. package/dist/chart-stacked-bar.js.map +1 -1
  45. package/dist/code-editor.js +2 -1
  46. package/dist/code-editor.js.map +1 -1
  47. package/dist/code-highlighter.js +2 -1
  48. package/dist/code-highlighter.js.map +1 -1
  49. package/dist/condition-builder.js +58 -0
  50. package/dist/condition-builder.js.map +1 -0
  51. package/dist/custom-elements-jsdocs.json +10860 -5567
  52. package/dist/custom-elements.json +16180 -7996
  53. package/dist/dropdown-button.js +216 -0
  54. package/dist/dropdown-button.js.map +1 -0
  55. package/dist/event-manager-D-QCmUgR.js +113 -0
  56. package/dist/event-manager-D-QCmUgR.js.map +1 -0
  57. package/dist/fab.js +421 -9
  58. package/dist/fab.js.map +1 -1
  59. package/dist/flow-designer-dZnLJOQT.js +1656 -0
  60. package/dist/flow-designer-dZnLJOQT.js.map +1 -0
  61. package/dist/flow-designer-node-XMe-jlKg.js +548 -0
  62. package/dist/flow-designer-node-XMe-jlKg.js.map +1 -0
  63. package/dist/flow-designer-node.js +4 -0
  64. package/dist/flow-designer-node.js.map +1 -0
  65. package/dist/flow-designer.js +16 -0
  66. package/dist/flow-designer.js.map +1 -0
  67. package/dist/html-editor.js +358 -0
  68. package/dist/html-editor.js.map +1 -0
  69. package/dist/icon-button-CK1ZuE-2.js +247 -0
  70. package/dist/icon-button-CK1ZuE-2.js.map +1 -0
  71. package/dist/index.js +31 -8
  72. package/dist/index.js.map +1 -1
  73. package/dist/{is-dark-mode-DicqGkCJ.js → is-dark-mode-DOcaw4Yq.js} +2 -27
  74. package/dist/is-dark-mode-DOcaw4Yq.js.map +1 -0
  75. package/dist/modal.js +418 -0
  76. package/dist/modal.js.map +1 -0
  77. package/dist/{select-4pl4XBj7.js → navigation-rail-DyO0oAZU.js} +2000 -2767
  78. package/dist/navigation-rail-DyO0oAZU.js.map +1 -0
  79. package/dist/notification-manager.js +268 -0
  80. package/dist/notification-manager.js.map +1 -0
  81. package/dist/notification.js +3 -2
  82. package/dist/notification.js.map +1 -1
  83. package/dist/peacock-loader.js +102 -14
  84. package/dist/peacock-loader.js.map +1 -1
  85. package/dist/popover-NC7b1lTq.js +1971 -0
  86. package/dist/popover-NC7b1lTq.js.map +1 -0
  87. package/dist/popover-content.js +125 -0
  88. package/dist/popover-content.js.map +1 -0
  89. package/dist/popover.js +4 -0
  90. package/dist/popover.js.map +1 -0
  91. package/dist/search.js +4 -0
  92. package/dist/search.js.map +1 -1
  93. package/dist/split-button.js +388 -0
  94. package/dist/split-button.js.map +1 -0
  95. package/dist/src/__controllers/floating-controller.d.ts +35 -0
  96. package/dist/src/__mixins/BaseButtonMixin.d.ts +20 -0
  97. package/dist/src/__mixins/BaseHyperlinkMixin.d.ts +18 -0
  98. package/dist/src/__mixins/MixinConstructor.d.ts +1 -0
  99. package/dist/src/banner/banner.d.ts +0 -4
  100. package/dist/src/button/BaseButton.d.ts +4 -47
  101. package/dist/src/button/button/button.d.ts +32 -3
  102. package/dist/src/button/button-group/button-group.d.ts +2 -2
  103. package/dist/src/button/icon-button/icon-button.d.ts +33 -8
  104. package/dist/src/calendar/base-event.d.ts +10 -0
  105. package/dist/src/calendar/calendar-column-view.d.ts +41 -0
  106. package/dist/src/calendar/calendar-event.d.ts +7 -0
  107. package/dist/src/calendar/calendar-month-view.d.ts +31 -0
  108. package/dist/src/calendar/calendar.d.ts +65 -0
  109. package/dist/src/calendar/event-manager.d.ts +17 -0
  110. package/dist/src/calendar/index.d.ts +4 -0
  111. package/dist/src/calendar/types.d.ts +13 -0
  112. package/dist/src/calendar/utils.d.ts +31 -0
  113. package/dist/src/canvas/canvas.d.ts +92 -0
  114. package/dist/src/canvas/index.d.ts +2 -0
  115. package/dist/src/card/card.d.ts +4 -15
  116. package/dist/src/condition-builder/cb-compound-expression.d.ts +31 -0
  117. package/dist/src/condition-builder/cb-divider.d.ts +26 -0
  118. package/dist/src/condition-builder/cb-expression.d.ts +31 -0
  119. package/dist/src/condition-builder/cb-predicate.d.ts +30 -0
  120. package/dist/src/condition-builder/condition-builder.d.ts +27 -0
  121. package/dist/src/condition-builder/index.d.ts +5 -0
  122. package/dist/src/dropdown-button/dropdown-button.d.ts +68 -0
  123. package/dist/src/dropdown-button/index.d.ts +1 -0
  124. package/dist/src/fab/fab.d.ts +4 -35
  125. package/dist/src/flow-designer/commands.d.ts +66 -0
  126. package/dist/src/flow-designer/flow-designer-node.d.ts +46 -0
  127. package/dist/src/flow-designer/flow-designer.d.ts +133 -0
  128. package/dist/src/flow-designer/index.d.ts +7 -0
  129. package/dist/src/flow-designer/layout.d.ts +30 -0
  130. package/dist/src/flow-designer/types.d.ts +142 -0
  131. package/dist/src/flow-designer/validation.d.ts +43 -0
  132. package/dist/src/flow-designer/workflow-utils.d.ts +40 -0
  133. package/dist/src/focus-ring/focus-ring.d.ts +11 -5
  134. package/dist/src/html-editor/html-editor.d.ts +56 -0
  135. package/dist/src/html-editor/index.d.ts +2 -0
  136. package/dist/src/index.d.ts +16 -1
  137. package/dist/src/link/link.d.ts +1 -1
  138. package/dist/src/menu/menu/menu.d.ts +5 -7
  139. package/dist/src/menu/menu-item/menu-item.d.ts +14 -13
  140. package/dist/src/modal/index.d.ts +1 -0
  141. package/dist/src/modal/modal.d.ts +63 -0
  142. package/dist/src/navigation-rail/index.d.ts +2 -0
  143. package/dist/src/navigation-rail/navigation-rail-item.d.ts +55 -0
  144. package/dist/src/navigation-rail/navigation-rail.d.ts +71 -0
  145. package/dist/src/notification-manager/index.d.ts +1 -0
  146. package/dist/src/notification-manager/notification-manager.d.ts +44 -0
  147. package/dist/src/popover/index.d.ts +2 -0
  148. package/dist/src/popover/popover-content.d.ts +29 -0
  149. package/dist/src/popover/popover.d.ts +62 -0
  150. package/dist/src/sidebar-menu/index.d.ts +3 -0
  151. package/dist/src/sidebar-menu/sidebar-menu-item.d.ts +58 -0
  152. package/dist/src/sidebar-menu/sidebar-menu.d.ts +38 -0
  153. package/dist/src/sidebar-menu/sidebar-sub-menu.d.ts +35 -0
  154. package/dist/src/split-button/index.d.ts +1 -0
  155. package/dist/src/split-button/split-button.d.ts +72 -0
  156. package/dist/src/toolbar/toolbar.d.ts +10 -10
  157. package/dist/src/tooltip/tooltip.d.ts +5 -15
  158. package/dist/src/url-field/index.d.ts +1 -0
  159. package/dist/src/url-field/url-field.d.ts +48 -0
  160. package/dist/test/flow-designer.test.d.ts +1 -0
  161. package/dist/test/sidebar-menu.test.d.ts +1 -0
  162. package/dist/toolbar.js +10 -10
  163. package/dist/toolbar.js.map +1 -1
  164. package/dist/tsconfig.tsbuildinfo +1 -1
  165. package/package.json +4 -2
  166. package/readme.md +73 -65
  167. package/scss/mixin.scss +16 -0
  168. package/src/__controllers/floating-controller.ts +237 -0
  169. package/src/__mixins/BaseButtonMixin.ts +83 -0
  170. package/src/__mixins/BaseHyperlinkMixin.ts +68 -0
  171. package/src/__mixins/MixinConstructor.ts +1 -0
  172. package/src/{__base_element → __mixins}/README.md +2 -2
  173. package/src/banner/banner.scss +20 -25
  174. package/src/banner/banner.ts +1 -7
  175. package/src/button/BaseButton.ts +11 -100
  176. package/src/button/button/button-sizes.scss +4 -2
  177. package/src/button/button/button.ts +77 -23
  178. package/src/button/button-group/button-group.ts +2 -2
  179. package/src/button/icon-button/icon-button.ts +75 -33
  180. package/src/calendar/base-event.ts +49 -0
  181. package/src/calendar/calendar-column-view.scss +326 -0
  182. package/src/calendar/calendar-column-view.ts +392 -0
  183. package/src/calendar/calendar-event.ts +20 -0
  184. package/src/calendar/calendar-month-view.scss +192 -0
  185. package/src/calendar/calendar-month-view.ts +244 -0
  186. package/src/calendar/calendar.scss +71 -0
  187. package/src/calendar/calendar.ts +298 -0
  188. package/src/calendar/event-manager.ts +117 -0
  189. package/src/calendar/index.ts +4 -0
  190. package/src/calendar/types.ts +14 -0
  191. package/src/calendar/utils.ts +180 -0
  192. package/src/canvas/canvas.scss +60 -0
  193. package/src/canvas/canvas.ts +391 -0
  194. package/src/canvas/index.ts +2 -0
  195. package/src/card/card.ts +11 -71
  196. package/src/chart-bar/chart-bar.ts +9 -14
  197. package/src/chart-bar/chart-stacked-bar.ts +12 -18
  198. package/src/chart-doughnut/chart-doughnut.ts +23 -27
  199. package/src/chart-pie/chart-pie.ts +19 -23
  200. package/src/checkbox/checkbox.scss +17 -34
  201. package/src/checkbox/checkbox.ts +3 -1
  202. package/src/code-highlighter/code-highlighter.scss +1 -0
  203. package/src/code-highlighter/code-highlighter.ts +1 -1
  204. package/src/condition-builder/cb-compound-expression.scss +37 -0
  205. package/src/condition-builder/cb-compound-expression.ts +80 -0
  206. package/src/condition-builder/cb-divider.scss +93 -0
  207. package/src/condition-builder/cb-divider.ts +56 -0
  208. package/src/condition-builder/cb-expression.scss +14 -0
  209. package/src/condition-builder/cb-expression.ts +49 -0
  210. package/src/condition-builder/cb-predicate.scss +35 -0
  211. package/src/condition-builder/cb-predicate.ts +102 -0
  212. package/src/condition-builder/condition-builder.scss +13 -0
  213. package/src/condition-builder/condition-builder.ts +38 -0
  214. package/src/condition-builder/index.ts +5 -0
  215. package/src/date-picker/date-picker.ts +1 -1
  216. package/src/dropdown-button/demo/index.html +110 -0
  217. package/src/dropdown-button/dropdown-button.scss +22 -0
  218. package/src/dropdown-button/dropdown-button.ts +206 -0
  219. package/src/dropdown-button/index.ts +1 -0
  220. package/src/elevation/elevation.scss +5 -5
  221. package/src/fab/fab.ts +29 -100
  222. package/src/flow-designer/DEMO.md +239 -0
  223. package/src/flow-designer/commands.ts +278 -0
  224. package/src/flow-designer/flow-designer-node.ts +172 -0
  225. package/src/flow-designer/flow-designer.scss +457 -0
  226. package/src/flow-designer/flow-designer.ts +611 -0
  227. package/src/flow-designer/index.ts +41 -0
  228. package/src/flow-designer/layout.ts +357 -0
  229. package/src/flow-designer/types.ts +166 -0
  230. package/src/flow-designer/validation.ts +284 -0
  231. package/src/flow-designer/workflow-utils.ts +282 -0
  232. package/src/focus-ring/focus-ring.ts +47 -40
  233. package/src/html-editor/html-editor.scss +146 -0
  234. package/src/html-editor/html-editor.ts +276 -0
  235. package/src/html-editor/index.ts +3 -0
  236. package/src/index.ts +28 -1
  237. package/src/input/input.ts +3 -1
  238. package/src/link/link.ts +2 -2
  239. package/src/menu/menu/menu.scss +2 -2
  240. package/src/menu/menu/menu.ts +91 -101
  241. package/src/menu/menu-item/menu-item.scss +4 -0
  242. package/src/menu/menu-item/menu-item.ts +85 -79
  243. package/src/modal/index.ts +1 -0
  244. package/src/modal/modal.scss +206 -0
  245. package/src/modal/modal.ts +201 -0
  246. package/src/navigation-rail/index.ts +2 -0
  247. package/src/navigation-rail/navigation-rail-item.scss +216 -0
  248. package/src/navigation-rail/navigation-rail-item.ts +223 -0
  249. package/src/navigation-rail/navigation-rail.scss +72 -0
  250. package/src/navigation-rail/navigation-rail.ts +149 -0
  251. package/src/notification/notification.ts +3 -2
  252. package/src/notification-manager/index.ts +1 -0
  253. package/src/notification-manager/notification-manager.scss +113 -0
  254. package/src/notification-manager/notification-manager.ts +199 -0
  255. package/src/number-field/number-field.ts +6 -4
  256. package/src/pagination/pagination.ts +6 -4
  257. package/src/peacock-loader.ts +93 -5
  258. package/src/popover/index.ts +2 -0
  259. package/src/popover/popover-content.scss +69 -0
  260. package/src/popover/popover-content.ts +51 -0
  261. package/src/popover/popover.scss +7 -0
  262. package/src/popover/popover.ts +170 -0
  263. package/src/search/search.ts +4 -0
  264. package/src/sidebar-menu/demo/index.html +68 -0
  265. package/src/sidebar-menu/index.ts +3 -0
  266. package/src/sidebar-menu/sidebar-menu-item.scss +102 -0
  267. package/src/sidebar-menu/sidebar-menu-item.ts +151 -0
  268. package/src/{tree-view/tree-view.scss → sidebar-menu/sidebar-menu.scss} +1 -1
  269. package/src/sidebar-menu/sidebar-menu.ts +182 -0
  270. package/src/sidebar-menu/sidebar-sub-menu.scss +130 -0
  271. package/src/sidebar-menu/sidebar-sub-menu.ts +160 -0
  272. package/src/skeleton/skeleton.scss +18 -24
  273. package/src/snackbar/snackbar.ts +1 -1
  274. package/src/split-button/index.ts +1 -0
  275. package/src/split-button/split-button-colors.scss +56 -0
  276. package/src/split-button/split-button-sizes.scss +28 -0
  277. package/src/split-button/split-button.scss +79 -0
  278. package/src/split-button/split-button.ts +236 -0
  279. package/src/table/table.ts +2 -2
  280. package/src/tabs/tab.ts +4 -3
  281. package/src/text/text.css-component.scss +7 -1
  282. package/src/time-picker/time-picker.ts +1 -1
  283. package/src/toolbar/toolbar.ts +10 -10
  284. package/src/tooltip/tooltip.scss +4 -3
  285. package/src/tooltip/tooltip.ts +64 -98
  286. package/src/url-field/index.ts +1 -0
  287. package/src/url-field/url-field.scss +50 -0
  288. package/src/url-field/url-field.ts +239 -0
  289. package/dist/button-DMN1dPAg.js.map +0 -1
  290. package/dist/button-group-CX9CUUXk.js +0 -435
  291. package/dist/button-group-CX9CUUXk.js.map +0 -1
  292. package/dist/fab-C5Nzxk0E.js +0 -497
  293. package/dist/fab-C5Nzxk0E.js.map +0 -1
  294. package/dist/is-dark-mode-DicqGkCJ.js.map +0 -1
  295. package/dist/select-4pl4XBj7.js.map +0 -1
  296. package/dist/spread-B5cgadZl.js +0 -32
  297. package/dist/spread-B5cgadZl.js.map +0 -1
  298. package/dist/src/__base_element/BaseHyperlink.d.ts +0 -20
  299. package/dist/src/menu/menu/MenuSurfaceController.d.ts +0 -18
  300. package/dist/src/tree-view/index.d.ts +0 -2
  301. package/dist/src/tree-view/tree-node.d.ts +0 -69
  302. package/dist/src/tree-view/tree-view.d.ts +0 -40
  303. package/dist/src/tree-view/wc-tree-view.d.ts +0 -6
  304. package/dist/test/tree-view.test.d.ts +0 -1
  305. package/dist/throttle-C7ZAPqtu.js +0 -24
  306. package/dist/throttle-C7ZAPqtu.js.map +0 -1
  307. package/src/__base_element/BaseHyperlink.ts +0 -42
  308. package/src/menu/menu/MenuSurfaceController.ts +0 -61
  309. package/src/tree-view/demo/index.html +0 -57
  310. package/src/tree-view/index.ts +0 -2
  311. package/src/tree-view/tree-node.scss +0 -101
  312. package/src/tree-view/tree-node.ts +0 -268
  313. package/src/tree-view/tree-view.ts +0 -182
  314. package/src/tree-view/wc-tree-view.ts +0 -9
@@ -0,0 +1,298 @@
1
+ import { LitElement, html, nothing } from 'lit';
2
+ import { property, state } from 'lit/decorators.js';
3
+ import { addDays, addMonths, formatDate } from './utils.js';
4
+ import { CalendarEvent } from './calendar-event.js';
5
+ import type { CalendarViewType, EventType } from './types.js';
6
+ import IndividualComponent from '@/IndividualComponent.js';
7
+ import styles from './calendar.scss';
8
+
9
+ /**
10
+ * @label Calendar
11
+ * @tag wc-calendar
12
+ * @rawTag calendar
13
+ * @summary A Material 3 inspired full calendar component for displaying events in day, week, or month views.
14
+ *
15
+ * @cssprop --calendar-border-color - Border color used throughout the calendar grid.
16
+ * @cssprop --calendar-event-bg-color - Background color for calendar events.
17
+ * @cssprop --calendar-event-border-color - Left border color for calendar events.
18
+ *
19
+ * @fires {CustomEvent} event-click - Dispatched when a calendar event is clicked. Detail contains `{ event }`.
20
+ * @fires {CustomEvent} view-change - Dispatched when the calendar view changes. Detail contains `{ view }`.
21
+ * @fires {CustomEvent} date-change - Dispatched when the context date changes. Detail contains `{ date }`.
22
+ *
23
+ * @example
24
+ * ```html
25
+ * <wc-calendar view="week" style="height: 600px"></wc-calendar>
26
+ * ```
27
+ */
28
+ @IndividualComponent
29
+ export class Calendar extends LitElement {
30
+ static styles = [styles];
31
+
32
+ /**
33
+ * Calendar events array.
34
+ */
35
+ @property({ type: Array })
36
+ events: EventType[] = [];
37
+
38
+ /**
39
+ * Available views configuration.
40
+ */
41
+ @property({ type: Array, attribute: 'available-views' })
42
+ availableViews: CalendarViewType[] = [
43
+ { label: 'Day', value: 'day', type: 'column', days: 1 },
44
+ { label: 'Week', value: 'week', type: 'column', days: 7 },
45
+ { label: 'Month', value: 'month', type: 'month' },
46
+ ];
47
+
48
+ /**
49
+ * Current calendar view.
50
+ */
51
+ @property({ type: String, reflect: true })
52
+ view: string = 'week';
53
+
54
+ /**
55
+ * Whether events are clickable.
56
+ */
57
+ @property({ type: Boolean, attribute: 'event-clickable' })
58
+ eventClickable: boolean = true;
59
+
60
+ /**
61
+ * Show loading state.
62
+ */
63
+ @property({ type: Boolean, attribute: 'show-loader' })
64
+ showLoader: boolean = false;
65
+
66
+ /**
67
+ * Timezone string (e.g. 'America/New_York').
68
+ */
69
+ @property({ type: String })
70
+ timezone: string = '';
71
+
72
+ /**
73
+ * The context date for the calendar view.
74
+ */
75
+ @property({ type: Object, attribute: false })
76
+ contextDate: Date | null = null;
77
+
78
+ @state()
79
+ private _currentTime: Date = new Date();
80
+
81
+ @state()
82
+ private _currentView: CalendarViewType | undefined;
83
+
84
+ override connectedCallback() {
85
+ super.connectedCallback();
86
+ if (this.timezone) {
87
+ this._currentTime = new Date(
88
+ new Date().toLocaleString('en', { timeZone: this.timezone }),
89
+ );
90
+ } else {
91
+ this._currentTime = new Date();
92
+ }
93
+ if (!this.contextDate) {
94
+ this.contextDate = this._currentTime;
95
+ }
96
+ }
97
+
98
+ override willUpdate(changedProperties: Map<string, unknown>) {
99
+ if (changedProperties.has('view') || changedProperties.has('availableViews')) {
100
+ this._currentView = this.availableViews.find(v => v.value === this.view);
101
+ }
102
+ }
103
+
104
+ private _onColumnViewDateClick(evt: CustomEvent) {
105
+ evt.stopPropagation();
106
+ this.view = 'day';
107
+ this.contextDate = evt.detail.date;
108
+ this.dispatchEvent(
109
+ new CustomEvent('view-change', {
110
+ detail: { view: this.view },
111
+ bubbles: true,
112
+ composed: true,
113
+ }),
114
+ );
115
+ this.dispatchEvent(
116
+ new CustomEvent('date-change', {
117
+ detail: { date: this.contextDate },
118
+ bubbles: true,
119
+ composed: true,
120
+ }),
121
+ );
122
+ }
123
+
124
+ private _onEventClick(evt: CustomEvent) {
125
+ evt.stopPropagation();
126
+ this.dispatchEvent(
127
+ new CustomEvent('event-click', {
128
+ detail: { event: evt.detail.event },
129
+ bubbles: true,
130
+ composed: true,
131
+ }),
132
+ );
133
+ }
134
+
135
+ previous() {
136
+ if (!this._currentView) return;
137
+ if (this._currentView.days) {
138
+ this.contextDate = addDays(
139
+ this.contextDate!,
140
+ -1 * this._currentView.days,
141
+ );
142
+ } else if (this._currentView.type === 'month') {
143
+ this.contextDate = addMonths(this.contextDate!, -1);
144
+ }
145
+ this.dispatchEvent(
146
+ new CustomEvent('date-change', {
147
+ detail: { date: this.contextDate },
148
+ bubbles: true,
149
+ composed: true,
150
+ }),
151
+ );
152
+ }
153
+
154
+ next() {
155
+ if (!this._currentView) return;
156
+ if (this._currentView.days) {
157
+ this.contextDate = addDays(
158
+ this.contextDate!,
159
+ this._currentView.days,
160
+ );
161
+ } else if (this._currentView.type === 'month') {
162
+ this.contextDate = addMonths(this.contextDate!, 1);
163
+ }
164
+ this.dispatchEvent(
165
+ new CustomEvent('date-change', {
166
+ detail: { date: this.contextDate },
167
+ bubbles: true,
168
+ composed: true,
169
+ }),
170
+ );
171
+ }
172
+
173
+ private _goToToday() {
174
+ this.contextDate = this._currentTime;
175
+ this.dispatchEvent(
176
+ new CustomEvent('date-change', {
177
+ detail: { date: this.contextDate },
178
+ bubbles: true,
179
+ composed: true,
180
+ }),
181
+ );
182
+ }
183
+
184
+ private _onViewSegmentChange(evt: CustomEvent<{ value: string | null }>) {
185
+ if (!evt.detail.value) return;
186
+ this.view = evt.detail.value;
187
+ this.dispatchEvent(
188
+ new CustomEvent('view-change', {
189
+ detail: { view: this.view },
190
+ bubbles: true,
191
+ composed: true,
192
+ }),
193
+ );
194
+ }
195
+
196
+ private _renderHeader() {
197
+ return html`
198
+ <div class="calendar-header-classic">
199
+ <div class="header-left">
200
+ <wc-button
201
+ variant="outlined"
202
+ size="sm"
203
+ class="color-secondary"
204
+ @click=${() => this._goToToday()}
205
+ >
206
+ Today
207
+ </wc-button>
208
+ <wc-icon-button
209
+ variant="text"
210
+ size="sm"
211
+ class="color-secondary"
212
+ @click=${() => this.previous()}
213
+ >
214
+ <wc-icon name="chevron_left"></wc-icon>
215
+ </wc-icon-button>
216
+ <wc-icon-button
217
+ variant="text"
218
+ size="sm"
219
+ class="color-secondary"
220
+ @click=${() => this.next()}
221
+ >
222
+ <wc-icon name="chevron_right"></wc-icon>
223
+ </wc-icon-button>
224
+ <div class="title">
225
+ ${this.contextDate
226
+ ? formatDate(this.contextDate, 'MMMM d, yyyy')
227
+ : ''}
228
+ </div>
229
+ </div>
230
+ <div class="header-right">
231
+ <wc-segmented-button-group @change=${this._onViewSegmentChange}>
232
+ ${this.availableViews.map(
233
+ v =>
234
+ html`<wc-segmented-button
235
+ .value=${v.value}
236
+ ?selected=${this.view === v.value}
237
+ >
238
+ ${v.label}
239
+ </wc-segmented-button>`,
240
+ )}
241
+ </wc-segmented-button-group>
242
+ </div>
243
+ </div>
244
+ `;
245
+ }
246
+
247
+ private _renderCalendarView() {
248
+ if (!this._currentView) return html`<div>Invalid view</div>`;
249
+
250
+ const calEvents = this.events.map(
251
+ event =>
252
+ new CalendarEvent(
253
+ event.start,
254
+ event.end,
255
+ event.title,
256
+ event.color,
257
+ event,
258
+ ),
259
+ );
260
+
261
+ if (this._currentView.type === 'column') {
262
+ return html`
263
+ <wc-calendar-column-view
264
+ .events=${calEvents}
265
+ .view=${this._currentView.value}
266
+ .days=${this._currentView.days || 7}
267
+ .currentTime=${this._currentTime}
268
+ .contextDate=${this.contextDate}
269
+ ?event-clickable=${this.eventClickable}
270
+ @column-view-date-click=${this._onColumnViewDateClick}
271
+ @column-view-event-click=${this._onEventClick}
272
+ ></wc-calendar-column-view>
273
+ `;
274
+ } else if (this._currentView.type === 'month') {
275
+ return html`
276
+ <wc-calendar-month-view
277
+ .events=${calEvents}
278
+ .currentTime=${this._currentTime}
279
+ .contextDate=${this.contextDate}
280
+ ?event-clickable=${this.eventClickable}
281
+ @month-view-event-click=${this._onEventClick}
282
+ ></wc-calendar-month-view>
283
+ `;
284
+ }
285
+ return nothing;
286
+ }
287
+
288
+ render() {
289
+ return html`
290
+ <div class="calendar">
291
+ <div class="calendar-header">${this._renderHeader()}</div>
292
+ <div class="calendar-body">
293
+ <div class="view-container">${this._renderCalendarView()}</div>
294
+ </div>
295
+ </div>
296
+ `;
297
+ }
298
+ }
@@ -0,0 +1,117 @@
1
+ import { CalendarEvent } from './calendar-event.js';
2
+
3
+ export class ColumnEvent extends CalendarEvent {
4
+ width: number = 1;
5
+
6
+ constructor(event: CalendarEvent) {
7
+ super(event.start, event.end, event.title, event.color, event.data);
8
+ }
9
+ }
10
+
11
+ export class EventManager {
12
+ #events: ColumnEvent[] = [];
13
+ columns: ColumnEvent[][] = [];
14
+
15
+ addEvents(events: CalendarEvent[]): void {
16
+ events.forEach(event => {
17
+ this.#events.push(new ColumnEvent(event));
18
+ });
19
+ }
20
+
21
+ process(): void {
22
+ this.columns = [];
23
+ let events = this.#events.sort((a, b) => {
24
+ return a.start.valueOf() - b.start.valueOf() || b.length() - a.length();
25
+ });
26
+
27
+ let oldLength: number | null = null;
28
+ /* Bucketing: group non-overlapping events into columns */
29
+ while (events.length) {
30
+ if (oldLength === events.length) {
31
+ throw new Error(
32
+ 'Events not processed in previous run, breaking infinite loop',
33
+ );
34
+ }
35
+ oldLength = events.length;
36
+
37
+ const column: ColumnEvent[] = [];
38
+ for (let i = 0; i < events.length; i++) {
39
+ if (i === 0) {
40
+ column.push(events[i]);
41
+ } else if (events[i].start.valueOf() >= column[column.length - 1].end.valueOf()) {
42
+ column.push(events[i]);
43
+ }
44
+ }
45
+ this.columns.push(column);
46
+ events = events.filter(e => !column.find(ce => ce.gid === e.gid));
47
+ }
48
+
49
+ /* Calculate widths for events that span multiple columns */
50
+ for (let i = 0; i < this.columns.length - 1; i++) {
51
+ this.columns[i].forEach(event => {
52
+ for (let j = i + 1; j < this.columns.length; j++) {
53
+ if (this.columns[j].find(colEvent => event.isOverlapping(colEvent))) {
54
+ break;
55
+ }
56
+ event.width++;
57
+ }
58
+ });
59
+ }
60
+ }
61
+ }
62
+
63
+ export class MonthEventManager {
64
+ #events: ColumnEvent[] = [];
65
+ columns: ColumnEvent[][] = [];
66
+
67
+ addEvents(events: CalendarEvent[]): void {
68
+ events.forEach(event => {
69
+ this.#events.push(new ColumnEvent(event));
70
+ });
71
+ }
72
+
73
+ process(): void {
74
+ this.columns = [];
75
+ let events = this.#events.sort((a, b) => {
76
+ return a.start.valueOf() - b.start.valueOf() || b.length() - a.length();
77
+ });
78
+
79
+ let oldLength: number | null = null;
80
+ while (events.length) {
81
+ if (oldLength === events.length) {
82
+ throw new Error(
83
+ 'Events not processed in previous run, breaking infinite loop',
84
+ );
85
+ }
86
+ oldLength = events.length;
87
+
88
+ const column: ColumnEvent[] = [];
89
+ for (let i = 0; i < events.length; i++) {
90
+ if (i === 0) {
91
+ column.push(events[i]);
92
+ } else {
93
+ const lastEnd = new Date(column[column.length - 1].end);
94
+ lastEnd.setHours(23, 59, 59, 999);
95
+ const nextStart = new Date(events[i].start);
96
+ nextStart.setHours(0, 0, 0, 0);
97
+ if (nextStart.valueOf() > lastEnd.valueOf()) {
98
+ column.push(events[i]);
99
+ }
100
+ }
101
+ }
102
+ this.columns.push(column);
103
+ events = events.filter(e => !column.find(ce => ce.gid === e.gid));
104
+ }
105
+
106
+ for (let i = 0; i < this.columns.length - 1; i++) {
107
+ this.columns[i].forEach(event => {
108
+ for (let j = i + 1; j < this.columns.length; j++) {
109
+ if (this.columns[j].find(colEvent => event.isOverlapping(colEvent))) {
110
+ break;
111
+ }
112
+ event.width++;
113
+ }
114
+ });
115
+ }
116
+ }
117
+ }
@@ -0,0 +1,4 @@
1
+ export { Calendar } from './calendar.js';
2
+ export { CalendarColumnView } from './calendar-column-view.js';
3
+ export { CalendarMonthView } from './calendar-month-view.js';
4
+ export type { CalendarViewType, EventType } from './types.js';
@@ -0,0 +1,14 @@
1
+ export type CalendarViewType = {
2
+ label: string;
3
+ value: string;
4
+ type: 'column' | 'month';
5
+ days?: number;
6
+ };
7
+
8
+ export type EventType = {
9
+ start: Date;
10
+ end: Date;
11
+ title: string;
12
+ color?: string;
13
+ [key: string]: any;
14
+ };
@@ -0,0 +1,180 @@
1
+ /**
2
+ * Pure date utility functions (no external dependencies).
3
+ */
4
+
5
+ export function startOfDay(date: Date): Date {
6
+ const d = new Date(date);
7
+ d.setHours(0, 0, 0, 0);
8
+ return d;
9
+ }
10
+
11
+ export function endOfDay(date: Date): Date {
12
+ const d = new Date(date);
13
+ d.setHours(23, 59, 59, 999);
14
+ return d;
15
+ }
16
+
17
+ export function addDays(date: Date, days: number): Date {
18
+ const d = new Date(date);
19
+ d.setDate(d.getDate() + days);
20
+ return d;
21
+ }
22
+
23
+ export function addMonths(date: Date, months: number): Date {
24
+ const d = new Date(date);
25
+ d.setMonth(d.getMonth() + months);
26
+ return d;
27
+ }
28
+
29
+ export function addHours(date: Date, hours: number): Date {
30
+ const d = new Date(date);
31
+ d.setHours(d.getHours() + hours);
32
+ return d;
33
+ }
34
+
35
+ export function differenceInDays(dateA: Date, dateB: Date): number {
36
+ const a = startOfDay(dateA);
37
+ const b = startOfDay(dateB);
38
+ return Math.round((a.valueOf() - b.valueOf()) / 86400000);
39
+ }
40
+
41
+ export function startOfWeek(
42
+ date: Date,
43
+ weekStartsOn: 0 | 1 | 2 | 3 | 4 | 5 | 6 = 1,
44
+ ): Date {
45
+ const d = startOfDay(date);
46
+ const day = d.getDay();
47
+ const diff = (day < weekStartsOn ? 7 : 0) + day - weekStartsOn;
48
+ d.setDate(d.getDate() - diff);
49
+ return d;
50
+ }
51
+
52
+ export function endOfWeek(
53
+ date: Date,
54
+ weekStartsOn: 0 | 1 | 2 | 3 | 4 | 5 | 6 = 1,
55
+ ): Date {
56
+ const d = startOfWeek(date, weekStartsOn);
57
+ d.setDate(d.getDate() + 6);
58
+ return endOfDay(d);
59
+ }
60
+
61
+ export function startOfMonth(date: Date): Date {
62
+ const d = new Date(date);
63
+ d.setDate(1);
64
+ d.setHours(0, 0, 0, 0);
65
+ return d;
66
+ }
67
+
68
+ export function endOfMonth(date: Date): Date {
69
+ const d = new Date(date);
70
+ d.setMonth(d.getMonth() + 1, 0);
71
+ d.setHours(23, 59, 59, 999);
72
+ return d;
73
+ }
74
+
75
+ export function calculateMonthRange(
76
+ date: Date,
77
+ weekStartsOn: 0 | 1 | 2 | 3 | 4 | 5 | 6 = 1,
78
+ ) {
79
+ const sd = startOfWeek(startOfMonth(date), weekStartsOn);
80
+ const ed = endOfWeek(endOfMonth(date), weekStartsOn);
81
+ return { startDate: sd, endDate: ed, totalDays: 42 };
82
+ }
83
+
84
+ export function calculateWeekRange(
85
+ date: Date,
86
+ weekStartsOn: 0 | 1 | 2 | 3 | 4 | 5 | 6 = 1,
87
+ ) {
88
+ const sd = startOfWeek(date, weekStartsOn);
89
+ const ed = endOfWeek(date, weekStartsOn);
90
+ return { startDate: sd, endDate: ed, totalDays: 7 };
91
+ }
92
+
93
+ export function calculateDateRange(
94
+ view: string,
95
+ contextDate: Date,
96
+ days: number,
97
+ ) {
98
+ if (view === 'week') {
99
+ return calculateWeekRange(contextDate, 1);
100
+ }
101
+ return {
102
+ startDate: startOfDay(contextDate),
103
+ endDate: endOfDay(addDays(contextDate, days - 1)),
104
+ totalDays: days,
105
+ };
106
+ }
107
+
108
+ export const LONG_EVENT_PADDING = 0.25;
109
+
110
+ const DAY_NAMES_SHORT = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
111
+ const DAY_NAMES_LONG = [
112
+ 'Sunday',
113
+ 'Monday',
114
+ 'Tuesday',
115
+ 'Wednesday',
116
+ 'Thursday',
117
+ 'Friday',
118
+ 'Saturday',
119
+ ];
120
+ const MONTH_NAMES = [
121
+ 'January',
122
+ 'February',
123
+ 'March',
124
+ 'April',
125
+ 'May',
126
+ 'June',
127
+ 'July',
128
+ 'August',
129
+ 'September',
130
+ 'October',
131
+ 'November',
132
+ 'December',
133
+ ];
134
+
135
+ export function formatDate(date: Date, pattern: string): string {
136
+ const day = date.getDate();
137
+ const dayOfWeek = date.getDay();
138
+ const month = date.getMonth();
139
+ const year = date.getFullYear();
140
+ const hours = date.getHours();
141
+ const minutes = date.getMinutes();
142
+
143
+ switch (pattern) {
144
+ case 'MMMM d, yyyy':
145
+ return `${MONTH_NAMES[month]} ${day}, ${year}`;
146
+ case 'EEEE':
147
+ return DAY_NAMES_LONG[dayOfWeek];
148
+ case 'E':
149
+ return DAY_NAMES_SHORT[dayOfWeek];
150
+ case 'd':
151
+ return `${day}`;
152
+ case 'dd':
153
+ return day < 10 ? `0${day}` : `${day}`;
154
+ case 'hh a': {
155
+ const h = hours % 12 || 12;
156
+ const ampm = hours < 12 ? 'AM' : 'PM';
157
+ return `${h < 10 ? '0' : ''}${h} ${ampm}`;
158
+ }
159
+ case 'hh:mm a': {
160
+ const h = hours % 12 || 12;
161
+ const ampm = hours < 12 ? 'AM' : 'PM';
162
+ return `${h < 10 ? '0' : ''}${h}:${minutes < 10 ? '0' : ''}${minutes} ${ampm}`;
163
+ }
164
+ case 'dd-MM-yyyy':
165
+ return `${day < 10 ? '0' : ''}${day}-${month + 1 < 10 ? '0' : ''}${month + 1}-${year}`;
166
+ default:
167
+ return date.toLocaleDateString();
168
+ }
169
+ }
170
+
171
+ export function getTimePercent(date: Date, forDay?: Date): number {
172
+ const day = forDay || date;
173
+ const sd = startOfDay(day);
174
+ const ed = endOfDay(day);
175
+ const percent =
176
+ ((date.valueOf() - sd.valueOf()) / (ed.valueOf() - sd.valueOf())) * 100;
177
+ if (percent < 0) return 0;
178
+ if (percent > 100) return 100;
179
+ return percent;
180
+ }
@@ -0,0 +1,60 @@
1
+ @use '../../scss/mixin';
2
+
3
+ @include mixin.base-styles;
4
+
5
+ :host {
6
+ display: block;
7
+ --canvas-background: var(--color-surface-container-low);
8
+ --canvas-dot-color: var(--color-outline-variant);
9
+ --canvas-line-color: var(--color-on-surface);
10
+ --canvas-hover-color: var(--color-primary);
11
+ --canvas-arrow-color: var(--color-on-surface);
12
+ }
13
+
14
+ .canvas-wrapper {
15
+ background: var(--canvas-background);
16
+ border-radius: var(--shape-corner-medium);
17
+ }
18
+
19
+ #canvas-background circle {
20
+ fill: var(--canvas-dot-color);
21
+ }
22
+
23
+ #endarrow polyline {
24
+ fill: none;
25
+ stroke: var(--canvas-arrow-color);
26
+ vector-effect: non-scaling-stroke;
27
+ stroke-width: 2;
28
+ }
29
+
30
+ .line {
31
+ &.no-color {
32
+ stroke: var(--canvas-line-color);
33
+ }
34
+
35
+ &.variant-dashed {
36
+ stroke-dasharray: 6 6;
37
+ }
38
+
39
+ &.variant-animated-dashed {
40
+ animation: canvas-dash-flow 600ms linear infinite;
41
+ }
42
+ }
43
+
44
+ .clickable {
45
+ cursor: pointer;
46
+
47
+ &:hover .line {
48
+ stroke: var(--canvas-hover-color);
49
+ }
50
+ }
51
+
52
+ .line.clickable:hover {
53
+ stroke: var(--canvas-hover-color);
54
+ }
55
+
56
+ @keyframes canvas-dash-flow {
57
+ to {
58
+ stroke-dashoffset: -12;
59
+ }
60
+ }