@redvars/peacock 3.6.2 → 3.7.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 (200) hide show
  1. package/dist/ButtonConstants-D06bY4uy.js +114 -0
  2. package/dist/ButtonConstants-D06bY4uy.js.map +1 -0
  3. package/dist/{BaseHyperlinkMixin-BNuwbiEf.js → NativeHyperlinkMixin-DrYXyfMQ.js} +8 -10
  4. package/dist/NativeHyperlinkMixin-DrYXyfMQ.js.map +1 -0
  5. package/dist/assets/components.css +1 -1
  6. package/dist/assets/components.css.map +1 -1
  7. package/dist/assets/styles.css +1 -1
  8. package/dist/assets/styles.css.map +1 -1
  9. package/dist/button-colors-Dwnez1tR.js +586 -0
  10. package/dist/button-colors-Dwnez1tR.js.map +1 -0
  11. package/dist/button-group.js +8 -8
  12. package/dist/button-group.js.map +1 -1
  13. package/dist/button.js +236 -133
  14. package/dist/button.js.map +1 -1
  15. package/dist/calendar-column-view.js +0 -1
  16. package/dist/calendar-column-view.js.map +1 -1
  17. package/dist/calendar-month-view.js +0 -1
  18. package/dist/calendar-month-view.js.map +1 -1
  19. package/dist/canvas.js +126 -107
  20. package/dist/canvas.js.map +1 -1
  21. package/dist/card-content.js +0 -1
  22. package/dist/card-content.js.map +1 -1
  23. package/dist/card.js +96 -90
  24. package/dist/card.js.map +1 -1
  25. package/dist/cb-compound-expression.js +4 -1
  26. package/dist/cb-compound-expression.js.map +1 -1
  27. package/dist/cb-divider.js +0 -1
  28. package/dist/cb-divider.js.map +1 -1
  29. package/dist/cb-expression.js +0 -2
  30. package/dist/cb-expression.js.map +1 -1
  31. package/dist/cb-predicate.js +0 -1
  32. package/dist/cb-predicate.js.map +1 -1
  33. package/dist/code-highlighter.js +23 -6
  34. package/dist/code-highlighter.js.map +1 -1
  35. package/dist/custom-elements-jsdocs.json +5079 -17882
  36. package/dist/custom-elements.json +19272 -19314
  37. package/dist/fab.js +181 -117
  38. package/dist/fab.js.map +1 -1
  39. package/dist/flow-designer.js +4 -4
  40. package/dist/icon-button-DJ0kZXYr.js +318 -0
  41. package/dist/icon-button-DJ0kZXYr.js.map +1 -0
  42. package/dist/index.js +7 -7
  43. package/dist/{navigation-rail-CD7IrqbN.js → navigation-rail-CM_svs5_.js} +1311 -730
  44. package/dist/navigation-rail-CM_svs5_.js.map +1 -0
  45. package/dist/observe-slot-change-D8Xg-kSS.js +60 -0
  46. package/dist/observe-slot-change-D8Xg-kSS.js.map +1 -0
  47. package/dist/peacock-loader.js +10 -7
  48. package/dist/peacock-loader.js.map +1 -1
  49. package/dist/popover-content.js +0 -1
  50. package/dist/popover-content.js.map +1 -1
  51. package/dist/search.js +15 -15
  52. package/dist/search.js.map +1 -1
  53. package/dist/src/__controllers/attachable-controller.d.ts +109 -0
  54. package/dist/src/__mixins/{BaseButtonMixin.d.ts → NativeButtonMixin.d.ts} +3 -3
  55. package/dist/src/__mixins/{BaseHyperlinkMixin.d.ts → NativeHyperlinkMixin.d.ts} +3 -4
  56. package/dist/src/__utils/is-link.d.ts +1 -0
  57. package/dist/src/__utils/observe-slot-change.d.ts +1 -1
  58. package/dist/src/accordion/accordion-item.d.ts +0 -1
  59. package/dist/src/breadcrumb/breadcrumb-item/breadcrumb-item.d.ts +0 -1
  60. package/dist/src/button/ButtonConstants.d.ts +1 -0
  61. package/dist/src/button/GroupButtonInterface.d.ts +4 -0
  62. package/dist/src/button/button/button.d.ts +32 -7
  63. package/dist/src/button/button-group/button-group.d.ts +2 -1
  64. package/dist/src/button/icon-button/icon-button.d.ts +26 -5
  65. package/dist/src/button/index.d.ts +1 -1
  66. package/dist/src/calendar/calendar-column-view.d.ts +0 -1
  67. package/dist/src/calendar/calendar-month-view.d.ts +0 -1
  68. package/dist/src/canvas/canvas.d.ts +3 -3
  69. package/dist/src/card/card-content.d.ts +0 -1
  70. package/dist/src/card/card.d.ts +9 -6
  71. package/dist/src/chip/chip/chip.d.ts +22 -3
  72. package/dist/src/condition-builder/cb-compound-expression.d.ts +0 -1
  73. package/dist/src/condition-builder/cb-divider.d.ts +0 -1
  74. package/dist/src/condition-builder/cb-expression.d.ts +0 -1
  75. package/dist/src/condition-builder/cb-predicate.d.ts +0 -1
  76. package/dist/src/fab/fab.d.ts +20 -6
  77. package/dist/src/field/field.d.ts +1 -0
  78. package/dist/src/focus-ring/focus-ring.d.ts +26 -20
  79. package/dist/src/image/image.d.ts +2 -2
  80. package/dist/src/index.d.ts +1 -0
  81. package/dist/src/input/input.d.ts +1 -3
  82. package/dist/src/item/index.d.ts +1 -0
  83. package/dist/src/item/item.d.ts +49 -0
  84. package/dist/src/link/link.d.ts +1 -1
  85. package/dist/src/list/list-item.d.ts +1 -2
  86. package/dist/src/menu/menu-item/menu-item.d.ts +9 -11
  87. package/dist/src/menu/sub-menu/sub-menu.d.ts +1 -1
  88. package/dist/src/navigation-rail/navigation-rail-item.d.ts +0 -2
  89. package/dist/src/navigation-rail/navigation-rail.d.ts +2 -6
  90. package/dist/src/popover/popover-content.d.ts +0 -1
  91. package/dist/src/ripple/ripple.d.ts +9 -1
  92. package/dist/src/search/search.d.ts +2 -6
  93. package/dist/src/segmented-button/segmented-button.d.ts +0 -1
  94. package/dist/src/select/option.d.ts +0 -1
  95. package/dist/src/sidebar-menu/sidebar-menu-item.d.ts +0 -1
  96. package/dist/src/sidebar-menu/sidebar-sub-menu.d.ts +0 -1
  97. package/dist/src/tabs/tab-panel.d.ts +0 -1
  98. package/dist/src/tabs/tab.d.ts +4 -6
  99. package/dist/test/item.test.d.ts +1 -0
  100. package/dist/tsconfig.tsbuildinfo +1 -1
  101. package/package.json +4 -2
  102. package/readme.md +2 -2
  103. package/scss/components.scss +0 -1
  104. package/scss/mixin.scss +33 -13
  105. package/scss/styles.scss +1 -3
  106. package/src/__controllers/attachable-controller.ts +198 -0
  107. package/src/__mixins/NativeButtonMixin.ts +87 -0
  108. package/src/__mixins/{BaseHyperlinkMixin.ts → NativeHyperlinkMixin.ts} +15 -15
  109. package/src/__utils/is-link.ts +3 -0
  110. package/src/__utils/observe-slot-change.ts +46 -14
  111. package/src/accordion/accordion-item.scss +1 -1
  112. package/src/accordion/accordion-item.ts +0 -1
  113. package/src/breadcrumb/breadcrumb-item/breadcrumb-item.ts +0 -1
  114. package/src/button/ButtonConstants.ts +1 -0
  115. package/src/button/GroupButtonInterface.ts +4 -0
  116. package/src/button/button/button-colors.scss +2 -2
  117. package/src/button/button/button-layers.scss +124 -0
  118. package/src/button/button/button-sizes.scss +31 -53
  119. package/src/button/button/button.scss +139 -262
  120. package/src/button/button/button.ts +260 -106
  121. package/src/button/button/only-button.scss +13 -0
  122. package/src/button/button-group/button-group.ts +59 -17
  123. package/src/button/icon-button/icon-button-sizes.scss +12 -27
  124. package/src/button/icon-button/icon-button.ts +191 -83
  125. package/src/button/index.ts +1 -1
  126. package/src/calendar/calendar-column-view.ts +0 -1
  127. package/src/calendar/calendar-month-view.ts +0 -1
  128. package/src/canvas/canvas.scss +18 -6
  129. package/src/canvas/canvas.ts +125 -103
  130. package/src/card/card-content.ts +2 -3
  131. package/src/card/card.scss +87 -95
  132. package/src/card/card.ts +62 -60
  133. package/src/chip/chip/chip.scss +66 -71
  134. package/src/chip/chip/chip.ts +155 -56
  135. package/src/code-highlighter/code-highlighter.scss +1 -1
  136. package/src/code-highlighter/code-highlighter.ts +20 -5
  137. package/src/condition-builder/cb-compound-expression.scss +4 -0
  138. package/src/condition-builder/cb-compound-expression.ts +0 -1
  139. package/src/condition-builder/cb-divider.ts +0 -1
  140. package/src/condition-builder/cb-expression.scss +0 -1
  141. package/src/condition-builder/cb-expression.ts +0 -1
  142. package/src/condition-builder/cb-predicate.ts +0 -1
  143. package/src/elevation/elevation.scss +5 -1
  144. package/src/empty-state/empty-state.scss +1 -0
  145. package/src/fab/fab-colors.scss +2 -2
  146. package/src/fab/fab-sizes.scss +24 -34
  147. package/src/fab/fab.scss +77 -71
  148. package/src/fab/fab.ts +141 -65
  149. package/src/field/field.ts +6 -0
  150. package/src/focus-ring/focus-ring.ts +81 -72
  151. package/src/image/image.scss +21 -16
  152. package/src/image/image.ts +13 -14
  153. package/src/index.ts +1 -0
  154. package/src/input/input.ts +16 -25
  155. package/src/item/index.ts +1 -0
  156. package/src/item/item.scss +195 -0
  157. package/src/item/item.ts +362 -0
  158. package/src/link/link.scss +1 -10
  159. package/src/link/link.ts +4 -2
  160. package/src/list/list-item.ts +8 -8
  161. package/src/menu/menu/menu.ts +5 -9
  162. package/src/menu/menu-item/menu-item.scss +30 -108
  163. package/src/menu/menu-item/menu-item.ts +102 -133
  164. package/src/menu/sub-menu/sub-menu.ts +6 -3
  165. package/src/navigation-rail/navigation-rail-item.scss +5 -0
  166. package/src/navigation-rail/navigation-rail-item.ts +10 -15
  167. package/src/navigation-rail/navigation-rail.ts +2 -6
  168. package/src/peacock-loader.ts +5 -1
  169. package/src/popover/popover-content.ts +0 -1
  170. package/src/ripple/ripple.ts +52 -20
  171. package/src/search/search.scss +3 -0
  172. package/src/search/search.ts +11 -16
  173. package/src/segmented-button/segmented-button.ts +0 -1
  174. package/src/select/option.ts +1 -2
  175. package/src/select/select.scss +1 -10
  176. package/src/select/select.ts +2 -0
  177. package/src/sidebar-menu/sidebar-menu-item.ts +0 -1
  178. package/src/sidebar-menu/sidebar-sub-menu.ts +0 -1
  179. package/src/skeleton/skeleton.scss +5 -1
  180. package/src/tabs/tab-panel.ts +0 -1
  181. package/src/tabs/tab.ts +60 -70
  182. package/src/text/text.css-component.scss +3 -21
  183. package/src/tooltip/tooltip.scss +5 -8
  184. package/src/tooltip/tooltip.ts +1 -2
  185. package/dist/BaseButton-BNFAYn-S.js +0 -219
  186. package/dist/BaseButton-BNFAYn-S.js.map +0 -1
  187. package/dist/BaseHyperlinkMixin-BNuwbiEf.js.map +0 -1
  188. package/dist/button-colors-AvGh22Zn.js +0 -561
  189. package/dist/button-colors-AvGh22Zn.js.map +0 -1
  190. package/dist/icon-button-ohxHhy4t.js +0 -247
  191. package/dist/icon-button-ohxHhy4t.js.map +0 -1
  192. package/dist/navigation-rail-CD7IrqbN.js.map +0 -1
  193. package/dist/observe-slot-change-BGJfgg2E.js +0 -31
  194. package/dist/observe-slot-change-BGJfgg2E.js.map +0 -1
  195. package/dist/src/button/BaseButton.d.ts +0 -28
  196. package/dist/src/focus-ring/FocusAttachableController.d.ts +0 -8
  197. package/src/__mixins/BaseButtonMixin.ts +0 -83
  198. package/src/button/BaseButton.ts +0 -113
  199. package/src/focus-ring/FocusAttachableController.ts +0 -28
  200. package/src/popover/tooltip.css-component.scss +0 -19
@@ -61,6 +61,9 @@ export type CanvasShape =
61
61
  | CanvasLineShape
62
62
  | CanvasConnectorShape;
63
63
 
64
+ const GRID_GAP = 10;
65
+ const GRID_DOT_RADIUS = 1;
66
+
64
67
  interface CanvasBounds {
65
68
  x: number;
66
69
  y: number;
@@ -68,6 +71,20 @@ interface CanvasBounds {
68
71
  height: number;
69
72
  }
70
73
 
74
+ interface CanvasExtents {
75
+ minX: number;
76
+ minY: number;
77
+ maxX: number;
78
+ maxY: number;
79
+ }
80
+
81
+ interface CanvasViewBox {
82
+ x: number;
83
+ y: number;
84
+ width: number;
85
+ height: number;
86
+ }
87
+
71
88
  /**
72
89
  * @label Canvas
73
90
  * @tag wc-canvas
@@ -118,10 +135,6 @@ export class Canvas extends LitElement {
118
135
  @property({ type: String })
119
136
  viewbox?: string;
120
137
 
121
- private unitSize: number = 1;
122
-
123
- private gap: number = this.unitSize * 10;
124
-
125
138
  private static getNextPoint(
126
139
  point: CanvasPoint,
127
140
  direction: CanvasDirection,
@@ -134,30 +147,33 @@ export class Canvas extends LitElement {
134
147
  return { x: point.x, y: point.y };
135
148
  }
136
149
 
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;
150
+ private static updateExtents(
151
+ extents: CanvasExtents,
152
+ x: number,
153
+ y: number,
154
+ ) {
155
+ if (x < extents.minX) extents.minX = x;
156
+ if (x > extents.maxX) extents.maxX = x;
157
+ if (y < extents.minY) extents.minY = y;
158
+ if (y > extents.maxY) extents.maxY = y;
147
159
  }
148
160
 
149
161
  private static getStrokeVariantClasses(variant?: CanvasStrokeVariant) {
150
162
  return {
151
163
  line: true,
152
- 'no-color': false,
153
164
  'variant-dashed': variant === 'dashed' || variant === 'animated-dashed',
154
165
  'variant-animated-dashed': variant === 'animated-dashed',
155
166
  };
156
167
  }
157
168
 
158
169
  private computeShapes(initialBounds: CanvasBounds) {
159
- const dotRadius = this.unitSize;
160
- let computedViewbox = { ...initialBounds };
170
+ // Track world-space bounds (grid units) as shapes are processed.
171
+ const extents: CanvasExtents = {
172
+ minX: initialBounds.x,
173
+ minY: initialBounds.y,
174
+ maxX: initialBounds.x + initialBounds.width,
175
+ maxY: initialBounds.y + initialBounds.height,
176
+ };
161
177
 
162
178
  const shapes = this.shapes.map(shape => {
163
179
  switch (shape.type) {
@@ -165,19 +181,14 @@ export class Canvas extends LitElement {
165
181
  const r = shape.radius || 1;
166
182
  const cx = shape.x || 0;
167
183
  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);
184
+ Canvas.updateExtents(extents, cx - r, cy - r);
185
+ Canvas.updateExtents(extents, cx + r, cy + r);
176
186
 
187
+ // Convert from grid units to SVG pixels using the fixed gap.
177
188
  return svg`<circle
178
- cx=${cx * this.gap + dotRadius}
179
- cy=${cy * this.gap + dotRadius}
180
- r=${r * this.gap}
189
+ cx=${cx * GRID_GAP + GRID_DOT_RADIUS}
190
+ cy=${cy * GRID_GAP + GRID_DOT_RADIUS}
191
+ r=${r * GRID_GAP}
181
192
  fill=${shape.color || 'var(--canvas-line-color, var(--color-on-surface))'}
182
193
  />`;
183
194
  }
@@ -186,27 +197,23 @@ export class Canvas extends LitElement {
186
197
  const h = shape.height || 1;
187
198
  const rx = shape.x || 0;
188
199
  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);
200
+ Canvas.updateExtents(extents, rx, ry);
201
+ Canvas.updateExtents(extents, rx + w, ry + h);
197
202
 
198
203
  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}
204
+ x=${rx * GRID_GAP + GRID_DOT_RADIUS}
205
+ y=${ry * GRID_GAP}
206
+ width=${w * GRID_GAP + GRID_DOT_RADIUS}
207
+ height=${h * GRID_GAP + GRID_DOT_RADIUS}
203
208
  fill=${shape.color || 'var(--canvas-line-color, var(--color-on-surface))'}
204
209
  />`;
205
210
  }
206
211
  case 'line': {
207
212
  const start = shape.start || { x: 0, y: 0 };
208
213
  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}`;
214
+ Canvas.updateExtents(extents, start.x, start.y);
215
+ Canvas.updateExtents(extents, end.x, end.y);
216
+ const pathString = `M${start.x * GRID_GAP + GRID_DOT_RADIUS} ${start.y * GRID_GAP + GRID_DOT_RADIUS} L${end.x * GRID_GAP + GRID_DOT_RADIUS} ${end.y * GRID_GAP + GRID_DOT_RADIUS}`;
210
217
  const strokeColor =
211
218
  shape.color ||
212
219
  'var(--canvas-line-color, var(--color-on-surface))';
@@ -215,7 +222,6 @@ export class Canvas extends LitElement {
215
222
  class=${classMap({
216
223
  ...Canvas.getStrokeVariantClasses(shape.variant),
217
224
  clickable: !!shape.clickable,
218
- 'no-color': !shape.color,
219
225
  })}
220
226
  stroke-width="2"
221
227
  stroke-linecap="round"
@@ -229,19 +235,20 @@ export class Canvas extends LitElement {
229
235
  }
230
236
  case 'connector': {
231
237
  const start = shape.start || { x: 0, y: 0 };
232
- let pathString = `M${start.x * this.gap + dotRadius} ${start.y * this.gap + dotRadius}`;
238
+ let pathString = `M${start.x * GRID_GAP + GRID_DOT_RADIUS} ${start.y * GRID_GAP + GRID_DOT_RADIUS}`;
233
239
  let current = { ...start };
234
- computedViewbox = Canvas.updateComputationArea(current, computedViewbox);
240
+ Canvas.updateExtents(extents, current.x, current.y);
235
241
 
236
242
  const pathSegments = shape.path || [];
237
243
  for (let i = 0; i < pathSegments.length; i += 1) {
238
244
  const path = pathSegments[i];
239
245
 
240
246
  if (i === 0) {
247
+ // Move one unit first so curved corner joins don't overlap start.
241
248
  const point = Canvas.getNextPoint(current, path.direction, 1);
242
- pathString += ` L${point.x * this.gap + dotRadius} ${point.y * this.gap + dotRadius}`;
249
+ pathString += ` L${point.x * GRID_GAP + GRID_DOT_RADIUS} ${point.y * GRID_GAP + GRID_DOT_RADIUS}`;
243
250
  current = { ...point };
244
- computedViewbox = Canvas.updateComputationArea(current, computedViewbox);
251
+ Canvas.updateExtents(extents, current.x, current.y);
245
252
  }
246
253
 
247
254
  const point = Canvas.getNextPoint(
@@ -249,26 +256,28 @@ export class Canvas extends LitElement {
249
256
  path.direction,
250
257
  path.length - 2,
251
258
  );
252
- pathString += ` L${point.x * this.gap + dotRadius} ${point.y * this.gap + dotRadius}`;
259
+ pathString += ` L${point.x * GRID_GAP + GRID_DOT_RADIUS} ${point.y * GRID_GAP + GRID_DOT_RADIUS}`;
253
260
  current = { ...point };
254
- computedViewbox = Canvas.updateComputationArea(current, computedViewbox);
261
+ Canvas.updateExtents(extents, current.x, current.y);
255
262
 
256
263
  if (i === pathSegments.length - 1) {
257
264
  const endPoint = Canvas.getNextPoint(current, path.direction, 1);
258
- pathString += ` L${endPoint.x * this.gap + dotRadius} ${endPoint.y * this.gap + dotRadius}`;
265
+ pathString += ` L${endPoint.x * GRID_GAP + GRID_DOT_RADIUS} ${endPoint.y * GRID_GAP + GRID_DOT_RADIUS}`;
259
266
  current = { ...endPoint };
260
- computedViewbox = Canvas.updateComputationArea(current, computedViewbox);
267
+ Canvas.updateExtents(extents, current.x, current.y);
261
268
  } else {
262
269
  const nextPath = pathSegments[i + 1];
263
270
  const midPoint = Canvas.getNextPoint(current, path.direction, 1);
271
+ Canvas.updateExtents(extents, midPoint.x, midPoint.y);
264
272
  const nextPoint = Canvas.getNextPoint(
265
273
  midPoint,
266
274
  nextPath.direction,
267
275
  1,
268
276
  );
269
- pathString += ` Q ${midPoint.x * this.gap + dotRadius} ${midPoint.y * this.gap + dotRadius} ${nextPoint.x * this.gap + dotRadius} ${nextPoint.y * this.gap + dotRadius}`;
277
+ // Use a quadratic segment to round corners between directions.
278
+ pathString += ` Q ${midPoint.x * GRID_GAP + GRID_DOT_RADIUS} ${midPoint.y * GRID_GAP + GRID_DOT_RADIUS} ${nextPoint.x * GRID_GAP + GRID_DOT_RADIUS} ${nextPoint.y * GRID_GAP + GRID_DOT_RADIUS}`;
270
279
  current = { ...nextPoint };
271
- computedViewbox = Canvas.updateComputationArea(current, computedViewbox);
280
+ Canvas.updateExtents(extents, current.x, current.y);
272
281
  }
273
282
  }
274
283
 
@@ -280,7 +289,6 @@ export class Canvas extends LitElement {
280
289
  <path
281
290
  class=${classMap({
282
291
  ...Canvas.getStrokeVariantClasses(shape.variant),
283
- 'no-color': !shape.color,
284
292
  })}
285
293
  stroke-width="2"
286
294
  stroke-linecap="round"
@@ -306,19 +314,68 @@ export class Canvas extends LitElement {
306
314
  }
307
315
  });
308
316
 
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;
317
+ // Expand bounds with padding so shapes are not flush to the edge.
318
+ const computedViewbox = {
319
+ x: extents.minX - this.padding,
320
+ y: extents.minY - this.padding,
321
+ width: Math.max(extents.maxX - extents.minX + this.padding * 2, 0),
322
+ height: Math.max(extents.maxY - extents.minY + this.padding * 2, 0),
323
+ };
316
324
 
317
325
  return { shapes, computedViewbox };
318
326
  }
319
327
 
328
+ private renderBackgroundSvg(computedViewBox: CanvasViewBox, svgViewBox: string) {
329
+ return html`
330
+ <svg
331
+ class="canvas canvas-background"
332
+ height="100%"
333
+ width="100%"
334
+ viewBox=${svgViewBox}
335
+ aria-hidden="true"
336
+ >
337
+ <defs>
338
+ <pattern
339
+ id="canvas-background"
340
+ patternUnits="userSpaceOnUse"
341
+ width=${GRID_GAP}
342
+ height=${GRID_GAP}
343
+ >
344
+ <circle cx="1" cy="1" r=${GRID_DOT_RADIUS} />
345
+ </pattern>
346
+ </defs>
347
+
348
+ <rect
349
+ x=${computedViewBox.x * GRID_GAP}
350
+ y=${computedViewBox.y * GRID_GAP}
351
+ width="100%"
352
+ height="100%"
353
+ fill="url(#canvas-background)"
354
+ />
355
+ </svg>
356
+ `;
357
+ }
358
+
359
+ private renderShapesSvg(shapes: unknown[], svgViewBox: string) {
360
+ return html`
361
+ <svg
362
+ class="canvas canvas-shapes"
363
+ height="100%"
364
+ width="100%"
365
+ viewBox=${svgViewBox}
366
+ >
367
+ <defs>
368
+ <marker id="endarrow" markerWidth="10" markerHeight="10" refX="5" refY="5" markerUnits="strokeWidth" orient="auto">
369
+ <polyline points="0 2, 5 5, 0 8"></polyline>
370
+ </marker>
371
+ </defs>
372
+
373
+ ${shapes}
374
+ </svg>
375
+ `;
376
+ }
377
+
320
378
  protected render() {
321
- const dotRadius = this.unitSize;
322
379
  let computedViewBox = { width: 0, height: 0, x: 0, y: 0 };
323
380
 
324
381
  const { shapes, computedViewbox } = this.computeShapes(computedViewBox);
@@ -334,57 +391,22 @@ export class Canvas extends LitElement {
334
391
  };
335
392
  }
336
393
 
394
+ // Zoom scales the outer viewport size while the SVG viewBox stays in world units.
337
395
  const wrapperWidth =
338
- (computedViewBox.width * this.gap + 2) * dotRadius * this.zoom;
396
+ (computedViewBox.width * GRID_GAP + 2) * GRID_DOT_RADIUS * this.zoom;
339
397
  const wrapperHeight =
340
- (computedViewBox.height * this.gap + 2) * dotRadius * this.zoom;
398
+ (computedViewBox.height * GRID_GAP + 2) * GRID_DOT_RADIUS * this.zoom;
341
399
 
342
- const svgViewBox = `${computedViewBox.x * this.gap} ${computedViewBox.y * this.gap} ${computedViewBox.width * this.gap + 2 * dotRadius} ${computedViewBox.height * this.gap + 2 * dotRadius}`;
400
+ // viewBox maps world-space extents into the internal SVG coordinate system.
401
+ const svgViewBox = `${computedViewBox.x * GRID_GAP} ${computedViewBox.y * GRID_GAP} ${computedViewBox.width * GRID_GAP + 2 * GRID_DOT_RADIUS} ${computedViewBox.height * GRID_GAP + 2 * GRID_DOT_RADIUS}`;
343
402
 
344
403
  return html`
345
404
  <div
346
405
  class="canvas-wrapper"
347
406
  style="width: ${wrapperWidth}px; height: ${wrapperHeight}px;"
348
407
  >
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>
408
+ ${this.renderBackgroundSvg(computedViewBox, svgViewBox)}
409
+ ${this.renderShapesSvg(shapes, svgViewBox)}
388
410
  </div>
389
411
  `;
390
412
  }
@@ -5,8 +5,7 @@ import IndividualComponent from '../IndividualComponent.js';
5
5
  * @label Card Content
6
6
  * @tag wc-card-content
7
7
  * @rawTag card-content
8
- * @parentRawTag
9
- *
8
+ *
10
9
  * @cssprop --card-content-padding - Inner padding for the card container. Defaults to 1rem.
11
10
  *
12
11
  * ```
@@ -23,4 +22,4 @@ export class CardContent extends LitElement {
23
22
  render() {
24
23
  return html`<slot></slot>`;
25
24
  }
26
- }
25
+ }
@@ -3,6 +3,7 @@
3
3
  @include mixin.base-styles;
4
4
 
5
5
  :host {
6
+ position: relative;
6
7
  display: block;
7
8
  --card-gap: 0;
8
9
  --card-padding: 0;
@@ -11,6 +12,11 @@
11
12
  --card-container-shape-start-end: unset;
12
13
  --card-container-shape-end-start: unset;
13
14
  --card-container-shape-end-end: unset;
15
+
16
+ --_container-shape-start-start: var(--card-container-shape-start-start, var(--card-container-shape));
17
+ --_container-shape-start-end: var(--card-container-shape-start-end, var(--card-container-shape));
18
+ --_container-shape-end-start: var(--card-container-shape-end-start, var(--card-container-shape));
19
+ --_container-shape-end-end: var(--card-container-shape-end-end, var(--card-container-shape));
14
20
  }
15
21
 
16
22
  /*
@@ -27,16 +33,10 @@
27
33
  }
28
34
 
29
35
  .card {
30
- position: relative;
31
36
  display: flex;
32
37
  height: 100%;
33
38
  width: 100%;
34
-
35
- --_container-shape-start-start: var(--card-container-shape-start-start, var(--card-container-shape));
36
- --_container-shape-start-end: var(--card-container-shape-start-end, var(--card-container-shape));
37
- --_container-shape-end-start: var(--card-container-shape-end-start, var(--card-container-shape));
38
- --_container-shape-end-end: var(--card-container-shape-end-end, var(--card-container-shape));
39
-
39
+ z-index: 0;
40
40
 
41
41
  .card-content {
42
42
  z-index: 0;
@@ -63,83 +63,80 @@
63
63
  height: 100%;
64
64
  }
65
65
  }
66
+ }
66
67
 
67
- /*
68
- Background layers
69
- */
70
- .focus-ring {
71
- z-index: 2;
72
- display: none;
73
- --focus-ring-container-shape-start-start: var(--_container-shape-start-start);
74
- --focus-ring-container-shape-start-end: var(--_container-shape-start-end);
75
- --focus-ring-container-shape-end-start: var(--_container-shape-end-start);
76
- --focus-ring-container-shape-end-end: var(--_container-shape-end-end);
77
- --focus-ring-container-shape-variant: var(--_container-corner-shape-variant);
78
- }
79
-
80
- .ripple {
81
- display: none;
82
- border-start-start-radius: var(--_container-shape-start-start);
83
- border-start-end-radius: var(--_container-shape-start-end);
84
- border-end-start-radius: var(--_container-shape-end-start);
85
- border-end-end-radius: var(--_container-shape-end-end);
86
- corner-shape: var(--_container-corner-shape-variant);
87
- --ripple-state-opacity: var(--_container-state-opacity, 0);
88
- --ripple-pressed-color: var(--_container-state-color);
89
- }
90
-
91
- .background {
92
- z-index: 0;
93
- display: block;
94
- position: absolute;
95
- top: 0;
96
- left: 0;
97
- width: 100%;
98
- height: 100%;
99
- background-color: var(--_container-color);
100
- opacity: var(--_container-opacity, 1);
101
-
102
- border-start-start-radius: var(--_container-shape-start-start);
103
- border-start-end-radius: var(--_container-shape-start-end);
104
- border-end-start-radius: var(--_container-shape-end-start);
105
- border-end-end-radius: var(--_container-shape-end-end);
106
- corner-shape: var(--_container-corner-shape-variant);
107
- pointer-events: none;
108
- }
109
-
110
- .elevation {
111
- --elevation-level: var(--_container-elevation-level);
112
- transition-duration: 280ms;
113
- --elevation-container-shape-start-start: var(--_container-shape-start-start);
114
- --elevation-container-shape-start-end: var(--_container-shape-start-end);
115
- --elevation-container-shape-end-start: var(--_container-shape-end-start);
116
- --elevation-container-shape-end-end: var(--_container-shape-end-end);
117
- --elevation-container-shape-variant: var(--_container-corner-shape-variant);
118
- }
68
+ /*
69
+ Background layers
70
+ */
71
+ .focus-ring {
72
+ z-index: 2;
73
+ display: none;
74
+ --focus-ring-container-shape-start-start: var(--_container-shape-start-start);
75
+ --focus-ring-container-shape-start-end: var(--_container-shape-start-end);
76
+ --focus-ring-container-shape-end-start: var(--_container-shape-end-start);
77
+ --focus-ring-container-shape-end-end: var(--_container-shape-end-end);
78
+ --focus-ring-container-shape-variant: var(--_container-corner-shape-variant);
79
+ }
119
80
 
120
- .outline {
121
- z-index: 0;
122
- display: none;
123
- position: absolute;
124
- left: 0;
125
- top: 0;
126
- width: 100%;
127
- height: 100%;
128
- pointer-events: none;
129
- border: var(--_outline-width) solid var(--_outline-color);
130
- opacity: var(--_outline-opacity, 1);
131
- border-start-start-radius: var(--_container-shape-start-start);
132
- border-start-end-radius: var(--_container-shape-start-end);
133
- border-end-start-radius: var(--_container-shape-end-start);
134
- border-end-end-radius: var(--_container-shape-end-end);
135
- corner-shape: var(--_container-corner-shape-variant);
136
- }
81
+ .ripple {
82
+ display: none;
83
+ border-start-start-radius: var(--_container-shape-start-start);
84
+ border-start-end-radius: var(--_container-shape-start-end);
85
+ border-end-start-radius: var(--_container-shape-end-start);
86
+ border-end-end-radius: var(--_container-shape-end-end);
87
+ corner-shape: var(--_container-corner-shape-variant);
88
+ --ripple-state-opacity: var(--_container-state-opacity, 0);
89
+ --ripple-pressed-color: var(--_container-state-color);
90
+ }
137
91
 
92
+ .background {
93
+ z-index: 0;
94
+ display: block;
95
+ position: absolute;
96
+ top: 0;
97
+ left: 0;
98
+ width: 100%;
99
+ height: 100%;
100
+ background-color: var(--_container-color);
101
+ opacity: var(--_container-opacity, 1);
102
+
103
+ border-start-start-radius: var(--_container-shape-start-start);
104
+ border-start-end-radius: var(--_container-shape-start-end);
105
+ border-end-start-radius: var(--_container-shape-end-start);
106
+ border-end-end-radius: var(--_container-shape-end-end);
107
+ corner-shape: var(--_container-corner-shape-variant);
108
+ pointer-events: none;
109
+ }
138
110
 
111
+ .elevation {
112
+ --elevation-level: var(--_container-elevation-level);
113
+ transition-duration: 280ms;
114
+ --elevation-container-shape-start-start: var(--_container-shape-start-start);
115
+ --elevation-container-shape-start-end: var(--_container-shape-start-end);
116
+ --elevation-container-shape-end-start: var(--_container-shape-end-start);
117
+ --elevation-container-shape-end-end: var(--_container-shape-end-end);
118
+ --elevation-container-shape-variant: var(--_container-corner-shape-variant);
139
119
  }
140
120
 
141
- .card.actionable {
121
+ .outline {
122
+ z-index: 0;
123
+ display: none;
124
+ position: absolute;
125
+ left: 0;
126
+ top: 0;
127
+ width: 100%;
128
+ height: 100%;
129
+ pointer-events: none;
130
+ border: var(--_outline-width) solid var(--_outline-color);
131
+ opacity: var(--_outline-opacity, 1);
132
+ border-start-start-radius: var(--_container-shape-start-start);
133
+ border-start-end-radius: var(--_container-shape-start-end);
134
+ border-end-start-radius: var(--_container-shape-end-start);
135
+ border-end-end-radius: var(--_container-shape-end-end);
136
+ corner-shape: var(--_container-corner-shape-variant);
137
+ }
142
138
 
139
+ :host([actionable]) {
143
140
  .focus-ring,
144
141
  .ripple {
145
142
  display: block;
@@ -150,24 +147,23 @@
150
147
  }
151
148
  }
152
149
 
153
- .card.variant-elevated {
150
+ :host([variant='elevated']) {
154
151
  --_container-color: var(--elevated-card-container-color);
155
152
  --_label-text-color: var(--elevated-card-label-text-color);
156
153
  --_container-elevation-level: 1;
157
-
158
154
  --_container-state-color: var(--_label-text-color);
159
155
 
160
- &:hover:not(:where(.disabled, .soft-disabled, .show-skeleton)) {
156
+ &:hover:not([disabled]) {
161
157
  --_container-elevation-level: 2;
162
158
  --_container-state-opacity: 0.08;
163
159
  }
164
160
 
165
- &.pressed:not(:where(.disabled, .soft-disabled, .show-skeleton)) {
161
+ &:has(.card.pressed):not([disabled]) {
166
162
  --_container-elevation-level: 1;
167
163
  --_container-state-opacity: 0.12;
168
164
  }
169
165
 
170
- &.disabled {
166
+ &[disabled] {
171
167
  --_container-color: var(--color-on-surface);
172
168
  --_container-opacity: 0.1;
173
169
  --_label-text-color: var(--color-on-surface);
@@ -179,24 +175,22 @@
179
175
  }
180
176
  }
181
177
 
182
-
183
- .card.variant-filled {
178
+ :host([variant='filled']) {
184
179
  --_container-color: var(--filled-card-container-color);
185
180
  --_label-text-color: var(--filled-card-label-text-color);
186
181
  --_container-state-color: var(--_label-text-color);
187
182
 
188
-
189
- &:hover:not(:where(.disabled, .soft-disabled, .show-skeleton)) {
183
+ &:hover:not([disabled]) {
190
184
  --_container-elevation-level: 1;
191
185
  --_container-state-opacity: 0.08;
192
186
  }
193
187
 
194
- &.pressed:not(:where(.disabled, .soft-disabled, .show-skeleton)) {
188
+ &:has(.card.pressed):not([disabled]) {
195
189
  --_container-elevation-level: 0;
196
190
  --_container-state-opacity: 0.1;
197
191
  }
198
192
 
199
- &.disabled {
193
+ &[disabled] {
200
194
  --_container-color: var(--color-on-surface);
201
195
  --_container-opacity: 0.1;
202
196
  --_label-text-color: var(--color-on-surface);
@@ -208,27 +202,25 @@
208
202
  }
209
203
  }
210
204
 
211
-
212
- .card.variant-outlined {
205
+ :host([variant='outlined']) {
213
206
  --_outline-width: var(--outlined-card-outline-width, 0.0675rem);
214
207
  --_outline-color: var(--outlined-card-outline-color);
215
208
  --_label-text-color: var(--outlined-card-label-text-color);
216
-
217
209
  --_container-state-color: var(--_label-text-color);
218
210
 
219
211
  .outline {
220
212
  display: block;
221
213
  }
222
214
 
223
- &:hover:not(:where(.disabled, .soft-disabled, .show-skeleton)) {
215
+ &:hover:not([disabled]) {
224
216
  --_container-state-opacity: 0.08;
225
217
  }
226
218
 
227
- &.pressed:not(:where(.disabled, .soft-disabled, .show-skeleton)) {
219
+ &:has(.card.pressed):not([disabled]) {
228
220
  --_container-state-opacity: 0.12;
229
221
  }
230
222
 
231
- &.disabled {
223
+ &[disabled] {
232
224
  --_outline-color: var(--color-on-surface);
233
225
  --_label-text-color: var(--color-on-surface);
234
226
  --_label-text-opacity: 0.38;
@@ -238,4 +230,4 @@
238
230
  display: none;
239
231
  }
240
232
  }
241
- }
233
+ }