@antv/infographic 0.2.17 → 0.2.18

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 (97) hide show
  1. package/README.md +1 -1
  2. package/README.zh-CN.md +1 -1
  3. package/dist/infographic.min.js +99 -99
  4. package/dist/infographic.min.js.map +1 -1
  5. package/esm/constants/service.d.ts +1 -1
  6. package/esm/constants/service.js +1 -1
  7. package/esm/designs/structures/chart-line.js +5 -3
  8. package/esm/editor/interactions/dblclick-edit-text.js +3 -3
  9. package/esm/editor/managers/interaction.js +6 -4
  10. package/esm/editor/plugins/components/button.d.ts +2 -1
  11. package/esm/editor/plugins/components/button.js +4 -4
  12. package/esm/editor/plugins/components/color-picker.d.ts +1 -0
  13. package/esm/editor/plugins/components/color-picker.js +3 -3
  14. package/esm/editor/plugins/components/popover.d.ts +3 -1
  15. package/esm/editor/plugins/components/popover.js +29 -9
  16. package/esm/editor/plugins/edit-bar/edit-bar.d.ts +3 -1
  17. package/esm/editor/plugins/edit-bar/edit-bar.js +17 -7
  18. package/esm/editor/plugins/edit-bar/edit-items/align-elements.js +6 -4
  19. package/esm/editor/plugins/edit-bar/edit-items/font-align.js +8 -5
  20. package/esm/editor/plugins/edit-bar/edit-items/font-color.js +7 -4
  21. package/esm/editor/plugins/edit-bar/edit-items/font-family.js +11 -9
  22. package/esm/editor/plugins/edit-bar/edit-items/font-size.js +8 -5
  23. package/esm/editor/plugins/edit-bar/edit-items/icon-color.js +7 -4
  24. package/esm/editor/plugins/edit-bar/edit-items/types.d.ts +5 -1
  25. package/esm/editor/plugins/reset-viewbox.d.ts +4 -1
  26. package/esm/editor/plugins/reset-viewbox.js +12 -6
  27. package/esm/editor/utils/index.d.ts +1 -0
  28. package/esm/editor/utils/index.js +1 -0
  29. package/esm/editor/utils/root.d.ts +3 -0
  30. package/esm/editor/utils/root.js +18 -0
  31. package/esm/exporter/svg.js +63 -3
  32. package/esm/resource/loaders/search.js +0 -3
  33. package/esm/templates/utils.js +11 -6
  34. package/esm/utils/padding.js +1 -1
  35. package/esm/utils/style.d.ts +3 -1
  36. package/esm/utils/style.js +27 -4
  37. package/esm/version.d.ts +1 -1
  38. package/esm/version.js +1 -1
  39. package/lib/constants/service.d.ts +1 -1
  40. package/lib/constants/service.js +1 -1
  41. package/lib/designs/structures/chart-line.js +5 -3
  42. package/lib/editor/interactions/dblclick-edit-text.js +3 -3
  43. package/lib/editor/managers/interaction.js +7 -5
  44. package/lib/editor/plugins/components/button.d.ts +2 -1
  45. package/lib/editor/plugins/components/button.js +4 -4
  46. package/lib/editor/plugins/components/color-picker.d.ts +1 -0
  47. package/lib/editor/plugins/components/color-picker.js +3 -3
  48. package/lib/editor/plugins/components/popover.d.ts +3 -1
  49. package/lib/editor/plugins/components/popover.js +32 -12
  50. package/lib/editor/plugins/edit-bar/edit-bar.d.ts +3 -1
  51. package/lib/editor/plugins/edit-bar/edit-bar.js +17 -7
  52. package/lib/editor/plugins/edit-bar/edit-items/align-elements.js +6 -4
  53. package/lib/editor/plugins/edit-bar/edit-items/font-align.js +8 -5
  54. package/lib/editor/plugins/edit-bar/edit-items/font-color.js +7 -4
  55. package/lib/editor/plugins/edit-bar/edit-items/font-family.js +11 -9
  56. package/lib/editor/plugins/edit-bar/edit-items/font-size.js +8 -5
  57. package/lib/editor/plugins/edit-bar/edit-items/icon-color.js +7 -4
  58. package/lib/editor/plugins/edit-bar/edit-items/types.d.ts +5 -1
  59. package/lib/editor/plugins/reset-viewbox.d.ts +4 -1
  60. package/lib/editor/plugins/reset-viewbox.js +12 -6
  61. package/lib/editor/utils/index.d.ts +1 -0
  62. package/lib/editor/utils/index.js +1 -0
  63. package/lib/editor/utils/root.d.ts +3 -0
  64. package/lib/editor/utils/root.js +22 -0
  65. package/lib/exporter/svg.js +63 -3
  66. package/lib/resource/loaders/search.js +0 -3
  67. package/lib/templates/utils.js +11 -6
  68. package/lib/utils/padding.js +1 -1
  69. package/lib/utils/style.d.ts +3 -1
  70. package/lib/utils/style.js +27 -4
  71. package/lib/version.d.ts +1 -1
  72. package/lib/version.js +1 -1
  73. package/package.json +1 -1
  74. package/src/constants/service.ts +1 -1
  75. package/src/designs/structures/chart-line.tsx +5 -3
  76. package/src/editor/interactions/dblclick-edit-text.ts +3 -2
  77. package/src/editor/managers/interaction.ts +9 -7
  78. package/src/editor/plugins/components/button.ts +5 -2
  79. package/src/editor/plugins/components/color-picker.ts +4 -2
  80. package/src/editor/plugins/components/popover.ts +31 -12
  81. package/src/editor/plugins/edit-bar/edit-bar.ts +26 -11
  82. package/src/editor/plugins/edit-bar/edit-items/align-elements.ts +7 -2
  83. package/src/editor/plugins/edit-bar/edit-items/font-align.ts +8 -3
  84. package/src/editor/plugins/edit-bar/edit-items/font-color.ts +7 -2
  85. package/src/editor/plugins/edit-bar/edit-items/font-family.ts +11 -7
  86. package/src/editor/plugins/edit-bar/edit-items/font-size.ts +8 -3
  87. package/src/editor/plugins/edit-bar/edit-items/icon-color.ts +7 -2
  88. package/src/editor/plugins/edit-bar/edit-items/types.ts +6 -1
  89. package/src/editor/plugins/reset-viewbox.ts +17 -8
  90. package/src/editor/utils/index.ts +1 -0
  91. package/src/editor/utils/root.ts +26 -0
  92. package/src/exporter/svg.ts +80 -3
  93. package/src/resource/loaders/search.ts +0 -3
  94. package/src/templates/utils.ts +30 -6
  95. package/src/utils/padding.ts +1 -1
  96. package/src/utils/style.ts +31 -4
  97. package/src/version.ts +1 -1
@@ -1,6 +1,7 @@
1
1
  import { COMPONENT_ROLE } from '../../constants/index.js';
2
2
  import { getBoundViewBox, getViewBox, injectStyleOnce, parsePadding, setElementRole, viewBoxToString, } from '../../utils/index.js';
3
3
  import { UpdateOptionsCommand } from '../commands/index.js';
4
+ import { getOverlayContainer } from '../utils/index.js';
4
5
  import { Plugin } from './base.js';
5
6
  import { IconButton } from './components/index.js';
6
7
  import { RESET_ICON } from './components/icons.js';
@@ -33,9 +34,12 @@ export class ResetViewBox extends Plugin {
33
34
  if (this.resetButton)
34
35
  return this.resetButton;
35
36
  const { style, className } = this.options || {};
37
+ const containerParent = this.resolveOverlayRoot();
38
+ this.ensureButtonStyle(containerParent);
36
39
  const button = IconButton({
37
40
  icon: RESET_ICON,
38
41
  onClick: this.resetViewBox,
42
+ root: containerParent,
39
43
  });
40
44
  button.classList.add(RESET_BUTTON_CLASS);
41
45
  if (className) {
@@ -46,9 +50,6 @@ export class ResetViewBox extends Plugin {
46
50
  }
47
51
  setElementRole(button, COMPONENT_ROLE);
48
52
  this.resetButton = button;
49
- const { getContainer } = this.options || {};
50
- const resolvedContainer = typeof getContainer === 'function' ? getContainer() : getContainer;
51
- const containerParent = resolvedContainer !== null && resolvedContainer !== void 0 ? resolvedContainer : document.body;
52
53
  containerParent === null || containerParent === void 0 ? void 0 : containerParent.appendChild(button);
53
54
  return button;
54
55
  };
@@ -139,7 +140,7 @@ export class ResetViewBox extends Plugin {
139
140
  init(options) {
140
141
  super.init(options);
141
142
  // Initialize originViewBox
142
- this.ensureButtonStyle();
143
+ this.ensureButtonStyle(this.resolveOverlayRoot());
143
144
  this.updateOriginViewBox();
144
145
  this.unregisterSync = this.editor.registerSync('viewBox', this.handleViewBoxChange);
145
146
  window.addEventListener('resize', this.handleResize);
@@ -161,7 +162,12 @@ export class ResetViewBox extends Plugin {
161
162
  const { padding } = this.state.getOptions();
162
163
  this.originViewBox = getBoundViewBox(svg, parsePadding(padding));
163
164
  }
164
- ensureButtonStyle() {
165
+ resolveOverlayRoot() {
166
+ const { getContainer } = this.options || {};
167
+ const resolvedContainer = typeof getContainer === 'function' ? getContainer() : getContainer;
168
+ return resolvedContainer !== null && resolvedContainer !== void 0 ? resolvedContainer : getOverlayContainer(this.editor.getDocument());
169
+ }
170
+ ensureButtonStyle(target) {
165
171
  injectStyleOnce(RESET_BUTTON_STYLE_ID, `
166
172
  button.${RESET_BUTTON_CLASS} {
167
173
  visibility: hidden;
@@ -179,7 +185,7 @@ export class ResetViewBox extends Plugin {
179
185
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
180
186
  cursor: pointer;
181
187
  }
182
- `);
188
+ `, target);
183
189
  }
184
190
  }
185
191
  const RESET_BUTTON_CLASS = 'infographic-reset-viewbox-btn';
@@ -6,3 +6,4 @@ export * from './event';
6
6
  export * from './extension';
7
7
  export * from './hotkey';
8
8
  export * from './object';
9
+ export * from './root';
@@ -6,3 +6,4 @@ export * from './event.js';
6
6
  export * from './extension.js';
7
7
  export * from './hotkey.js';
8
8
  export * from './object.js';
9
+ export * from './root.js';
@@ -0,0 +1,3 @@
1
+ export type OverlayContainer = HTMLElement | ShadowRoot;
2
+ export declare function getOverlayContainer(node?: Node | null): OverlayContainer;
3
+ export declare function eventPathContains(event: Event, node: Node): boolean;
@@ -0,0 +1,18 @@
1
+ function getConnectedRoot(node) {
2
+ if (!(node === null || node === void 0 ? void 0 : node.isConnected))
3
+ return document;
4
+ const root = node.getRootNode();
5
+ return root instanceof ShadowRoot ? root : document;
6
+ }
7
+ export function getOverlayContainer(node) {
8
+ const root = getConnectedRoot(node);
9
+ return root instanceof ShadowRoot ? root : document.body;
10
+ }
11
+ export function eventPathContains(event, node) {
12
+ const path = typeof event.composedPath === 'function' ? event.composedPath() : [];
13
+ if (path.length > 0) {
14
+ return path.some((current) => current === node || (current instanceof Node && node.contains(current)));
15
+ }
16
+ const target = event.target;
17
+ return target instanceof Node && (target === node || node.contains(target));
18
+ }
@@ -22,7 +22,10 @@ function getExportViewBox(svg) {
22
22
  return getViewBox(svg);
23
23
  const width = parseAbsoluteLength(svg.getAttribute('width'));
24
24
  const height = parseAbsoluteLength(svg.getAttribute('height'));
25
- if (width > 0 && height > 0) {
25
+ if (!Number.isNaN(width) &&
26
+ width > 0 &&
27
+ !Number.isNaN(height) &&
28
+ height > 0) {
26
29
  return { x: 0, y: 0, width, height };
27
30
  }
28
31
  const rect = svg.getBoundingClientRect();
@@ -214,8 +217,9 @@ function embedIcons(svg) {
214
217
  const existsSymbol = svg.querySelector(href);
215
218
  if (!existsSymbol) {
216
219
  const symbolElement = document.querySelector(href);
217
- if (symbolElement)
220
+ if (symbolElement) {
218
221
  defs.appendChild(symbolElement.cloneNode(true));
222
+ }
219
223
  }
220
224
  });
221
225
  });
@@ -423,6 +427,8 @@ function collectDefElements(svg, ids) {
423
427
  };
424
428
  while (queue.length) {
425
429
  const id = queue.shift();
430
+ if (!id)
431
+ continue;
426
432
  if (visited.has(id))
427
433
  continue;
428
434
  visited.add(id);
@@ -437,11 +443,65 @@ function collectDefElements(svg, ids) {
437
443
  }
438
444
  return collected;
439
445
  }
446
+ // Fallback implementation based on the CSS.escape algorithm
447
+ function cssEscape(value) {
448
+ const string = String(value);
449
+ const length = string.length;
450
+ let result = '';
451
+ if (length === 0) {
452
+ return '';
453
+ }
454
+ for (let i = 0; i < length; i++) {
455
+ const codeUnit = string.charCodeAt(i);
456
+ // Null character
457
+ if (codeUnit === 0x0000) {
458
+ result += '\uFFFD';
459
+ continue;
460
+ }
461
+ // Control characters or DEL
462
+ if ((codeUnit >= 0x0001 && codeUnit <= 0x001f) || codeUnit === 0x007f) {
463
+ result += '\\' + codeUnit.toString(16) + ' ';
464
+ continue;
465
+ }
466
+ // Escape if first character is a digit
467
+ if (i === 0 && codeUnit >= 0x0030 && codeUnit <= 0x0039) {
468
+ result += '\\' + codeUnit.toString(16) + ' ';
469
+ continue;
470
+ }
471
+ // Escape if second character is a digit and first is a hyphen
472
+ if (i === 1 &&
473
+ codeUnit >= 0x0030 &&
474
+ codeUnit <= 0x0039 &&
475
+ string.charCodeAt(0) === 0x002d) {
476
+ result += '\\' + codeUnit.toString(16) + ' ';
477
+ continue;
478
+ }
479
+ // If the character is the first and is a hyphen followed by end of string, escape it
480
+ if (i === 0 && length === 1 && codeUnit === 0x002d) {
481
+ result += '\\' + string.charAt(i);
482
+ continue;
483
+ }
484
+ // Characters that are safe to use unescaped
485
+ if (codeUnit >= 0x0080 ||
486
+ (codeUnit >= 0x0030 && codeUnit <= 0x0039) || // 0-9
487
+ (codeUnit >= 0x0041 && codeUnit <= 0x005a) || // A-Z
488
+ (codeUnit >= 0x0061 && codeUnit <= 0x007a) || // a-z
489
+ codeUnit === 0x002d || // -
490
+ codeUnit === 0x005f // _
491
+ ) {
492
+ result += string.charAt(i);
493
+ continue;
494
+ }
495
+ // All other characters
496
+ result += '\\' + string.charAt(i);
497
+ }
498
+ return result;
499
+ }
440
500
  function escapeCssId(id) {
441
501
  if (globalThis.CSS && typeof globalThis.CSS.escape === 'function') {
442
502
  return globalThis.CSS.escape(id);
443
503
  }
444
- return id.replace(/([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g, '\\$1');
504
+ return cssEscape(id);
445
505
  }
446
506
  function removeDefs(svg) {
447
507
  const defsList = Array.from(svg.querySelectorAll('defs'));
@@ -54,9 +54,6 @@ export function loadSearchResource(query, format) {
54
54
  const svgText = commaIndex >= 0 ? result.slice(commaIndex + 1) : result;
55
55
  return loadSVGResource(svgText);
56
56
  }
57
- if (mimeType === 'image/svg+xml' && format === 'svg' && isBase64) {
58
- return loadImageBase64Resource(result);
59
- }
60
57
  return loadImageBase64Resource(result);
61
58
  }
62
59
  return loadRemoteResource(result, format);
@@ -30,11 +30,20 @@ function getLevenshteinDistance(source, target) {
30
30
  function getCommonPrefixLength(source, target) {
31
31
  const limit = Math.min(source.length, target.length);
32
32
  let index = 0;
33
- while (index < limit && source[index] === target[index]) {
33
+ while (index < limit &&
34
+ source.charCodeAt(index) === target.charCodeAt(index)) {
34
35
  index += 1;
35
36
  }
36
37
  return index;
37
38
  }
39
+ function isBetterMatch(bestMatch, bestDistance, bestPrefixLength, candidateKey, candidateDistance, candidatePrefixLength) {
40
+ return (candidateDistance < bestDistance ||
41
+ (candidateDistance === bestDistance &&
42
+ candidatePrefixLength > bestPrefixLength) ||
43
+ (candidateDistance === bestDistance &&
44
+ candidatePrefixLength === bestPrefixLength &&
45
+ (!bestMatch || candidateKey < bestMatch)));
46
+ }
38
47
  export function findClosestTemplateKey(type, keys) {
39
48
  const normalizedType = normalizeTemplateKey(type);
40
49
  if (!normalizedType)
@@ -49,11 +58,7 @@ export function findClosestTemplateKey(type, keys) {
49
58
  }
50
59
  const distance = getLevenshteinDistance(normalizedType, normalizedKey);
51
60
  const prefixLength = getCommonPrefixLength(normalizedType, normalizedKey);
52
- if (distance < bestDistance ||
53
- (distance === bestDistance && prefixLength > bestPrefixLength) ||
54
- (distance === bestDistance &&
55
- prefixLength === bestPrefixLength &&
56
- (!bestMatch || key < bestMatch))) {
61
+ if (isBetterMatch(bestMatch, bestDistance, bestPrefixLength, key, distance, prefixLength)) {
57
62
  bestMatch = key;
58
63
  bestDistance = distance;
59
64
  bestPrefixLength = prefixLength;
@@ -26,7 +26,7 @@ export function setSVGPadding(svg, padding) {
26
26
  setSVGPaddingInNode(svg, padding);
27
27
  }
28
28
  else {
29
- if (document.contains(svg)) {
29
+ if (svg.isConnected) {
30
30
  setSVGPaddingInBrowser(svg, padding);
31
31
  }
32
32
  else {
@@ -1 +1,3 @@
1
- export declare function injectStyleOnce(id: string, styles: string): void;
1
+ type StyleTarget = Document | ShadowRoot | Node | null | undefined;
2
+ export declare function injectStyleOnce(id: string, styles: string, target?: StyleTarget): void;
3
+ export {};
@@ -1,8 +1,31 @@
1
- export function injectStyleOnce(id, styles) {
2
- if (document.getElementById(id))
1
+ function resolveStyleRoot(target) {
2
+ if (!target)
3
+ return document;
4
+ if (target instanceof Document || target instanceof ShadowRoot)
5
+ return target;
6
+ if (!target.isConnected)
7
+ return document;
8
+ const root = target.getRootNode();
9
+ return root instanceof ShadowRoot ? root : document;
10
+ }
11
+ function hasStyle(root, id) {
12
+ if (root instanceof Document)
13
+ return Boolean(root.getElementById(id));
14
+ return Boolean(root.querySelector(`#${id}`));
15
+ }
16
+ export function injectStyleOnce(id, styles, target) {
17
+ var _a;
18
+ const root = resolveStyleRoot(target);
19
+ if (hasStyle(root, id))
3
20
  return;
4
- const style = document.createElement('style');
21
+ const doc = root instanceof Document ? root : ((_a = root.ownerDocument) !== null && _a !== void 0 ? _a : document);
22
+ const style = doc.createElement('style');
5
23
  style.id = id;
6
24
  style.textContent = styles;
7
- document.head.appendChild(style);
25
+ if (root instanceof Document) {
26
+ root.head.appendChild(style);
27
+ }
28
+ else {
29
+ root.appendChild(style);
30
+ }
8
31
  }
package/esm/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const VERSION = "0.2.17";
1
+ export declare const VERSION = "0.2.18";
package/esm/version.js CHANGED
@@ -1 +1 @@
1
- export const VERSION = '0.2.17';
1
+ export const VERSION = '0.2.18';
@@ -1 +1 @@
1
- export declare const ICON_SERVICE_URL = "https://lab.weavefox.cn/api/v1/infographic/icon";
1
+ export declare const ICON_SERVICE_URL = "https://www.weavefox.cn/api/v1/infographic/icon";
@@ -1,4 +1,4 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ICON_SERVICE_URL = void 0;
4
- exports.ICON_SERVICE_URL = 'https://lab.weavefox.cn/api/v1/infographic/icon';
4
+ exports.ICON_SERVICE_URL = 'https://www.weavefox.cn/api/v1/infographic/icon';
@@ -9,6 +9,8 @@ const components_1 = require("../components");
9
9
  const layouts_1 = require("../layouts");
10
10
  const utils_2 = require("../utils");
11
11
  const registry_1 = require("./registry");
12
+ const ITEM_POSITION_H = 'center';
13
+ const ITEM_POSITION_V = 'normal';
12
14
  const ChartLine = (props) => {
13
15
  const { Title, Item, data, width, height = 260, gap = 10, padding = 24, showValue = true, options, valueFormatter = (value) => value.toString(), } = props;
14
16
  const { title, desc, items = [], xTitle, yTitle } = data;
@@ -21,8 +23,8 @@ const ChartLine = (props) => {
21
23
  indexes: [0],
22
24
  datum: items[0],
23
25
  data,
24
- positionH: 'center',
25
- positionV: 'normal',
26
+ positionH: ITEM_POSITION_H,
27
+ positionV: ITEM_POSITION_V,
26
28
  };
27
29
  const sampleBounds = (0, jsx_1.getElementBounds)((0, jsx_runtime_1.jsx)(Item, Object.assign({}, itemProps)));
28
30
  const labelWidth = sampleBounds.width;
@@ -162,7 +164,7 @@ const ChartLine = (props) => {
162
164
  if (yTitle) {
163
165
  titleElements.push((0, jsx_runtime_1.jsx)(jsx_1.Text, { x: paddingLeft + yTitleSpace / 2, y: chartOriginY + height / 2, alignHorizontal: "center", alignVertical: "middle", fontSize: 14, fontWeight: "bold", fill: axisColor, children: yTitle }));
164
166
  }
165
- return ((0, jsx_runtime_1.jsxs)(layouts_1.FlexLayout, { id: "infographic-container", flexDirection: "column", justifyContent: "center", alignItems: "center", children: [titleContent, (0, jsx_runtime_1.jsxs)(jsx_1.Group, { width: totalWidth, height: totalHeight, children: [(0, jsx_runtime_1.jsxs)(jsx_1.Defs, { children: [(0, jsx_runtime_1.jsx)("linearGradient", { id: gradientStrokeId, x1: "0%", y1: "0%", x2: "100%", y2: "0%", children: gradientStops }), (0, jsx_runtime_1.jsxs)("linearGradient", { id: gradientAreaId, x1: "0%", y1: "0%", x2: "100%", y2: "0%", children: [areaStops, (0, jsx_runtime_1.jsx)("stop", { offset: "100%", stopColor: colorPrimary, stopOpacity: "0.04" })] })] }), (0, jsx_runtime_1.jsx)(jsx_1.Group, { children: gridElements }), (0, jsx_runtime_1.jsx)(jsx_1.Group, { children: [...axisElements, ...tickElements] }), (0, jsx_runtime_1.jsx)(jsx_1.Group, { children: lineElements }), (0, jsx_runtime_1.jsx)(jsx_1.Group, { children: pointElements }), (0, jsx_runtime_1.jsx)(jsx_1.Group, { children: valueElements }), (0, jsx_runtime_1.jsx)(jsx_1.Group, { children: titleElements }), (0, jsx_runtime_1.jsx)(components_1.ItemsGroup, { children: xLabels })] })] }));
167
+ return ((0, jsx_runtime_1.jsxs)(layouts_1.FlexLayout, { id: "infographic-container", flexDirection: "column", justifyContent: "center", alignItems: "center", children: [titleContent, (0, jsx_runtime_1.jsxs)(jsx_1.Group, { width: totalWidth, height: totalHeight, children: [(0, jsx_runtime_1.jsxs)(jsx_1.Defs, { children: [(0, jsx_runtime_1.jsx)("linearGradient", { id: gradientStrokeId, x1: "0%", y1: "0%", x2: "100%", y2: "0%", children: gradientStops }), (0, jsx_runtime_1.jsx)("linearGradient", { id: gradientAreaId, x1: "0%", y1: "0%", x2: "100%", y2: "0%", children: areaStops })] }), (0, jsx_runtime_1.jsx)(jsx_1.Group, { children: gridElements }), (0, jsx_runtime_1.jsx)(jsx_1.Group, { children: [...axisElements, ...tickElements] }), (0, jsx_runtime_1.jsx)(jsx_1.Group, { children: lineElements }), (0, jsx_runtime_1.jsx)(jsx_1.Group, { children: pointElements }), (0, jsx_runtime_1.jsx)(jsx_1.Group, { children: valueElements }), (0, jsx_runtime_1.jsx)(jsx_1.Group, { children: titleElements }), (0, jsx_runtime_1.jsx)(components_1.ItemsGroup, { children: xLabels })] })] }));
166
168
  };
167
169
  exports.ChartLine = ChartLine;
168
170
  (0, registry_1.registerStructure)('chart-line', {
@@ -76,7 +76,7 @@ function editText(text, options) {
76
76
  const entity = (0, utils_1.getTextEntity)(text);
77
77
  if (!entity)
78
78
  return;
79
- ensureEditorStyles();
79
+ ensureEditorStyles(entity);
80
80
  new InlineTextEditor(entity, options).start();
81
81
  }
82
82
  class InlineTextEditor {
@@ -207,7 +207,7 @@ class InlineTextEditor {
207
207
  return this.entity.textContent || '';
208
208
  }
209
209
  }
210
- function ensureEditorStyles() {
210
+ function ensureEditorStyles(target) {
211
211
  (0, utils_1.injectStyleOnce)(EDITOR_STYLE_ID, `
212
212
  .${EDITOR_BASE_CLASS} {
213
213
  margin: 0;
@@ -220,5 +220,5 @@ function ensureEditorStyles() {
220
220
  .${EDITOR_BASE_CLASS}::selection {
221
221
  background-color: #b3d4fc;
222
222
  }
223
- `);
223
+ `, target);
224
224
  }
@@ -12,9 +12,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.InteractionManager = void 0;
13
13
  const utils_1 = require("../../utils");
14
14
  const utils_2 = require("../utils");
15
+ const utils_3 = require("../utils");
15
16
  class InteractionManager {
16
17
  constructor() {
17
- this.extensions = new utils_2.Extension();
18
+ this.extensions = new utils_3.Extension();
18
19
  this.interactions = [];
19
20
  this.active = false;
20
21
  this.running = null;
@@ -22,14 +23,15 @@ class InteractionManager {
22
23
  this.selection = new Set();
23
24
  this.handleClick = (event) => {
24
25
  const doc = this.editor.getDocument();
25
- const target = event.target;
26
- if (!target) {
26
+ const path = typeof event.composedPath === 'function' ? event.composedPath() : [];
27
+ const insideInfographic = (0, utils_2.eventPathContains)(event, doc) ||
28
+ path.some((node) => node instanceof HTMLElement && (0, utils_1.isInfographicComponent)(node));
29
+ if (!event.target) {
27
30
  this.deactivate();
28
31
  return;
29
32
  }
30
33
  // 点击画布 SVG 或者标记为组件的元素
31
- if (doc.contains(target) ||
32
- (0, utils_1.isInfographicComponent)(target))
34
+ if (insideInfographic)
33
35
  this.activate();
34
36
  else
35
37
  this.deactivate();
@@ -4,9 +4,10 @@ export interface IconButtonProps {
4
4
  icon: Icon;
5
5
  onClick?: () => void;
6
6
  activate?: boolean;
7
+ root?: Node;
7
8
  }
8
9
  export interface IconButtonHandle {
9
10
  activate: boolean;
10
11
  setActivate: (activate: boolean) => void;
11
12
  }
12
- export declare const IconButton: ({ icon, onClick, activate, }: IconButtonProps) => Button;
13
+ export declare const IconButton: ({ icon, onClick, activate, root, }: IconButtonProps) => Button;
@@ -2,8 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.IconButton = void 0;
4
4
  const utils_1 = require("../../../utils");
5
- const IconButton = ({ icon, onClick, activate = false, }) => {
6
- ensureIconButtonStyle();
5
+ const IconButton = ({ icon, onClick, activate = false, root, }) => {
6
+ ensureIconButtonStyle(root);
7
7
  const button = document.createElement('button');
8
8
  button.type = 'button';
9
9
  button.classList.add(ICON_BUTTON_CLASS);
@@ -27,7 +27,7 @@ const IconButton = ({ icon, onClick, activate = false, }) => {
27
27
  exports.IconButton = IconButton;
28
28
  const ICON_BUTTON_CLASS = 'infographic-edit-bar-icon-btn';
29
29
  const ICON_BUTTON_STYLE_ID = 'infographic-edit-bar-icon-btn-style';
30
- function ensureIconButtonStyle() {
30
+ function ensureIconButtonStyle(target) {
31
31
  (0, utils_1.injectStyleOnce)(ICON_BUTTON_STYLE_ID, `
32
32
  .${ICON_BUTTON_CLASS} {
33
33
  padding: 0;
@@ -53,5 +53,5 @@ function ensureIconButtonStyle() {
53
53
  .${ICON_BUTTON_CLASS}[data-activate="true"] {
54
54
  background-color: #d9d9d9;
55
55
  }
56
- `);
56
+ `, target);
57
57
  }
@@ -2,6 +2,7 @@ export type ColorPickerProps = {
2
2
  value?: string;
3
3
  swatches?: string[];
4
4
  onChange?: (value: string) => void;
5
+ root?: Node;
5
6
  };
6
7
  export type ColorPickerHandle = {
7
8
  setValue: (value?: string) => void;
@@ -49,7 +49,7 @@ function ColorPicker(props) {
49
49
  if (typeof document === 'undefined') {
50
50
  throw new Error('ColorPicker can only be used in the browser.');
51
51
  }
52
- ensureColorPickerStyles();
52
+ ensureColorPickerStyles(props.root);
53
53
  const container = document.createElement('div');
54
54
  container.classList.add(COLOR_PICKER_CLASS);
55
55
  const swatchContainer = document.createElement('div');
@@ -242,7 +242,7 @@ function createSwitchLabel(text) {
242
242
  span.classList.add(COLOR_PICKER_SWITCH_LABEL_CLASS);
243
243
  return span;
244
244
  }
245
- function ensureColorPickerStyles() {
245
+ function ensureColorPickerStyles(target) {
246
246
  (0, utils_1.injectStyleOnce)(COLOR_PICKER_STYLE_ID, `
247
247
  .${COLOR_PICKER_CLASS} {
248
248
  width: 240px;
@@ -353,5 +353,5 @@ function ensureColorPickerStyles() {
353
353
  .${COLOR_PICKER_SWITCH_CLASS}[data-format="rgba"] .${COLOR_PICKER_SWITCH_LABEL_CLASS}:last-child {
354
354
  color: #ffffff;
355
355
  }
356
- `);
356
+ `, target);
357
357
  }
@@ -3,7 +3,7 @@ export type PopoverPlacementPreference = PopoverPlacement | PopoverPlacement[];
3
3
  export interface PopoverProps {
4
4
  content: HTMLElement | string | (() => HTMLElement | string);
5
5
  target?: HTMLElement;
6
- getContainer?: HTMLElement | (() => HTMLElement);
6
+ getContainer?: OverlayRoot | (() => OverlayRoot);
7
7
  placement?: PopoverPlacementPreference;
8
8
  padding?: number | string;
9
9
  open?: boolean;
@@ -13,6 +13,7 @@ export interface PopoverProps {
13
13
  mouseLeaveDelay?: number;
14
14
  offset?: number;
15
15
  }
16
+ type OverlayRoot = HTMLElement | ShadowRoot;
16
17
  export interface PopoverHandle {
17
18
  setOpen: (open: boolean) => void;
18
19
  toggle: () => void;
@@ -21,3 +22,4 @@ export interface PopoverHandle {
21
22
  destroy: () => void;
22
23
  }
23
24
  export declare function Popover(props: PopoverProps): HTMLDivElement & PopoverHandle;
25
+ export {};
@@ -1,15 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Popover = Popover;
4
+ const utils_1 = require("../../utils");
4
5
  const constants_1 = require("../../../constants");
5
- const utils_1 = require("../../../utils");
6
+ const utils_2 = require("../../../utils");
6
7
  const POPOVER_CLASS = 'infographic-edit-popover';
7
8
  const POPOVER_CONTENT_CLASS = `${POPOVER_CLASS}__content`;
8
9
  const POPOVER_ARROW_CLASS = `${POPOVER_CLASS}__arrow`;
9
10
  const POPOVER_STYLE_ID = 'infographic-edit-popover-style';
10
11
  function Popover(props) {
11
12
  var _a, _b, _c, _d, _e, _f, _g, _h;
12
- ensurePopoverStyle();
13
13
  const placement = (_a = props.placement) !== null && _a !== void 0 ? _a : 'top';
14
14
  const closeOnOutsideClick = (_b = props.closeOnOutsideClick) !== null && _b !== void 0 ? _b : true;
15
15
  const triggerActions = Array.isArray(props.trigger)
@@ -31,11 +31,11 @@ function Popover(props) {
31
31
  const next = typeof props.getContainer === 'function'
32
32
  ? props.getContainer()
33
33
  : props.getContainer;
34
- return next !== null && next !== void 0 ? next : document.body;
34
+ return next !== null && next !== void 0 ? next : (0, utils_1.getOverlayContainer)(trigger);
35
35
  };
36
36
  const content = document.createElement('div');
37
37
  content.classList.add(POPOVER_CONTENT_CLASS);
38
- (0, utils_1.setElementRole)(content, constants_1.COMPONENT_ROLE);
38
+ (0, utils_2.setElementRole)(content, constants_1.COMPONENT_ROLE);
39
39
  content.dataset.placement = Array.isArray(placement)
40
40
  ? placement[0]
41
41
  : placement;
@@ -44,7 +44,18 @@ function Popover(props) {
44
44
  content.style.setProperty('--popover-arrow-size', `${arrowSize}px`);
45
45
  content.style.setProperty('--popover-arrow-inner-size', `${arrowInnerSize}px`);
46
46
  const contentContainer = getContentContainer();
47
+ ensurePopoverStyle(contentContainer);
47
48
  const isPortal = contentContainer !== container;
49
+ const getPortalOffsetParent = () => {
50
+ const offsetParent = content.offsetParent;
51
+ if (offsetParent)
52
+ return offsetParent;
53
+ if (contentContainer instanceof ShadowRoot)
54
+ return contentContainer.host;
55
+ if (contentContainer instanceof HTMLElement)
56
+ return contentContainer;
57
+ return document.documentElement;
58
+ };
48
59
  const arrow = document.createElement('div');
49
60
  arrow.classList.add(POPOVER_ARROW_CLASS);
50
61
  content.appendChild(arrow);
@@ -122,8 +133,17 @@ function Popover(props) {
122
133
  if (!isPortal)
123
134
  return;
124
135
  ({ left, top } = position);
125
- content.style.left = `${left}px`;
126
- content.style.top = `${top}px`;
136
+ const offsetParent = getPortalOffsetParent();
137
+ if (offsetParent === document.body ||
138
+ offsetParent === document.documentElement) {
139
+ content.style.left = `${left}px`;
140
+ content.style.top = `${top}px`;
141
+ }
142
+ else {
143
+ const parentRect = offsetParent.getBoundingClientRect();
144
+ content.style.left = `${left - parentRect.left + offsetParent.scrollLeft}px`;
145
+ content.style.top = `${top - parentRect.top + offsetParent.scrollTop}px`;
146
+ }
127
147
  content.style.right = 'auto';
128
148
  content.style.bottom = 'auto';
129
149
  content.style.transform = 'translate(0, 0)';
@@ -167,9 +187,9 @@ function Popover(props) {
167
187
  };
168
188
  const toggle = () => setOpen(!open);
169
189
  const handleOutsideClick = (event) => {
170
- const targetNode = event.target;
171
- if (!container.contains(targetNode) &&
172
- (isPortal ? !content.contains(targetNode) : true)) {
190
+ const insideTrigger = (0, utils_1.eventPathContains)(event, container);
191
+ const insideContent = (0, utils_1.eventPathContains)(event, content);
192
+ if (!insideTrigger && !insideContent) {
173
193
  setOpen(false);
174
194
  }
175
195
  };
@@ -237,8 +257,8 @@ function Popover(props) {
237
257
  };
238
258
  return Object.assign(container, api);
239
259
  }
240
- function ensurePopoverStyle() {
241
- (0, utils_1.injectStyleOnce)(POPOVER_STYLE_ID, `
260
+ function ensurePopoverStyle(target) {
261
+ (0, utils_2.injectStyleOnce)(POPOVER_STYLE_ID, `
242
262
  .${POPOVER_CLASS} {
243
263
  position: relative;
244
264
  display: inline-flex;
@@ -380,5 +400,5 @@ function ensurePopoverStyle() {
380
400
  .${POPOVER_CONTENT_CLASS}[data-placement="right"][data-open="true"] {
381
401
  transform: translate(0, -50%);
382
402
  }
383
- `);
403
+ `, target);
384
404
  }
@@ -4,8 +4,9 @@ import { Plugin } from '../base';
4
4
  export interface EditBarOptions {
5
5
  style?: Partial<CSSStyleDeclaration>;
6
6
  className?: string;
7
- getContainer?: HTMLElement | (() => HTMLElement);
7
+ getContainer?: OverlayRoot | (() => OverlayRoot);
8
8
  }
9
+ type OverlayRoot = HTMLElement | ShadowRoot;
9
10
  type EditItem = HTMLElement;
10
11
  export declare class EditBar extends Plugin implements IPlugin {
11
12
  private options?;
@@ -27,6 +28,7 @@ export declare class EditBar extends Plugin implements IPlugin {
27
28
  protected getGeometryEditItems(_selection: Selection): EditItem[];
28
29
  protected getGeometryCollectionEditItems(selection: Selection): EditItem[];
29
30
  protected getElementCollectionEditItems(selection: Selection): EditItem[];
31
+ private resolveOverlayRoot;
30
32
  private placeEditBar;
31
33
  }
32
34
  export {};