@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
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@redvars/peacock",
3
3
  "description": "The foundation for beautiful user interfaces",
4
4
  "license": "Apache-2.0",
5
- "version": "3.5.1",
5
+ "version": "3.6.1",
6
6
  "type": "module",
7
7
  "main": "dist/index.js",
8
8
  "module": "dist/index.js",
@@ -17,7 +17,9 @@
17
17
  "private": false,
18
18
  "exports": {
19
19
  ".": "./dist/src/index.js",
20
- "./icon.js": "./dist/src/index.js"
20
+ "./icon.js": "./dist/src/index.js",
21
+ "./flow-designer.js": "./dist/src/flow-designer/flow-designer.js",
22
+ "./flow-designer-node.js": "./dist/src/flow-designer/flow-designer-node.js"
21
23
  },
22
24
  "files": [
23
25
  "src",
@@ -39,6 +41,12 @@
39
41
  "test:watch": "tsc && concurrently -k -r \"tsc --watch --preserveWatchOutput\" \"wtr --watch\""
40
42
  },
41
43
  "dependencies": {
44
+ "@tiptap/core": "^2.11.3",
45
+ "@tiptap/extension-mention": "^2.11.3",
46
+ "@tiptap/extension-placeholder": "^2.11.3",
47
+ "@tiptap/extension-underline": "^2.11.3",
48
+ "@tiptap/pm": "^2.11.3",
49
+ "@tiptap/starter-kit": "^2.11.3",
42
50
  "@floating-ui/dom": "^1.7.5",
43
51
  "@types/prettier": "^3.0.0",
44
52
  "d3": "^7.9.0",
package/readme.md CHANGED
@@ -44,9 +44,9 @@ Visit [https://peacock.redvars.com](https://peacock.redvars.com) to view the doc
44
44
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
45
45
  <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+Mono:wght@100..900&family=Noto+Sans:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
46
46
 
47
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@redvars/peacock@3.5.1/dist/assets/styles.css"></link>
47
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@redvars/peacock@3.6.1/dist/assets/styles.css"></link>
48
48
  <script type='module'
49
- src='https://cdn.jsdelivr.net/npm/@redvars/peacock@3.5.1/dist/peacock-loader.js'></script>
49
+ src='https://cdn.jsdelivr.net/npm/@redvars/peacock@3.6.1/dist/peacock-loader.js'></script>
50
50
  </head>
51
51
 
52
52
  <wc-button>Button</wc-button>
@@ -74,7 +74,7 @@ menus, checkboxes, and radio buttons.
74
74
  | Date time picker | datetime-picker | 🔴 |
75
75
  | [Field / Form control](https://peacock.redvars.com/components/field) | wc-field | 🟡 |
76
76
  | File picker | file-picker | 🔴 |
77
- | HTML editor | html-editor | 🔴 |
77
+ | [HTML editor](https://peacock.redvars.com/components/html-editor) | wc-html-editor | 🟡 |
78
78
  | [Input](https://peacock.redvars.com/components/input) | wc-input | 🟢 |
79
79
  | Input URL | input-url | 🔴 |
80
80
  | Month picker | month-picker | 🔴 |
@@ -0,0 +1,237 @@
1
+ import {
2
+ computePosition,
3
+ autoUpdate,
4
+ offset,
5
+ flip,
6
+ shift,
7
+ arrow,
8
+ Placement,
9
+ Strategy,
10
+ Middleware,
11
+ } from '@floating-ui/dom';
12
+ import { ReactiveController, ReactiveControllerHost } from 'lit';
13
+
14
+ export type TriggerType =
15
+ | 'hover'
16
+ | 'click'
17
+ | 'context-menu'
18
+ | 'manual'
19
+ | 'focus'
20
+ | 'hover-focus';
21
+
22
+ export interface FloatingOptions {
23
+ placement?: Placement;
24
+ strategy?: Strategy;
25
+ offset?: number;
26
+ trigger?: TriggerType;
27
+ closeOnClickOutside?: boolean;
28
+ onOpenChange?: (isOpen: boolean) => void;
29
+ }
30
+
31
+ export class FloatingController implements ReactiveController {
32
+ private host: ReactiveControllerHost;
33
+
34
+ private reference: HTMLElement | null = null;
35
+
36
+ private floating: HTMLElement | null = null;
37
+
38
+ private arrowElement: HTMLElement | null = null;
39
+
40
+ private cleanup: (() => void) | null = null;
41
+
42
+ private options: Required<FloatingOptions>;
43
+
44
+ private isHostConnected = false;
45
+
46
+ public isOpen = false;
47
+
48
+ constructor(host: ReactiveControllerHost, options: FloatingOptions = {}) {
49
+ this.options = {
50
+ placement: options.placement || 'bottom',
51
+ strategy: options.strategy || 'absolute',
52
+ offset: options.offset ?? 8,
53
+ trigger: options.trigger || 'hover',
54
+ closeOnClickOutside: options.closeOnClickOutside ?? true,
55
+ onOpenChange: options.onOpenChange ?? (() => undefined),
56
+ };
57
+ this.host = host;
58
+ this.host.addController(this);
59
+ }
60
+
61
+ hostConnected() {
62
+ this.isHostConnected = true;
63
+ if (this.options.closeOnClickOutside) {
64
+ document.addEventListener('mousedown', this.handleOutsideClick);
65
+ }
66
+ }
67
+
68
+ hostDisconnected() {
69
+ this.isHostConnected = false;
70
+ this.cleanup?.();
71
+ this.removeEventListeners();
72
+ document.removeEventListener('mousedown', this.handleOutsideClick);
73
+ }
74
+
75
+ setElements(reference: HTMLElement, floating: HTMLElement, arrowElement?: HTMLElement) {
76
+ this.cleanup?.();
77
+ this.cleanup = null;
78
+ this.removeEventListeners();
79
+ this.reference = reference;
80
+ this.floating = floating;
81
+ this.arrowElement = arrowElement || null;
82
+ this.setupEventListeners();
83
+ if (this.isOpen) {
84
+ this.updatePosition();
85
+ }
86
+ }
87
+
88
+ setOptions(options: Partial<FloatingOptions>) {
89
+ const previousTrigger = this.options.trigger;
90
+ const previousCloseOnClickOutside = this.options.closeOnClickOutside;
91
+
92
+ this.options = {
93
+ ...this.options,
94
+ ...options,
95
+ onOpenChange: options.onOpenChange ?? this.options.onOpenChange,
96
+ };
97
+
98
+ if (this.reference && previousTrigger !== this.options.trigger) {
99
+ this.removeEventListeners();
100
+ this.setupEventListeners();
101
+ }
102
+
103
+ if (this.isHostConnected && previousCloseOnClickOutside !== this.options.closeOnClickOutside) {
104
+ document.removeEventListener('mousedown', this.handleOutsideClick);
105
+ if (this.options.closeOnClickOutside) {
106
+ document.addEventListener('mousedown', this.handleOutsideClick);
107
+ }
108
+ }
109
+
110
+ if (this.isOpen) {
111
+ this.updatePosition();
112
+ }
113
+ }
114
+
115
+ private setupEventListeners() {
116
+ if (!this.reference) return;
117
+
118
+ if (this.options.trigger === 'hover' || this.options.trigger === 'hover-focus') {
119
+ this.reference.addEventListener('mouseenter', this.open);
120
+ this.reference.addEventListener('mouseleave', this.close);
121
+ }
122
+
123
+ if (this.options.trigger === 'click') {
124
+ this.reference.addEventListener('click', this.toggle);
125
+ }
126
+
127
+ if (this.options.trigger === 'context-menu') {
128
+ this.reference.addEventListener('contextmenu', this.handleContextMenu);
129
+ }
130
+
131
+ if (this.options.trigger === 'focus' || this.options.trigger === 'hover-focus') {
132
+ this.reference.addEventListener('focusin', this.open);
133
+ this.reference.addEventListener('focusout', this.handleFocusOut);
134
+ }
135
+ }
136
+
137
+ private removeEventListeners() {
138
+ if (!this.reference) return;
139
+ this.reference.removeEventListener('mouseenter', this.open);
140
+ this.reference.removeEventListener('mouseleave', this.close);
141
+ this.reference.removeEventListener('click', this.toggle);
142
+ this.reference.removeEventListener('contextmenu', this.handleContextMenu);
143
+ this.reference.removeEventListener('focusin', this.open);
144
+ this.reference.removeEventListener('focusout', this.handleFocusOut);
145
+ }
146
+
147
+ private toggle = () => (this.isOpen ? this.close() : this.open());
148
+
149
+ private handleContextMenu = (e: MouseEvent) => {
150
+ e.preventDefault();
151
+ this.open();
152
+ };
153
+
154
+ private handleFocusOut = (e: FocusEvent) => {
155
+ if (!this.reference || this.reference.contains(e.relatedTarget as Node)) return;
156
+ this.close();
157
+ };
158
+
159
+ private handleOutsideClick = (e: MouseEvent) => {
160
+ if (
161
+ this.isOpen &&
162
+ this.reference &&
163
+ this.floating &&
164
+ !this.reference.contains(e.target as Node) &&
165
+ !this.floating.contains(e.target as Node)
166
+ ) {
167
+ this.close();
168
+ }
169
+ };
170
+
171
+ open = () => {
172
+ if (this.isOpen) return;
173
+ this.isOpen = true;
174
+ this.options.onOpenChange(this.isOpen);
175
+ this.host.requestUpdate();
176
+ this.updatePosition();
177
+ };
178
+
179
+ close = () => {
180
+ if (!this.isOpen) return;
181
+ this.isOpen = false;
182
+ this.options.onOpenChange(this.isOpen);
183
+ this.cleanup?.();
184
+ this.cleanup = null;
185
+ this.host.requestUpdate();
186
+ };
187
+
188
+ private updatePosition() {
189
+ if (!this.reference || !this.floating) return;
190
+
191
+ this.cleanup = autoUpdate(this.reference, this.floating, () => {
192
+ if (!this.reference || !this.floating) return;
193
+
194
+ const middleware: Middleware[] = [
195
+ offset(this.options.offset),
196
+ flip(),
197
+ shift({ padding: 5 }),
198
+ ];
199
+
200
+ if (this.arrowElement) {
201
+ middleware.push(arrow({ element: this.arrowElement }));
202
+ }
203
+
204
+ computePosition(this.reference, this.floating, {
205
+ placement: this.options.placement,
206
+ strategy: this.options.strategy,
207
+ middleware,
208
+ }).then(({ x, y, placement, middlewareData }) => {
209
+ if (!this.floating) return;
210
+
211
+ Object.assign(this.floating.style, {
212
+ left: `${x}px`,
213
+ top: `${y}px`,
214
+ position: this.options.strategy,
215
+ });
216
+
217
+ if (this.arrowElement && middlewareData.arrow) {
218
+ const { x: ax, y: ay } = middlewareData.arrow;
219
+ const staticSide = {
220
+ top: 'bottom',
221
+ right: 'left',
222
+ bottom: 'top',
223
+ left: 'right',
224
+ }[placement.split('-')[0]]!;
225
+
226
+ Object.assign(this.arrowElement.style, {
227
+ left: ax != null ? `${ax}px` : '',
228
+ top: ay != null ? `${ay}px` : '',
229
+ right: '',
230
+ bottom: '',
231
+ [staticSide]: '-4px',
232
+ });
233
+ }
234
+ });
235
+ });
236
+ }
237
+ }
@@ -11,7 +11,7 @@
11
11
  background: var(--banner-container-color);
12
12
  border-radius: var(--banner-border-radius);
13
13
  display: grid;
14
- gap: var(--spacing-200);
14
+ gap: var(--spacing-100);
15
15
  grid-template-columns: auto 1fr;
16
16
  padding: var(--spacing-200);
17
17
  }
@@ -21,8 +21,7 @@
21
21
  color: var(--banner-icon-color);
22
22
  display: inline-flex;
23
23
  justify-content: center;
24
- min-width: 1.5rem;
25
- padding-top: 0.1rem;
24
+ --icon-size: 1.5rem;
26
25
  }
27
26
 
28
27
  .banner-content {
@@ -196,6 +196,7 @@ export class Button extends BaseButton {
196
196
  href=${this.href}
197
197
  target=${this.target}
198
198
  tabindex=${this.disabled ? '-1' : '0'}
199
+
199
200
  @click=${this.__dispatchClick}
200
201
  @mousedown=${this.__handlePress}
201
202
  @keydown=${this.__handlePress}
@@ -0,0 +1,49 @@
1
+ import { startOfDay, endOfDay } from './utils.js';
2
+
3
+ export class BaseEvent {
4
+ gid: string;
5
+ start: Date;
6
+ end: Date;
7
+
8
+ constructor(start: Date, end: Date) {
9
+ this.gid = crypto.randomUUID();
10
+ this.start = start;
11
+ this.end = end;
12
+ }
13
+
14
+ length(): number {
15
+ return this.end.valueOf() - this.start.valueOf();
16
+ }
17
+
18
+ isOverlapping(event: BaseEvent): boolean {
19
+ let totalLength: number;
20
+ if (this.start.valueOf() <= event.start.valueOf()) {
21
+ totalLength = event.end.valueOf() - this.start.valueOf();
22
+ } else {
23
+ totalLength = this.end.valueOf() - event.start.valueOf();
24
+ }
25
+ return this.length() + event.length() >= totalLength;
26
+ }
27
+
28
+ isOverlappingWithoutTime(event: BaseEvent): boolean {
29
+ const thisStartDay = startOfDay(this.start);
30
+ const eventStartDay = startOfDay(event.start);
31
+ const thisEndDay = endOfDay(this.end);
32
+ const eventEndDay = endOfDay(event.end);
33
+
34
+ let totalLength: number;
35
+ if (thisStartDay.valueOf() <= eventStartDay.valueOf()) {
36
+ totalLength = eventEndDay.valueOf() - thisStartDay.valueOf();
37
+ } else {
38
+ totalLength = thisEndDay.valueOf() - eventStartDay.valueOf();
39
+ }
40
+ return this.length() + event.length() >= totalLength;
41
+ }
42
+
43
+ isOverlappingWithDate(date: Date): boolean {
44
+ return (
45
+ this.start.valueOf() <= date.valueOf() &&
46
+ this.end.valueOf() >= date.valueOf()
47
+ );
48
+ }
49
+ }
@@ -0,0 +1,326 @@
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: 4rem;
11
+ }
12
+
13
+ .scale {
14
+ width: var(--scale-size);
15
+ flex-shrink: 0;
16
+ }
17
+
18
+ .calendar-column-view {
19
+ display: flex;
20
+ flex-direction: column;
21
+ height: 100%;
22
+ }
23
+
24
+ /* ── Header ── */
25
+ .view-header {
26
+ display: flex;
27
+ background: var(--color-surface-container);
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;
46
+ gap: 0.5rem;
47
+ border-top: 3px solid transparent;
48
+ }
49
+
50
+ &.today .column-content {
51
+ border-top-color: var(--color-primary);
52
+
53
+ .date {
54
+ color: var(--color-on-primary);
55
+ background: var(--color-primary);
56
+ }
57
+ }
58
+
59
+ .date {
60
+ font-size: 1.5rem;
61
+ font-weight: 500;
62
+ cursor: pointer;
63
+ border-radius: 50%;
64
+ width: 2.5rem;
65
+ height: 2.5rem;
66
+ display: flex;
67
+ align-items: center;
68
+ justify-content: center;
69
+ color: var(--color-on-surface);
70
+ transition: background 200ms ease;
71
+
72
+ &:hover {
73
+ background: var(--color-primary-90);
74
+ }
75
+ }
76
+
77
+ .day {
78
+ font-size: 0.875rem;
79
+ font-weight: 500;
80
+ color: var(--color-on-surface-variant);
81
+ }
82
+ }
83
+ }
84
+
85
+ .scrollbar-placeholder {
86
+ width: var(--scrollbar-width, 0px);
87
+ }
88
+ }
89
+
90
+ /* ── Multi-day section ── */
91
+ .multi-day-section-wrapper {
92
+ background: var(--color-surface-container);
93
+ border-bottom: 1px solid var(--calendar-border-color);
94
+
95
+ .multi-day-section-scroll {
96
+ overflow-y: auto;
97
+ max-height: 6rem;
98
+ }
99
+
100
+ .multi-day-section {
101
+ position: relative;
102
+ }
103
+
104
+ .multi-day-background {
105
+ display: flex;
106
+ height: 100%;
107
+ position: absolute;
108
+ width: 100%;
109
+
110
+ .columns {
111
+ display: flex;
112
+ flex: 1;
113
+
114
+ .column {
115
+ flex: 1;
116
+ border-inline-start: 1px solid var(--calendar-border-color);
117
+
118
+ &:first-child {
119
+ border-inline-start: 0;
120
+ }
121
+ }
122
+ }
123
+ }
124
+
125
+ .multi-events {
126
+ padding: 0 0 0 var(--scale-size);
127
+
128
+ .row {
129
+ height: 1.8rem;
130
+ box-sizing: content-box;
131
+ position: relative;
132
+ padding-bottom: 0.25rem;
133
+
134
+ &:last-child {
135
+ padding-bottom: 0;
136
+ }
137
+ }
138
+
139
+ .row-spacer {
140
+ height: 0.75rem;
141
+ }
142
+
143
+ .event {
144
+ position: absolute;
145
+ height: 1.8rem;
146
+ text-overflow: ellipsis;
147
+ overflow: hidden;
148
+ }
149
+ }
150
+ }
151
+
152
+ /* ── View body ── */
153
+ .view-body {
154
+ height: 100%;
155
+ border-bottom: 1px solid var(--calendar-border-color);
156
+ overflow-y: auto;
157
+
158
+ .view-body-scroll {
159
+ display: flex;
160
+ position: relative;
161
+
162
+ .scale {
163
+ border-right: 1px solid var(--calendar-scale-color);
164
+
165
+ .background {
166
+ border-inline-start: 1rem;
167
+ }
168
+
169
+ .row {
170
+ width: 0;
171
+ position: relative;
172
+ height: 2rem;
173
+ border-bottom: 1px dashed var(--calendar-scale-color);
174
+
175
+ &.hour {
176
+ border-bottom: 1px solid var(--calendar-scale-color);
177
+ width: 50%;
178
+ margin-inline-start: 50%;
179
+ }
180
+
181
+ &:last-child {
182
+ border-bottom: 0;
183
+ }
184
+
185
+ .time {
186
+ position: absolute;
187
+ top: -0.5rem;
188
+ font-size: 0.75rem;
189
+ color: var(--color-on-surface-variant);
190
+ }
191
+ }
192
+ }
193
+
194
+ .drawing-area {
195
+ flex: 1;
196
+ position: relative;
197
+
198
+ .background {
199
+ position: relative;
200
+ width: 100%;
201
+ height: 100%;
202
+
203
+ .row {
204
+ height: 2rem;
205
+ border-bottom: 1px dashed var(--calendar-scale-color);
206
+ display: flex;
207
+
208
+ &.hour {
209
+ border-bottom: 1px solid var(--calendar-scale-color);
210
+ }
211
+
212
+ &:last-child {
213
+ border-bottom: 0;
214
+ }
215
+
216
+ .column {
217
+ flex: 1;
218
+ border-inline-start: 1px solid var(--calendar-border-color);
219
+
220
+ &:first-child {
221
+ border-inline-start: 0;
222
+ }
223
+
224
+ &.today {
225
+ background: color-mix(in srgb, var(--color-primary) 4%, transparent);
226
+ }
227
+ }
228
+ }
229
+ }
230
+
231
+ .events-container {
232
+ position: absolute;
233
+ top: 0;
234
+ left: 0;
235
+ width: 100%;
236
+ height: 100%;
237
+ display: flex;
238
+
239
+ .column {
240
+ flex: 1;
241
+ padding: 0 0.5rem 0 1px;
242
+
243
+ .column-content {
244
+ position: relative;
245
+ height: 100%;
246
+ }
247
+
248
+ .event {
249
+ position: absolute;
250
+ }
251
+ }
252
+ }
253
+ }
254
+
255
+ /* ── Current time line ── */
256
+ .current-time-line {
257
+ position: absolute;
258
+ z-index: 100;
259
+ pointer-events: none;
260
+ width: calc(100% - var(--scale-size));
261
+ margin-inline-start: var(--scale-size);
262
+
263
+ .time {
264
+ position: absolute;
265
+ @include mixin.get-typography(label-small);
266
+ color: var(--color-on-primary-container);
267
+ transform: translate(calc(-100% - 2px), -50%);
268
+ background: var(--color-primary-container);
269
+ padding: 2px 4px;
270
+ border-radius: var(--shape-corner-extra-small);
271
+ }
272
+
273
+ .dash-line {
274
+ position: absolute;
275
+ left: 0;
276
+ border-bottom: 1px dashed var(--color-primary);
277
+ }
278
+
279
+ .dot {
280
+ border-radius: 50%;
281
+ width: 0.5rem;
282
+ height: 0.5rem;
283
+ background: var(--color-primary);
284
+ display: block;
285
+ position: absolute;
286
+ top: -0.25rem;
287
+ }
288
+
289
+ .line {
290
+ border-bottom: 2px solid var(--color-primary);
291
+ position: absolute;
292
+ top: -1px;
293
+ }
294
+ }
295
+ }
296
+ }
297
+
298
+ /* ── Event styles ── */
299
+ .event {
300
+ background: var(--calendar-event-bg-color);
301
+ border-inline-start: 0.25rem solid var(--calendar-event-border-color);
302
+ border-radius: var(--shape-corner-extra-small);
303
+ transition: background 150ms ease;
304
+
305
+ .event-title {
306
+ padding: 0.25rem 0.375rem;
307
+ font-size: 0.75rem;
308
+ font-weight: 500;
309
+ color: var(--calendar-event-text-color);
310
+ white-space: nowrap;
311
+ overflow: hidden;
312
+ text-overflow: ellipsis;
313
+ }
314
+
315
+ &.clickable {
316
+ cursor: pointer;
317
+
318
+ &:hover {
319
+ background: var(--calendar-event-bg-color--hover);
320
+
321
+ .event-title {
322
+ color: var(--calendar-event-text-color--hover);
323
+ }
324
+ }
325
+ }
326
+ }