@antv/infographic 0.2.17 → 0.2.19

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 +110 -110
  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 +192 -52
  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 +192 -52
  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 +267 -62
  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 +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 +1 @@
1
- export const ICON_SERVICE_URL = 'https://lab.weavefox.cn/api/v1/infographic/icon';
1
+ export const ICON_SERVICE_URL = 'https://www.weavefox.cn/api/v1/infographic/icon';
@@ -6,6 +6,8 @@ import { ItemsGroup } from '../components/index.js';
6
6
  import { FlexLayout } from '../layouts/index.js';
7
7
  import { getColorPrimary, getPaletteColor, getThemeColors } from '../utils/index.js';
8
8
  import { registerStructure } from './registry.js';
9
+ const ITEM_POSITION_H = 'center';
10
+ const ITEM_POSITION_V = 'normal';
9
11
  export const ChartLine = (props) => {
10
12
  const { Title, Item, data, width, height = 260, gap = 10, padding = 24, showValue = true, options, valueFormatter = (value) => value.toString(), } = props;
11
13
  const { title, desc, items = [], xTitle, yTitle } = data;
@@ -18,8 +20,8 @@ export const ChartLine = (props) => {
18
20
  indexes: [0],
19
21
  datum: items[0],
20
22
  data,
21
- positionH: 'center',
22
- positionV: 'normal',
23
+ positionH: ITEM_POSITION_H,
24
+ positionV: ITEM_POSITION_V,
23
25
  };
24
26
  const sampleBounds = getElementBounds(_jsx(Item, Object.assign({}, itemProps)));
25
27
  const labelWidth = sampleBounds.width;
@@ -159,7 +161,7 @@ export const ChartLine = (props) => {
159
161
  if (yTitle) {
160
162
  titleElements.push(_jsx(Text, { x: paddingLeft + yTitleSpace / 2, y: chartOriginY + height / 2, alignHorizontal: "center", alignVertical: "middle", fontSize: 14, fontWeight: "bold", fill: axisColor, children: yTitle }));
161
163
  }
162
- return (_jsxs(FlexLayout, { id: "infographic-container", flexDirection: "column", justifyContent: "center", alignItems: "center", children: [titleContent, _jsxs(Group, { width: totalWidth, height: totalHeight, children: [_jsxs(Defs, { children: [_jsx("linearGradient", { id: gradientStrokeId, x1: "0%", y1: "0%", x2: "100%", y2: "0%", children: gradientStops }), _jsxs("linearGradient", { id: gradientAreaId, x1: "0%", y1: "0%", x2: "100%", y2: "0%", children: [areaStops, _jsx("stop", { offset: "100%", stopColor: colorPrimary, stopOpacity: "0.04" })] })] }), _jsx(Group, { children: gridElements }), _jsx(Group, { children: [...axisElements, ...tickElements] }), _jsx(Group, { children: lineElements }), _jsx(Group, { children: pointElements }), _jsx(Group, { children: valueElements }), _jsx(Group, { children: titleElements }), _jsx(ItemsGroup, { children: xLabels })] })] }));
164
+ return (_jsxs(FlexLayout, { id: "infographic-container", flexDirection: "column", justifyContent: "center", alignItems: "center", children: [titleContent, _jsxs(Group, { width: totalWidth, height: totalHeight, children: [_jsxs(Defs, { children: [_jsx("linearGradient", { id: gradientStrokeId, x1: "0%", y1: "0%", x2: "100%", y2: "0%", children: gradientStops }), _jsx("linearGradient", { id: gradientAreaId, x1: "0%", y1: "0%", x2: "100%", y2: "0%", children: areaStops })] }), _jsx(Group, { children: gridElements }), _jsx(Group, { children: [...axisElements, ...tickElements] }), _jsx(Group, { children: lineElements }), _jsx(Group, { children: pointElements }), _jsx(Group, { children: valueElements }), _jsx(Group, { children: titleElements }), _jsx(ItemsGroup, { children: xLabels })] })] }));
163
165
  };
164
166
  registerStructure('chart-line', {
165
167
  component: ChartLine,
@@ -72,7 +72,7 @@ function editText(text, options) {
72
72
  const entity = getTextEntity(text);
73
73
  if (!entity)
74
74
  return;
75
- ensureEditorStyles();
75
+ ensureEditorStyles(entity);
76
76
  new InlineTextEditor(entity, options).start();
77
77
  }
78
78
  class InlineTextEditor {
@@ -203,7 +203,7 @@ class InlineTextEditor {
203
203
  return this.entity.textContent || '';
204
204
  }
205
205
  }
206
- function ensureEditorStyles() {
206
+ function ensureEditorStyles(target) {
207
207
  injectStyleOnce(EDITOR_STYLE_ID, `
208
208
  .${EDITOR_BASE_CLASS} {
209
209
  margin: 0;
@@ -216,5 +216,5 @@ function ensureEditorStyles() {
216
216
  .${EDITOR_BASE_CLASS}::selection {
217
217
  background-color: #b3d4fc;
218
218
  }
219
- `);
219
+ `, target);
220
220
  }
@@ -8,6 +8,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  import { createElement, getElementByRole, isInfographicComponent, setElementRole, } from '../../utils/index.js';
11
+ import { eventPathContains } from '../utils/index.js';
11
12
  import { Extension } from '../utils/index.js';
12
13
  export class InteractionManager {
13
14
  constructor() {
@@ -19,14 +20,15 @@ export class InteractionManager {
19
20
  this.selection = new Set();
20
21
  this.handleClick = (event) => {
21
22
  const doc = this.editor.getDocument();
22
- const target = event.target;
23
- if (!target) {
23
+ const path = typeof event.composedPath === 'function' ? event.composedPath() : [];
24
+ const insideInfographic = eventPathContains(event, doc) ||
25
+ path.some((node) => node instanceof HTMLElement && isInfographicComponent(node));
26
+ if (!event.target) {
24
27
  this.deactivate();
25
28
  return;
26
29
  }
27
30
  // 点击画布 SVG 或者标记为组件的元素
28
- if (doc.contains(target) ||
29
- isInfographicComponent(target))
31
+ if (insideInfographic)
30
32
  this.activate();
31
33
  else
32
34
  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;
@@ -1,6 +1,6 @@
1
1
  import { injectStyleOnce } from '../../../utils/index.js';
2
- export const IconButton = ({ icon, onClick, activate = false, }) => {
3
- ensureIconButtonStyle();
2
+ export const IconButton = ({ icon, onClick, activate = false, root, }) => {
3
+ ensureIconButtonStyle(root);
4
4
  const button = document.createElement('button');
5
5
  button.type = 'button';
6
6
  button.classList.add(ICON_BUTTON_CLASS);
@@ -23,7 +23,7 @@ export const IconButton = ({ icon, onClick, activate = false, }) => {
23
23
  };
24
24
  const ICON_BUTTON_CLASS = 'infographic-edit-bar-icon-btn';
25
25
  const ICON_BUTTON_STYLE_ID = 'infographic-edit-bar-icon-btn-style';
26
- function ensureIconButtonStyle() {
26
+ function ensureIconButtonStyle(target) {
27
27
  injectStyleOnce(ICON_BUTTON_STYLE_ID, `
28
28
  .${ICON_BUTTON_CLASS} {
29
29
  padding: 0;
@@ -49,5 +49,5 @@ function ensureIconButtonStyle() {
49
49
  .${ICON_BUTTON_CLASS}[data-activate="true"] {
50
50
  background-color: #d9d9d9;
51
51
  }
52
- `);
52
+ `, target);
53
53
  }
@@ -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;
@@ -46,7 +46,7 @@ export function ColorPicker(props) {
46
46
  if (typeof document === 'undefined') {
47
47
  throw new Error('ColorPicker can only be used in the browser.');
48
48
  }
49
- ensureColorPickerStyles();
49
+ ensureColorPickerStyles(props.root);
50
50
  const container = document.createElement('div');
51
51
  container.classList.add(COLOR_PICKER_CLASS);
52
52
  const swatchContainer = document.createElement('div');
@@ -239,7 +239,7 @@ function createSwitchLabel(text) {
239
239
  span.classList.add(COLOR_PICKER_SWITCH_LABEL_CLASS);
240
240
  return span;
241
241
  }
242
- function ensureColorPickerStyles() {
242
+ function ensureColorPickerStyles(target) {
243
243
  injectStyleOnce(COLOR_PICKER_STYLE_ID, `
244
244
  .${COLOR_PICKER_CLASS} {
245
245
  width: 240px;
@@ -350,5 +350,5 @@ function ensureColorPickerStyles() {
350
350
  .${COLOR_PICKER_SWITCH_CLASS}[data-format="rgba"] .${COLOR_PICKER_SWITCH_LABEL_CLASS}:last-child {
351
351
  color: #ffffff;
352
352
  }
353
- `);
353
+ `, target);
354
354
  }
@@ -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,3 +1,4 @@
1
+ import { eventPathContains, getOverlayContainer } from '../../utils/index.js';
1
2
  import { COMPONENT_ROLE } from '../../../constants/index.js';
2
3
  import { injectStyleOnce, setElementRole } from '../../../utils/index.js';
3
4
  const POPOVER_CLASS = 'infographic-edit-popover';
@@ -6,7 +7,6 @@ const POPOVER_ARROW_CLASS = `${POPOVER_CLASS}__arrow`;
6
7
  const POPOVER_STYLE_ID = 'infographic-edit-popover-style';
7
8
  export function Popover(props) {
8
9
  var _a, _b, _c, _d, _e, _f, _g, _h;
9
- ensurePopoverStyle();
10
10
  const placement = (_a = props.placement) !== null && _a !== void 0 ? _a : 'top';
11
11
  const closeOnOutsideClick = (_b = props.closeOnOutsideClick) !== null && _b !== void 0 ? _b : true;
12
12
  const triggerActions = Array.isArray(props.trigger)
@@ -28,7 +28,7 @@ export function Popover(props) {
28
28
  const next = typeof props.getContainer === 'function'
29
29
  ? props.getContainer()
30
30
  : props.getContainer;
31
- return next !== null && next !== void 0 ? next : document.body;
31
+ return next !== null && next !== void 0 ? next : getOverlayContainer(trigger);
32
32
  };
33
33
  const content = document.createElement('div');
34
34
  content.classList.add(POPOVER_CONTENT_CLASS);
@@ -41,7 +41,18 @@ export function Popover(props) {
41
41
  content.style.setProperty('--popover-arrow-size', `${arrowSize}px`);
42
42
  content.style.setProperty('--popover-arrow-inner-size', `${arrowInnerSize}px`);
43
43
  const contentContainer = getContentContainer();
44
+ ensurePopoverStyle(contentContainer);
44
45
  const isPortal = contentContainer !== container;
46
+ const getPortalOffsetParent = () => {
47
+ const offsetParent = content.offsetParent;
48
+ if (offsetParent)
49
+ return offsetParent;
50
+ if (contentContainer instanceof ShadowRoot)
51
+ return contentContainer.host;
52
+ if (contentContainer instanceof HTMLElement)
53
+ return contentContainer;
54
+ return document.documentElement;
55
+ };
45
56
  const arrow = document.createElement('div');
46
57
  arrow.classList.add(POPOVER_ARROW_CLASS);
47
58
  content.appendChild(arrow);
@@ -119,8 +130,17 @@ export function Popover(props) {
119
130
  if (!isPortal)
120
131
  return;
121
132
  ({ left, top } = position);
122
- content.style.left = `${left}px`;
123
- content.style.top = `${top}px`;
133
+ const offsetParent = getPortalOffsetParent();
134
+ if (offsetParent === document.body ||
135
+ offsetParent === document.documentElement) {
136
+ content.style.left = `${left}px`;
137
+ content.style.top = `${top}px`;
138
+ }
139
+ else {
140
+ const parentRect = offsetParent.getBoundingClientRect();
141
+ content.style.left = `${left - parentRect.left + offsetParent.scrollLeft}px`;
142
+ content.style.top = `${top - parentRect.top + offsetParent.scrollTop}px`;
143
+ }
124
144
  content.style.right = 'auto';
125
145
  content.style.bottom = 'auto';
126
146
  content.style.transform = 'translate(0, 0)';
@@ -164,9 +184,9 @@ export function Popover(props) {
164
184
  };
165
185
  const toggle = () => setOpen(!open);
166
186
  const handleOutsideClick = (event) => {
167
- const targetNode = event.target;
168
- if (!container.contains(targetNode) &&
169
- (isPortal ? !content.contains(targetNode) : true)) {
187
+ const insideTrigger = eventPathContains(event, container);
188
+ const insideContent = eventPathContains(event, content);
189
+ if (!insideTrigger && !insideContent) {
170
190
  setOpen(false);
171
191
  }
172
192
  };
@@ -234,7 +254,7 @@ export function Popover(props) {
234
254
  };
235
255
  return Object.assign(container, api);
236
256
  }
237
- function ensurePopoverStyle() {
257
+ function ensurePopoverStyle(target) {
238
258
  injectStyleOnce(POPOVER_STYLE_ID, `
239
259
  .${POPOVER_CLASS} {
240
260
  position: relative;
@@ -377,5 +397,5 @@ function ensurePopoverStyle() {
377
397
  .${POPOVER_CONTENT_CLASS}[data-placement="right"][data-open="true"] {
378
398
  transform: translate(0, -50%);
379
399
  }
380
- `);
400
+ `, target);
381
401
  }
@@ -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 {};
@@ -1,6 +1,7 @@
1
1
  import { COMPONENT_ROLE } from '../../../constants/index.js';
2
2
  import { getCombinedBounds } from '../../../jsx/index.js';
3
3
  import { getCommonAttrs, getIconAttrs, getTextElementProps, isEditableText, isGeometryElement, isIconElement, setElementRole, } from '../../../utils/index.js';
4
+ import { getOverlayContainer } from '../../utils/index.js';
4
5
  import { Plugin } from '../base.js';
5
6
  import { ElementAlign, FontAlign, FontColor, FontFamily, FontSize, IconColor, } from './edit-items/index.js';
6
7
  export class EditBar extends Plugin {
@@ -109,29 +110,31 @@ export class EditBar extends Plugin {
109
110
  }
110
111
  setElementRole(container, COMPONENT_ROLE);
111
112
  this.container = container;
112
- const { getContainer } = this.options || {};
113
- const resolvedContainer = typeof getContainer === 'function' ? getContainer() : getContainer;
114
- const containerParent = resolvedContainer !== null && resolvedContainer !== void 0 ? resolvedContainer : document.body;
113
+ const containerParent = this.resolveOverlayRoot();
115
114
  containerParent === null || containerParent === void 0 ? void 0 : containerParent.appendChild(container);
116
115
  return container;
117
116
  }
118
117
  getTextEditItems(text) {
119
118
  const { attributes = {} } = getTextElementProps(text);
120
- return [FontColor, FontSize, FontAlign, FontFamily].map((item) => item([text], attributes, this.commander));
119
+ const root = this.resolveOverlayRoot();
120
+ return [FontColor, FontSize, FontAlign, FontFamily].map((item) => item([text], attributes, this.commander, { root }));
121
121
  }
122
122
  getTextCollectionEditItems(selection) {
123
123
  const attrs = getCommonAttrs(selection.map((text) => getTextElementProps(text).attributes || {}));
124
- const items = [FontColor, FontSize, FontAlign, FontFamily].map((item) => item(selection, attrs, this.commander));
124
+ const root = this.resolveOverlayRoot();
125
+ const items = [FontColor, FontSize, FontAlign, FontFamily].map((item) => item(selection, attrs, this.commander, { root }));
125
126
  const commonItems = this.getElementCollectionEditItems(selection);
126
127
  return [...items, ...commonItems];
127
128
  }
128
129
  getIconEditItems(selection) {
129
130
  const attrs = getIconAttrs(selection[0]);
130
- return [IconColor].map((item) => item(selection, attrs, this.commander));
131
+ const root = this.resolveOverlayRoot();
132
+ return [IconColor].map((item) => item(selection, attrs, this.commander, { root }));
131
133
  }
132
134
  getIconCollectionEditItems(selection) {
133
135
  const attrs = getCommonAttrs(selection.map((icon) => getIconAttrs(icon)));
134
- return [IconColor].map((item) => item(selection, attrs, this.commander));
136
+ const root = this.resolveOverlayRoot();
137
+ return [IconColor].map((item) => item(selection, attrs, this.commander, { root }));
135
138
  }
136
139
  getGeometryEditItems(_selection) {
137
140
  return [];
@@ -143,12 +146,19 @@ export class EditBar extends Plugin {
143
146
  getElementCollectionEditItems(selection) {
144
147
  if (selection.length <= 1)
145
148
  return [];
149
+ const root = this.resolveOverlayRoot();
146
150
  return [
147
151
  ElementAlign(selection, {}, this.commander, {
148
152
  enableDistribution: selection.length > 2,
153
+ root,
149
154
  }),
150
155
  ];
151
156
  }
157
+ resolveOverlayRoot() {
158
+ const { getContainer } = this.options || {};
159
+ const resolvedContainer = typeof getContainer === 'function' ? getContainer() : getContainer;
160
+ return resolvedContainer !== null && resolvedContainer !== void 0 ? resolvedContainer : getOverlayContainer(this.editor.getDocument());
161
+ }
152
162
  placeEditBar(container, selection) {
153
163
  var _a;
154
164
  if (selection.length === 0)
@@ -29,17 +29,18 @@ const ALIGN_OPTIONS = [
29
29
  ];
30
30
  export const ElementAlign = (selection, _attrs, commander, options) => {
31
31
  var _a;
32
- injectStyleOnce(GRID_STYLE_ID, GRID_STYLES);
32
+ injectStyleOnce(GRID_STYLE_ID, GRID_STYLES, options === null || options === void 0 ? void 0 : options.root);
33
33
  const enableDistribution = (_a = options === null || options === void 0 ? void 0 : options.enableDistribution) !== null && _a !== void 0 ? _a : true;
34
- const content = createAlignContent((action) => alignSelection(selection, action, commander), enableDistribution);
34
+ const content = createAlignContent((action) => alignSelection(selection, action, commander), enableDistribution, options === null || options === void 0 ? void 0 : options.root);
35
35
  return Popover({
36
- target: IconButton({ icon: ELEMENT_ICONS.align }),
36
+ target: IconButton({ icon: ELEMENT_ICONS.align, root: options === null || options === void 0 ? void 0 : options.root }),
37
37
  content,
38
+ getContainer: options === null || options === void 0 ? void 0 : options.root,
38
39
  placement: 'top',
39
40
  offset: 12,
40
41
  });
41
42
  };
42
- function createAlignContent(onSelect, enableDistribution) {
43
+ function createAlignContent(onSelect, enableDistribution, root) {
43
44
  const content = document.createElement('div');
44
45
  content.classList.add(GRID_CLASS);
45
46
  if (!enableDistribution)
@@ -49,6 +50,7 @@ function createAlignContent(onSelect, enableDistribution) {
49
50
  : ALIGN_OPTIONS.filter(({ action }) => action !== 'H_DISTRIBUTE' && action !== 'V_DISTRIBUTE');
50
51
  visibleOptions.forEach(({ icon, action }) => {
51
52
  const button = IconButton({
53
+ root,
52
54
  icon,
53
55
  onClick: () => onSelect(action),
54
56
  });
@@ -22,13 +22,14 @@ const GRID_STYLES = `
22
22
  gap: 2px;
23
23
  }
24
24
  `;
25
- export const FontAlign = (selection, attrs, commander) => {
26
- injectStyleOnce(GRID_STYLE_ID, GRID_STYLES);
25
+ export const FontAlign = (selection, attrs, commander, options) => {
26
+ const root = options === null || options === void 0 ? void 0 : options.root;
27
+ injectStyleOnce(GRID_STYLE_ID, GRID_STYLES, root);
27
28
  const state = {
28
29
  horizontal: attrs['data-horizontal-align'],
29
30
  vertical: attrs['data-vertical-align'],
30
31
  };
31
- const button = IconButton({ icon: TEXT_ICONS.align });
32
+ const button = IconButton({ icon: TEXT_ICONS.align, root });
32
33
  const content = createAlignContent(state, (align) => {
33
34
  const attributes = {};
34
35
  if (align.horizontal)
@@ -40,15 +41,16 @@ export const FontAlign = (selection, attrs, commander) => {
40
41
  commander.executeBatch(selection.map((text) => new UpdateElementCommand(text, {
41
42
  attributes,
42
43
  })));
43
- });
44
+ }, root);
44
45
  return Popover({
45
46
  target: button,
46
47
  content,
48
+ getContainer: root,
47
49
  placement: 'top',
48
50
  offset: 12,
49
51
  });
50
52
  };
51
- function createAlignContent(state, onAlignChange) {
53
+ function createAlignContent(state, onAlignChange, root) {
52
54
  const content = document.createElement('div');
53
55
  content.classList.add(GRID_CLASS);
54
56
  const buttons = {};
@@ -61,6 +63,7 @@ function createAlignContent(state, onAlignChange) {
61
63
  const createButtons = (options, stateKey) => {
62
64
  options.forEach(({ icon, align }) => {
63
65
  const button = IconButton({
66
+ root,
64
67
  icon,
65
68
  onClick: () => {
66
69
  if (state[stateKey] === align)
@@ -4,8 +4,9 @@ import { ColorPicker, Popover } from '../../components/index.js';
4
4
  const FONT_COLOR_BUTTON_CLASS = 'infographic-font-color-btn';
5
5
  const FONT_COLOR_STYLE_ID = 'infographic-font-color-style';
6
6
  const DEFAULT_COLOR = '#1f1f1f';
7
- export const FontColor = (selection, attrs, commander) => {
8
- ensureFontColorStyles();
7
+ export const FontColor = (selection, attrs, commander, options) => {
8
+ const root = options === null || options === void 0 ? void 0 : options.root;
9
+ ensureFontColorStyles(root);
9
10
  const color = normalizeColor(attrs.fill);
10
11
  const isMixed = attrs.fill === undefined && selection.length > 1;
11
12
  const button = document.createElement('button');
@@ -13,6 +14,7 @@ export const FontColor = (selection, attrs, commander) => {
13
14
  button.classList.add(FONT_COLOR_BUTTON_CLASS);
14
15
  setButtonColor(button, color !== null && color !== void 0 ? color : DEFAULT_COLOR, isMixed);
15
16
  const picker = ColorPicker({
17
+ root,
16
18
  value: color !== null && color !== void 0 ? color : DEFAULT_COLOR,
17
19
  onChange: (nextColor) => {
18
20
  setButtonColor(button, nextColor, false);
@@ -24,6 +26,7 @@ export const FontColor = (selection, attrs, commander) => {
24
26
  return Popover({
25
27
  target: button,
26
28
  content: picker,
29
+ getContainer: root,
27
30
  placement: ['top', 'bottom'],
28
31
  offset: 12,
29
32
  trigger: 'hover',
@@ -44,7 +47,7 @@ function setButtonColor(button, color, mixed) {
44
47
  else
45
48
  button.removeAttribute('data-mixed');
46
49
  }
47
- function ensureFontColorStyles() {
50
+ function ensureFontColorStyles(target) {
48
51
  injectStyleOnce(FONT_COLOR_STYLE_ID, `
49
52
  .${FONT_COLOR_BUTTON_CLASS} {
50
53
  position: relative;
@@ -73,5 +76,5 @@ function ensureFontColorStyles() {
73
76
  #f5f5f5 12px
74
77
  );
75
78
  }
76
- `);
79
+ `, target);
77
80
  }
@@ -6,22 +6,23 @@ const FONT_LIST_CLASS = 'infographic-font-family-list';
6
6
  const FONT_OPTION_CLASS = `${FONT_LIST_CLASS}__option`;
7
7
  const FONT_LIST_STYLE_ID = 'infographic-font-family-list-style';
8
8
  const DEFAULT_FONT_LABEL = '默认';
9
- export const FontFamily = (selection, attrs, commander) => {
10
- ensureFontFamilyListStyle();
9
+ export const FontFamily = (selection, attrs, commander, editItemOptions) => {
10
+ const root = editItemOptions === null || editItemOptions === void 0 ? void 0 : editItemOptions.root;
11
+ ensureFontFamilyListStyle(root);
11
12
  const fonts = getFonts();
12
13
  const current = normalizeFontFamily(attrs['font-family']);
13
- const options = fonts.map((font) => ({
14
+ const fontOptions = fonts.map((font) => ({
14
15
  label: font.name || font.fontFamily,
15
16
  value: font.fontFamily,
16
17
  }));
17
- if (!options.some((option) => normalizeFontFamily(option.value) === current)) {
18
- options.unshift({
18
+ if (!fontOptions.some((option) => normalizeFontFamily(option.value) === current)) {
19
+ fontOptions.unshift({
19
20
  label: DEFAULT_FONT_LABEL,
20
21
  value: current,
21
22
  });
22
23
  }
23
24
  let selected = current;
24
- const content = createFontList(options, selected, (value) => {
25
+ const content = createFontList(fontOptions, selected, (value) => {
25
26
  if (selected === value)
26
27
  return;
27
28
  selected = value;
@@ -29,10 +30,11 @@ export const FontFamily = (selection, attrs, commander) => {
29
30
  attributes: { 'font-family': decodeFontFamily(value) },
30
31
  })));
31
32
  });
32
- const button = IconButton({ icon: TEXT_ICONS.fontFamily });
33
+ const button = IconButton({ icon: TEXT_ICONS.fontFamily, root });
33
34
  const popover = Popover({
34
35
  target: button,
35
36
  content,
37
+ getContainer: root,
36
38
  placement: ['top', 'bottom'],
37
39
  offset: 12,
38
40
  trigger: 'hover',
@@ -81,7 +83,7 @@ function normalizeFontFamily(font) {
81
83
  return encodeFontFamily(font.join(', '));
82
84
  return encodeFontFamily(String(font));
83
85
  }
84
- function ensureFontFamilyListStyle() {
86
+ function ensureFontFamilyListStyle(target) {
85
87
  injectStyleOnce(FONT_LIST_STYLE_ID, `
86
88
  .${FONT_LIST_CLASS} {
87
89
  display: flex;
@@ -111,5 +113,5 @@ function ensureFontFamilyListStyle() {
111
113
  background: #e6f4ff;
112
114
  color: #0958d9;
113
115
  }
114
- `);
116
+ `, target);
115
117
  }
@@ -18,23 +18,25 @@ const FONT_SIZE_STYLES = `
18
18
  gap: 2px;
19
19
  }
20
20
  `;
21
- export const FontSize = (selection, attrs, commander) => {
22
- injectStyleOnce(FONT_SIZE_STYLE_ID, FONT_SIZE_STYLES);
23
- const button = IconButton({ icon: TEXT_ICONS.fontSize });
21
+ export const FontSize = (selection, attrs, commander, options) => {
22
+ const root = options === null || options === void 0 ? void 0 : options.root;
23
+ injectStyleOnce(FONT_SIZE_STYLE_ID, FONT_SIZE_STYLES, root);
24
+ const button = IconButton({ icon: TEXT_ICONS.fontSize, root });
24
25
  const currentSize = normalizeFontSize(attrs['font-size']);
25
26
  const content = createFontSizeContent(currentSize, (size) => {
26
27
  commander.executeBatch(selection.map((text) => new UpdateElementCommand(text, {
27
28
  attributes: { 'font-size': size },
28
29
  })));
29
- });
30
+ }, root);
30
31
  return Popover({
31
32
  target: button,
32
33
  content,
34
+ getContainer: root,
33
35
  placement: 'top',
34
36
  offset: 12,
35
37
  });
36
38
  };
37
- function createFontSizeContent(defaultSize, onSizeChange) {
39
+ function createFontSizeContent(defaultSize, onSizeChange, root) {
38
40
  const content = document.createElement('div');
39
41
  content.classList.add(FONT_SIZE_CLASS);
40
42
  let selected = defaultSize;
@@ -47,6 +49,7 @@ function createFontSizeContent(defaultSize, onSizeChange) {
47
49
  };
48
50
  FONT_SIZE_OPTIONS.forEach(({ label, value }) => {
49
51
  const button = IconButton({
52
+ root,
50
53
  icon: createLabelIcon(label),
51
54
  onClick: () => {
52
55
  if (selected === value)
@@ -4,8 +4,9 @@ import { ColorPicker, Popover } from '../../components/index.js';
4
4
  const ICON_COLOR_BUTTON_CLASS = 'infographic-icon-color-btn';
5
5
  const ICON_COLOR_STYLE_ID = 'infographic-icon-color-style';
6
6
  const DEFAULT_COLOR = '#1f1f1f';
7
- export const IconColor = (selection, attrs, commander) => {
8
- ensureIconColorStyles();
7
+ export const IconColor = (selection, attrs, commander, options) => {
8
+ const root = options === null || options === void 0 ? void 0 : options.root;
9
+ ensureIconColorStyles(root);
9
10
  const color = normalizeColor(attrs.fill);
10
11
  const isMixed = attrs.fill === undefined && selection.length > 1;
11
12
  const button = document.createElement('button');
@@ -13,6 +14,7 @@ export const IconColor = (selection, attrs, commander) => {
13
14
  button.classList.add(ICON_COLOR_BUTTON_CLASS);
14
15
  setButtonColor(button, color !== null && color !== void 0 ? color : DEFAULT_COLOR, isMixed);
15
16
  const picker = ColorPicker({
17
+ root,
16
18
  value: color !== null && color !== void 0 ? color : DEFAULT_COLOR,
17
19
  onChange: (nextColor) => {
18
20
  setButtonColor(button, nextColor, false);
@@ -24,6 +26,7 @@ export const IconColor = (selection, attrs, commander) => {
24
26
  return Popover({
25
27
  target: button,
26
28
  content: picker,
29
+ getContainer: root,
27
30
  placement: ['top', 'bottom'],
28
31
  offset: 12,
29
32
  trigger: 'hover',
@@ -44,7 +47,7 @@ function setButtonColor(button, color, mixed) {
44
47
  else
45
48
  button.removeAttribute('data-mixed');
46
49
  }
47
- function ensureIconColorStyles() {
50
+ function ensureIconColorStyles(target) {
48
51
  injectStyleOnce(ICON_COLOR_STYLE_ID, `
49
52
  .${ICON_COLOR_BUTTON_CLASS} {
50
53
  position: relative;
@@ -73,5 +76,5 @@ function ensureIconColorStyles() {
73
76
  #f5f5f5 12px
74
77
  );
75
78
  }
76
- `);
79
+ `, target);
77
80
  }
@@ -1,3 +1,7 @@
1
1
  import type { BaseAttributes } from '../../../../types';
2
2
  import type { ICommandManager, Selection } from '../../../types';
3
- export type EditItem<T extends BaseAttributes = BaseAttributes> = (selection: Selection, attrs: T, commander: ICommandManager, options?: Record<string, any>) => HTMLElement;
3
+ export type EditItemOptions = {
4
+ root?: HTMLElement | ShadowRoot;
5
+ [key: string]: any;
6
+ };
7
+ export type EditItem<T extends BaseAttributes = BaseAttributes> = (selection: Selection, attrs: T, commander: ICommandManager, options?: EditItemOptions) => HTMLElement;
@@ -3,8 +3,9 @@ import { Plugin } from './base';
3
3
  export interface ResetViewBoxOptions {
4
4
  style?: Partial<CSSStyleDeclaration>;
5
5
  className?: string;
6
- getContainer?: HTMLElement | (() => HTMLElement);
6
+ getContainer?: OverlayRoot | (() => OverlayRoot);
7
7
  }
8
+ type OverlayRoot = HTMLElement | ShadowRoot;
8
9
  export declare class ResetViewBox extends Plugin implements IPlugin {
9
10
  private options?;
10
11
  name: string;
@@ -29,5 +30,7 @@ export declare class ResetViewBox extends Plugin implements IPlugin {
29
30
  private showButton;
30
31
  private hideButton;
31
32
  private removeButton;
33
+ private resolveOverlayRoot;
32
34
  private ensureButtonStyle;
33
35
  }
36
+ export {};