@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,391 @@
1
+ import { html, LitElement, svg, nothing } from 'lit';
2
+ import { property } from 'lit/decorators.js';
3
+ import { classMap } from 'lit/directives/class-map.js';
4
+ import IndividualComponent from '@/IndividualComponent.js';
5
+ import styles from './canvas.scss';
6
+
7
+ export type CanvasDirection = 'up' | 'down' | 'left' | 'right';
8
+
9
+ export type CanvasStrokeVariant = 'solid' | 'dashed' | 'animated-dashed';
10
+
11
+ export interface CanvasPoint {
12
+ x: number;
13
+ y: number;
14
+ }
15
+
16
+ export interface CanvasPathSegment {
17
+ direction: CanvasDirection;
18
+ length: number;
19
+ }
20
+
21
+ interface BaseCanvasShape {
22
+ color?: string;
23
+ }
24
+
25
+ interface BaseCanvasStrokeShape extends BaseCanvasShape {
26
+ variant?: CanvasStrokeVariant;
27
+ showArrow?: boolean;
28
+ clickable?: boolean;
29
+ }
30
+
31
+ export interface CanvasCircleShape extends BaseCanvasShape {
32
+ type: 'circle';
33
+ x?: number;
34
+ y?: number;
35
+ radius?: number;
36
+ }
37
+
38
+ export interface CanvasRectShape extends BaseCanvasShape {
39
+ type: 'rect';
40
+ x?: number;
41
+ y?: number;
42
+ width?: number;
43
+ height?: number;
44
+ }
45
+
46
+ export interface CanvasLineShape extends BaseCanvasStrokeShape {
47
+ type: 'line';
48
+ start?: CanvasPoint;
49
+ end?: CanvasPoint;
50
+ }
51
+
52
+ export interface CanvasConnectorShape extends BaseCanvasStrokeShape {
53
+ type: 'connector';
54
+ start?: CanvasPoint;
55
+ path?: CanvasPathSegment[];
56
+ }
57
+
58
+ export type CanvasShape =
59
+ | CanvasCircleShape
60
+ | CanvasRectShape
61
+ | CanvasLineShape
62
+ | CanvasConnectorShape;
63
+
64
+ interface CanvasBounds {
65
+ x: number;
66
+ y: number;
67
+ width: number;
68
+ height: number;
69
+ }
70
+
71
+ /**
72
+ * @label Canvas
73
+ * @tag wc-canvas
74
+ * @rawTag canvas
75
+ * @summary A Material 3 inspired SVG canvas for drawing shapes, lines, and connectors on a dotted grid.
76
+ *
77
+ * @cssprop --canvas-background - Background color for the canvas wrapper. Defaults to surface-container-low.
78
+ * @cssprop --canvas-dot-color - Color of the background grid dots. Defaults to outline-variant.
79
+ * @cssprop --canvas-line-color - Default stroke color for lines and connectors. Defaults to on-surface.
80
+ * @cssprop --canvas-hover-color - Stroke color on hover for clickable shapes. Defaults to primary.
81
+ * @cssprop --canvas-arrow-color - Stroke color for arrow markers. Defaults to on-surface.
82
+ *
83
+ * @example
84
+ * ```html
85
+ * <wc-canvas id="my-canvas"></wc-canvas>
86
+ * <script>
87
+ * document.querySelector('#my-canvas').shapes = [
88
+ * { type: 'circle', x: 0, y: 0, radius: 0.25, color: 'red' },
89
+ * ];
90
+ * </script>
91
+ * ```
92
+ */
93
+ @IndividualComponent
94
+ export class Canvas extends LitElement {
95
+ static styles = [styles];
96
+
97
+ /**
98
+ * Array of shape objects to render on the canvas.
99
+ */
100
+ @property({ type: Array })
101
+ shapes: CanvasShape[] = [];
102
+
103
+ /**
104
+ * Padding around the computed viewbox (in grid units).
105
+ */
106
+ @property({ type: Number, reflect: true })
107
+ padding: number = 1;
108
+
109
+ /**
110
+ * Zoom multiplier for the canvas dimensions.
111
+ */
112
+ @property({ type: Number, reflect: true })
113
+ zoom: number = 1;
114
+
115
+ /**
116
+ * Optional viewbox override string (e.g. "0 0 100 100").
117
+ */
118
+ @property({ type: String })
119
+ viewbox?: string;
120
+
121
+ private unitSize: number = 1;
122
+
123
+ private gap: number = this.unitSize * 10;
124
+
125
+ private static getNextPoint(
126
+ point: CanvasPoint,
127
+ direction: CanvasDirection,
128
+ length: number,
129
+ ): CanvasPoint {
130
+ if (direction === 'down') return { x: point.x, y: point.y + length };
131
+ if (direction === 'up') return { x: point.x, y: point.y - length };
132
+ if (direction === 'left') return { x: point.x - length, y: point.y };
133
+ if (direction === 'right') return { x: point.x + length, y: point.y };
134
+ return { x: point.x, y: point.y };
135
+ }
136
+
137
+ private static updateComputationArea(
138
+ point: CanvasPoint,
139
+ area: CanvasBounds,
140
+ ): CanvasBounds {
141
+ const nextArea = { ...area };
142
+ if (point.x > nextArea.width) nextArea.width = point.x;
143
+ else if (point.x < nextArea.x) nextArea.x = point.x;
144
+ if (point.y > nextArea.height) nextArea.height = point.y;
145
+ else if (point.y < nextArea.y) nextArea.y = point.y;
146
+ return nextArea;
147
+ }
148
+
149
+ private static getStrokeVariantClasses(variant?: CanvasStrokeVariant) {
150
+ return {
151
+ line: true,
152
+ 'no-color': false,
153
+ 'variant-dashed': variant === 'dashed' || variant === 'animated-dashed',
154
+ 'variant-animated-dashed': variant === 'animated-dashed',
155
+ };
156
+ }
157
+
158
+ private computeShapes(initialBounds: CanvasBounds) {
159
+ const dotRadius = this.unitSize;
160
+ let computedViewbox = { ...initialBounds };
161
+
162
+ const shapes = this.shapes.map(shape => {
163
+ switch (shape.type) {
164
+ case 'circle': {
165
+ const r = shape.radius || 1;
166
+ const cx = shape.x || 0;
167
+ const cy = shape.y || 0;
168
+ if (cx + Math.ceil(r) > computedViewbox.width)
169
+ computedViewbox.width = cx + Math.ceil(r);
170
+ if (cx - Math.ceil(r) < computedViewbox.x)
171
+ computedViewbox.x = cx - Math.ceil(r);
172
+ if (cy + Math.ceil(r) > computedViewbox.height)
173
+ computedViewbox.height = cy + Math.ceil(r);
174
+ if (cy - Math.ceil(r) < computedViewbox.y)
175
+ computedViewbox.y = cy - Math.ceil(r);
176
+
177
+ return svg`<circle
178
+ cx=${cx * this.gap + dotRadius}
179
+ cy=${cy * this.gap + dotRadius}
180
+ r=${r * this.gap}
181
+ fill=${shape.color || 'var(--canvas-line-color, var(--color-on-surface))'}
182
+ />`;
183
+ }
184
+ case 'rect': {
185
+ const w = shape.width || 1;
186
+ const h = shape.height || 1;
187
+ const rx = shape.x || 0;
188
+ const ry = shape.y || 0;
189
+ if (rx + Math.ceil(w) > computedViewbox.width)
190
+ computedViewbox.width = rx + Math.ceil(w);
191
+ if (rx - Math.ceil(w) < computedViewbox.x)
192
+ computedViewbox.x = rx - Math.ceil(w);
193
+ if (ry + Math.ceil(h) > computedViewbox.height)
194
+ computedViewbox.height = ry + Math.ceil(h);
195
+ if (ry - Math.ceil(h) < computedViewbox.y)
196
+ computedViewbox.y = ry - Math.ceil(h);
197
+
198
+ return svg`<rect
199
+ x=${rx * this.gap + dotRadius}
200
+ y=${ry * this.gap}
201
+ width=${w * this.gap + dotRadius}
202
+ height=${h * this.gap + dotRadius}
203
+ fill=${shape.color || 'var(--canvas-line-color, var(--color-on-surface))'}
204
+ />`;
205
+ }
206
+ case 'line': {
207
+ const start = shape.start || { x: 0, y: 0 };
208
+ const end = shape.end || { x: 0, y: 0 };
209
+ const pathString = `M${start.x * this.gap + dotRadius} ${start.y * this.gap + dotRadius} L${end.x * this.gap + dotRadius} ${end.y * this.gap + dotRadius}`;
210
+ const strokeColor =
211
+ shape.color ||
212
+ 'var(--canvas-line-color, var(--color-on-surface))';
213
+
214
+ return svg`<path
215
+ class=${classMap({
216
+ ...Canvas.getStrokeVariantClasses(shape.variant),
217
+ clickable: !!shape.clickable,
218
+ 'no-color': !shape.color,
219
+ })}
220
+ stroke-width="2"
221
+ stroke-linecap="round"
222
+ stroke-linejoin="round"
223
+ stroke=${strokeColor}
224
+ marker-end=${shape.showArrow ? 'url(#endarrow)' : ''}
225
+ d=${pathString}
226
+ stroke-dasharray=${shape.variant === 'dashed' || shape.variant === 'animated-dashed' ? '6,6' : nothing}
227
+ fill="none"
228
+ />`;
229
+ }
230
+ case 'connector': {
231
+ const start = shape.start || { x: 0, y: 0 };
232
+ let pathString = `M${start.x * this.gap + dotRadius} ${start.y * this.gap + dotRadius}`;
233
+ let current = { ...start };
234
+ computedViewbox = Canvas.updateComputationArea(current, computedViewbox);
235
+
236
+ const pathSegments = shape.path || [];
237
+ for (let i = 0; i < pathSegments.length; i += 1) {
238
+ const path = pathSegments[i];
239
+
240
+ if (i === 0) {
241
+ const point = Canvas.getNextPoint(current, path.direction, 1);
242
+ pathString += ` L${point.x * this.gap + dotRadius} ${point.y * this.gap + dotRadius}`;
243
+ current = { ...point };
244
+ computedViewbox = Canvas.updateComputationArea(current, computedViewbox);
245
+ }
246
+
247
+ const point = Canvas.getNextPoint(
248
+ current,
249
+ path.direction,
250
+ path.length - 2,
251
+ );
252
+ pathString += ` L${point.x * this.gap + dotRadius} ${point.y * this.gap + dotRadius}`;
253
+ current = { ...point };
254
+ computedViewbox = Canvas.updateComputationArea(current, computedViewbox);
255
+
256
+ if (i === pathSegments.length - 1) {
257
+ const endPoint = Canvas.getNextPoint(current, path.direction, 1);
258
+ pathString += ` L${endPoint.x * this.gap + dotRadius} ${endPoint.y * this.gap + dotRadius}`;
259
+ current = { ...endPoint };
260
+ computedViewbox = Canvas.updateComputationArea(current, computedViewbox);
261
+ } else {
262
+ const nextPath = pathSegments[i + 1];
263
+ const midPoint = Canvas.getNextPoint(current, path.direction, 1);
264
+ const nextPoint = Canvas.getNextPoint(
265
+ midPoint,
266
+ nextPath.direction,
267
+ 1,
268
+ );
269
+ pathString += ` Q ${midPoint.x * this.gap + dotRadius} ${midPoint.y * this.gap + dotRadius} ${nextPoint.x * this.gap + dotRadius} ${nextPoint.y * this.gap + dotRadius}`;
270
+ current = { ...nextPoint };
271
+ computedViewbox = Canvas.updateComputationArea(current, computedViewbox);
272
+ }
273
+ }
274
+
275
+ const strokeColor =
276
+ shape.color ||
277
+ 'var(--canvas-line-color, var(--color-on-surface))';
278
+
279
+ return svg`<g class=${classMap({ clickable: !!shape.clickable })}>
280
+ <path
281
+ class=${classMap({
282
+ ...Canvas.getStrokeVariantClasses(shape.variant),
283
+ 'no-color': !shape.color,
284
+ })}
285
+ stroke-width="2"
286
+ stroke-linecap="round"
287
+ stroke-linejoin="round"
288
+ stroke=${strokeColor}
289
+ marker-end=${shape.showArrow ? 'url(#endarrow)' : ''}
290
+ d=${pathString}
291
+ stroke-dasharray=${shape.variant === 'dashed' || shape.variant === 'animated-dashed' ? '6,6' : nothing}
292
+ fill="none"
293
+ />
294
+ <path
295
+ stroke-width="10"
296
+ stroke-linecap="round"
297
+ stroke-linejoin="round"
298
+ stroke="transparent"
299
+ d=${pathString}
300
+ fill="none"
301
+ />
302
+ </g>`;
303
+ }
304
+ default:
305
+ return nothing;
306
+ }
307
+ });
308
+
309
+ // Padding
310
+ computedViewbox.x -= this.padding;
311
+ computedViewbox.y -= this.padding;
312
+ computedViewbox.width += this.padding;
313
+ computedViewbox.height += this.padding;
314
+ computedViewbox.width -= computedViewbox.x;
315
+ computedViewbox.height -= computedViewbox.y;
316
+
317
+ return { shapes, computedViewbox };
318
+ }
319
+
320
+ protected render() {
321
+ const dotRadius = this.unitSize;
322
+ let computedViewBox = { width: 0, height: 0, x: 0, y: 0 };
323
+
324
+ const { shapes, computedViewbox } = this.computeShapes(computedViewBox);
325
+ computedViewBox = computedViewbox;
326
+
327
+ if (this.viewbox) {
328
+ const viewBox = this.viewbox.split(' ');
329
+ computedViewBox = {
330
+ x: parseInt(viewBox[0], 10),
331
+ y: parseInt(viewBox[1], 10),
332
+ width: parseInt(viewBox[2], 10),
333
+ height: parseInt(viewBox[3], 10),
334
+ };
335
+ }
336
+
337
+ const wrapperWidth =
338
+ (computedViewBox.width * this.gap + 2) * dotRadius * this.zoom;
339
+ const wrapperHeight =
340
+ (computedViewBox.height * this.gap + 2) * dotRadius * this.zoom;
341
+
342
+ const svgViewBox = `${computedViewBox.x * this.gap} ${computedViewBox.y * this.gap} ${computedViewBox.width * this.gap + 2 * dotRadius} ${computedViewBox.height * this.gap + 2 * dotRadius}`;
343
+
344
+ return html`
345
+ <div
346
+ class="canvas-wrapper"
347
+ style="width: ${wrapperWidth}px; height: ${wrapperHeight}px;"
348
+ >
349
+ <svg
350
+ class="canvas"
351
+ height="100%"
352
+ width="100%"
353
+ viewBox=${svgViewBox}
354
+ >
355
+ <defs>
356
+ <pattern
357
+ id="canvas-background"
358
+ patternUnits="userSpaceOnUse"
359
+ width=${this.gap}
360
+ height=${this.gap}
361
+ >
362
+ <circle cx="1" cy="1" r=${dotRadius} />
363
+ </pattern>
364
+
365
+ <marker
366
+ id="endarrow"
367
+ markerWidth="15"
368
+ markerHeight="22.5"
369
+ refX="9"
370
+ refY="15"
371
+ markerUnits="userSpaceOnUse"
372
+ orient="auto"
373
+ >
374
+ <polyline points="0 22.5, 7.5 15, 0 7.5"></polyline>
375
+ </marker>
376
+ </defs>
377
+
378
+ <rect
379
+ x=${computedViewBox.x * this.gap}
380
+ y=${computedViewBox.y * this.gap}
381
+ width="100%"
382
+ height="100%"
383
+ fill="url(#canvas-background)"
384
+ />
385
+
386
+ ${shapes}
387
+ </svg>
388
+ </div>
389
+ `;
390
+ }
391
+ }
@@ -0,0 +1,2 @@
1
+ export { Canvas } from './canvas.js';
2
+ export type { CanvasShape } from './canvas.js';
@@ -171,7 +171,7 @@ export class CodeHighlighter extends LitElement {
171
171
  <div class="header-title">${this.language}</div>
172
172
  <div class="header-actions">
173
173
  <wc-icon-button
174
- color="dark"
174
+ color="surface"
175
175
  variant="text"
176
176
  size="xs"
177
177
  aria-label=${locale.copyToClipboard}
@@ -0,0 +1,37 @@
1
+ @use '../../scss/mixin';
2
+
3
+ @include mixin.base-styles;
4
+
5
+ :host {
6
+ display: block;
7
+ }
8
+
9
+ .compound-expression {
10
+ display: flex;
11
+ padding-top: var(--spacing-200);
12
+
13
+ .field-name-container {
14
+ display: flex;
15
+ flex-direction: column;
16
+ padding-top: var(--spacing-100);
17
+ padding-right: var(--spacing-200);
18
+
19
+ .field-label {
20
+ @include mixin.get-typography-not-important(label-medium);
21
+ color: var(--color-on-surface-variant);
22
+ }
23
+
24
+ .field-compound-type {
25
+ flex: 1;
26
+ padding-bottom: var(--spacing-250);
27
+ }
28
+ }
29
+
30
+ .conditions {
31
+ flex: 1;
32
+ }
33
+ }
34
+
35
+ .slot-end {
36
+ display: block;
37
+ }
@@ -0,0 +1,80 @@
1
+ import { html, LitElement, nothing } from 'lit';
2
+ import { property } from 'lit/decorators.js';
3
+ import IndividualComponent from '@/IndividualComponent.js';
4
+ import styles from './cb-compound-expression.scss';
5
+
6
+ /**
7
+ * @label CB Compound Expression
8
+ * @tag wc-cb-compound-expression
9
+ * @rawTag cb-compound-expression
10
+ * @summary A compound expression group in a condition builder that displays a field label, an optional condition operator divider, and slots for child expressions.
11
+ * @tags condition-builder
12
+ * @parentRawTag compound-builder
13
+ *
14
+ * @example
15
+ * ```html
16
+ * <wc-cb-compound-expression field-label="Age" condition-operator="or">
17
+ * <wc-cb-expression>
18
+ * <wc-input placeholder="Enter value"></wc-input>
19
+ * </wc-cb-expression>
20
+ * </wc-cb-compound-expression>
21
+ * ```
22
+ */
23
+ @IndividualComponent
24
+ export class CbCompoundExpression extends LitElement {
25
+ static styles = [styles];
26
+
27
+ /** The logical operator joining conditions in this group ('and' or 'or'). */
28
+ @property({ type: String, attribute: 'condition-operator', reflect: true })
29
+ conditionOperator?: 'and' | 'or';
30
+
31
+ /** The field name for the compound expression. */
32
+ @property({ type: String, attribute: 'field-name' })
33
+ fieldName = '';
34
+
35
+ /** The display label for the field. */
36
+ @property({ type: String, attribute: 'field-label' })
37
+ fieldLabel = '';
38
+
39
+ override updated() {
40
+ this.__adjustSlotEndPadding();
41
+ }
42
+
43
+ private __adjustSlotEndPadding() {
44
+ const slotEnd = this.renderRoot.querySelector<HTMLElement>('.slot-end');
45
+ const fieldNameContainer =
46
+ this.renderRoot.querySelector<HTMLElement>('.field-name-container');
47
+ if (slotEnd && fieldNameContainer) {
48
+ slotEnd.style.paddingInlineStart =
49
+ fieldNameContainer.getBoundingClientRect().width + 'px';
50
+ }
51
+ }
52
+
53
+ private __renderOperatorDivider() {
54
+ if (!this.conditionOperator) return nothing;
55
+ return html`
56
+ <wc-cb-divider connect-end>
57
+ <wc-tag color="yellow" size="sm">${this.conditionOperator}</wc-tag>
58
+ </wc-cb-divider>
59
+ `;
60
+ }
61
+
62
+ render() {
63
+ return html`
64
+ <div class="compound-expression" field-name=${this.fieldName}>
65
+ <div class="field-name-container">
66
+ <span class="field-label">${this.fieldLabel}</span>
67
+ <div class="field-compound-type">
68
+ ${this.__renderOperatorDivider()}
69
+ </div>
70
+ </div>
71
+ <div class="conditions">
72
+ <slot></slot>
73
+ </div>
74
+ </div>
75
+ <div class="slot-end">
76
+ <slot name="end"></slot>
77
+ </div>
78
+ `;
79
+ }
80
+ }
@@ -0,0 +1,93 @@
1
+ @use '../../scss/mixin';
2
+
3
+ @include mixin.base-styles;
4
+
5
+ :host {
6
+ display: block;
7
+ height: 100%;
8
+ width: 100%;
9
+ --cb-divider-line-color: var(--color-outline-variant);
10
+ }
11
+
12
+ .divider {
13
+ display: flex;
14
+ }
15
+
16
+ .divider:not(.vertical) {
17
+ height: 100%;
18
+ flex-direction: column;
19
+ align-items: center;
20
+ justify-content: center;
21
+ padding-bottom: var(--spacing-200);
22
+
23
+ .line {
24
+ height: 100%;
25
+ }
26
+
27
+ &.connect-start .line-start {
28
+ width: 1rem;
29
+ margin-left: 1rem;
30
+ border-inline-start: 1px solid var(--cb-divider-line-color);
31
+ border-top: 1px solid var(--cb-divider-line-color);
32
+ border-radius: var(--shape-corner-extra-small) 0 0 0;
33
+ }
34
+
35
+ &:not(.connect-start) .line-start {
36
+ border-inline-start: 1px solid var(--cb-divider-line-color);
37
+ }
38
+
39
+ &.connect-end .line-end {
40
+ width: 1rem;
41
+ margin-left: 1rem;
42
+ border-inline-start: 1px solid var(--cb-divider-line-color);
43
+ border-bottom: 1px solid var(--cb-divider-line-color);
44
+ border-radius: 0 0 0 var(--shape-corner-extra-small);
45
+ }
46
+
47
+ &:not(.connect-end) .line-end {
48
+ border-inline-start: 1px solid var(--cb-divider-line-color);
49
+ }
50
+
51
+ .content {
52
+ padding: var(--spacing-050) 0;
53
+ }
54
+ }
55
+
56
+ .divider.vertical {
57
+ width: 100%;
58
+ flex-direction: row;
59
+ align-items: center;
60
+ justify-content: center;
61
+
62
+ .line {
63
+ width: 100%;
64
+ }
65
+
66
+ &.connect-start .line-start {
67
+ height: 1rem;
68
+ margin-top: 1rem;
69
+ border-top: 1px solid var(--cb-divider-line-color);
70
+ border-left: 1px solid var(--cb-divider-line-color);
71
+ border-radius: var(--shape-corner-extra-small) 0 0 0;
72
+ }
73
+
74
+ &:not(.connect-start) .line-start {
75
+ border-top: 1px solid var(--cb-divider-line-color);
76
+ }
77
+
78
+ &.connect-end .line-end {
79
+ height: 1rem;
80
+ margin-top: 1rem;
81
+ border-top: 1px solid var(--cb-divider-line-color);
82
+ border-right: 1px solid var(--cb-divider-line-color);
83
+ border-radius: 0 var(--shape-corner-extra-small) 0 0;
84
+ }
85
+
86
+ &:not(.connect-end) .line-end {
87
+ border-top: 1px solid var(--cb-divider-line-color);
88
+ }
89
+
90
+ .content {
91
+ padding: 0 var(--spacing-050);
92
+ }
93
+ }
@@ -0,0 +1,56 @@
1
+ import { html, LitElement } from 'lit';
2
+ import { property } from 'lit/decorators.js';
3
+ import { classMap } from 'lit/directives/class-map.js';
4
+ import IndividualComponent from '@/IndividualComponent.js';
5
+ import styles from './cb-divider.scss';
6
+
7
+ /**
8
+ * @label CB Divider
9
+ * @tag wc-cb-divider
10
+ * @rawTag cb-divider
11
+ * @summary A divider line used within a condition builder to visually connect expressions with operator tags.
12
+ * @tags condition-builder
13
+ * @parentRawTag compound-builder
14
+ *
15
+ * @example
16
+ * ```html
17
+ * <wc-cb-divider>
18
+ * <wc-tag color="green">and</wc-tag>
19
+ * </wc-cb-divider>
20
+ * ```
21
+ */
22
+ @IndividualComponent
23
+ export class CbDivider extends LitElement {
24
+ static styles = [styles];
25
+
26
+ /** Whether to render the divider vertically instead of horizontally. */
27
+ @property({ type: Boolean, reflect: true })
28
+ vertical = false;
29
+
30
+ /** Whether to render a connecting line at the start. */
31
+ @property({ type: Boolean, reflect: true, attribute: 'connect-start' })
32
+ connectStart = false;
33
+
34
+ /** Whether to render a connecting line at the end. */
35
+ @property({ type: Boolean, reflect: true, attribute: 'connect-end' })
36
+ connectEnd = false;
37
+
38
+ render() {
39
+ const classes = {
40
+ divider: true,
41
+ 'connect-start': this.connectStart,
42
+ 'connect-end': this.connectEnd,
43
+ vertical: this.vertical,
44
+ };
45
+
46
+ return html`
47
+ <div class=${classMap(classes)}>
48
+ <div class="line line-start"></div>
49
+ <div class="content">
50
+ <slot></slot>
51
+ </div>
52
+ <div class="line line-end"></div>
53
+ </div>
54
+ `;
55
+ }
56
+ }
@@ -0,0 +1,14 @@
1
+ @use '../../scss/mixin';
2
+
3
+ @include mixin.base-styles;
4
+
5
+ :host {
6
+ display: block;
7
+ }
8
+
9
+ .expression {
10
+ display: flex;
11
+ gap: var(--spacing-100);
12
+ align-items: center;
13
+ padding-bottom: var(--spacing-200);
14
+ }