@tmagic/stage 1.3.5 → 1.3.7

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.
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.3.5",
2
+ "version": "1.3.7",
3
3
  "name": "@tmagic/stage",
4
4
  "type": "module",
5
5
  "sideEffects": [
@@ -17,13 +17,8 @@
17
17
  "./*": "./*"
18
18
  },
19
19
  "license": "Apache-2.0",
20
- "scripts": {
21
- "build": "npm run build:type && vite build",
22
- "build:type": "npm run clear:type && tsc --declaration --emitDeclarationOnly --project tsconfig.build.json",
23
- "clear:type": "rimraf ./types"
24
- },
25
20
  "engines": {
26
- "node": ">=14"
21
+ "node": ">=18"
27
22
  },
28
23
  "repository": {
29
24
  "type": "git",
@@ -31,9 +26,9 @@
31
26
  },
32
27
  "dependencies": {
33
28
  "@scena/guides": "^0.29.2",
34
- "@tmagic/core": "1.3.5",
35
- "@tmagic/schema": "1.3.5",
36
- "@tmagic/utils": "1.3.5",
29
+ "@tmagic/core": "1.3.7",
30
+ "@tmagic/schema": "1.3.7",
31
+ "@tmagic/utils": "1.3.7",
37
32
  "events": "^3.3.0",
38
33
  "keycon": "^1.4.0",
39
34
  "lodash-es": "^4.17.21",
@@ -43,10 +38,15 @@
43
38
  "devDependencies": {
44
39
  "@types/events": "^3.0.0",
45
40
  "@types/lodash-es": "^4.17.4",
46
- "@types/node": "^15.12.4",
41
+ "@types/node": "^18.19.0",
47
42
  "rimraf": "^3.0.2",
48
43
  "sass": "^1.35.1",
49
44
  "typescript": "^5.0.4",
50
- "vite": "^4.4.4"
45
+ "vite": "^5.0.7"
46
+ },
47
+ "scripts": {
48
+ "build": "npm run build:type && vite build",
49
+ "build:type": "npm run clear:type && tsc --declaration --emitDeclarationOnly --project tsconfig.build.json",
50
+ "clear:type": "rimraf ./types"
51
51
  }
52
- }
52
+ }
@@ -57,7 +57,7 @@ const defaultContainerHighlightDuration = 800;
57
57
  */
58
58
  export default class ActionManager extends EventEmitter {
59
59
  private dr: StageDragResize;
60
- private multiDr: StageMultiDragResize;
60
+ private multiDr?: StageMultiDragResize;
61
61
  private highlightLayer: StageHighlight;
62
62
  /** 单选、多选、高亮的容器(蒙层的content) */
63
63
  private container: HTMLElement;
@@ -81,6 +81,8 @@ export default class ActionManager extends EventEmitter {
81
81
  private canSelect: CanSelect;
82
82
  private isContainer: IsContainer;
83
83
  private getRenderDocument: GetRenderDocument;
84
+ private disabledMultiSelect = false;
85
+ private config: ActionManagerConfig;
84
86
 
85
87
  private mouseMoveHandler = throttle(async (event: MouseEvent): Promise<void> => {
86
88
  if ((event.target as HTMLDivElement)?.classList?.contains('moveable-direction')) {
@@ -99,41 +101,24 @@ export default class ActionManager extends EventEmitter {
99
101
 
100
102
  constructor(config: ActionManagerConfig) {
101
103
  super();
104
+ this.config = config;
102
105
  this.container = config.container;
103
106
  this.containerHighlightClassName = config.containerHighlightClassName || CONTAINER_HIGHLIGHT_CLASS_NAME;
104
107
  this.containerHighlightDuration = config.containerHighlightDuration || defaultContainerHighlightDuration;
105
108
  this.containerHighlightType = config.containerHighlightType;
109
+ this.disabledMultiSelect = config.disabledMultiSelect ?? false;
106
110
  this.getTargetElement = config.getTargetElement;
107
111
  this.getElementsFromPoint = config.getElementsFromPoint;
108
112
  this.canSelect = config.canSelect || ((el: HTMLElement) => !!el.id);
109
113
  this.getRenderDocument = config.getRenderDocument;
110
114
  this.isContainer = config.isContainer;
111
115
 
112
- const createDrHelper = () =>
113
- new DragResizeHelper({
114
- container: config.container,
115
- updateDragEl: config.updateDragEl,
116
- });
116
+ this.dr = this.createDr(config);
117
+
118
+ if (!this.disabledMultiSelect) {
119
+ this.multiDr = this.createMultiDr(config);
120
+ }
117
121
 
118
- this.dr = new StageDragResize({
119
- container: config.container,
120
- disabledDragStart: config.disabledDragStart,
121
- moveableOptions: this.changeCallback(config.moveableOptions, false),
122
- dragResizeHelper: createDrHelper(),
123
- getRootContainer: config.getRootContainer,
124
- getRenderDocument: config.getRenderDocument,
125
- markContainerEnd: this.markContainerEnd.bind(this),
126
- delayedMarkContainer: this.delayedMarkContainer.bind(this),
127
- });
128
- this.multiDr = new StageMultiDragResize({
129
- container: config.container,
130
- moveableOptions: this.changeCallback(config.moveableOptions, true),
131
- dragResizeHelper: createDrHelper(),
132
- getRootContainer: config.getRootContainer,
133
- getRenderDocument: config.getRenderDocument,
134
- markContainerEnd: this.markContainerEnd.bind(this),
135
- delayedMarkContainer: this.delayedMarkContainer.bind(this),
136
- });
137
122
  this.highlightLayer = new StageHighlight({
138
123
  container: config.container,
139
124
  updateDragEl: config.updateDragEl,
@@ -142,7 +127,22 @@ export default class ActionManager extends EventEmitter {
142
127
 
143
128
  this.initMouseEvent();
144
129
  this.initKeyEvent();
145
- this.initActionEvent();
130
+ }
131
+
132
+ public disableMultiSelect() {
133
+ this.disabledMultiSelect = true;
134
+ if (this.multiDr) {
135
+ this.multiDr.destroy();
136
+ this.multiDr = undefined;
137
+ }
138
+ }
139
+
140
+ public enableMultiSelect() {
141
+ this.disabledMultiSelect = false;
142
+
143
+ if (!this.multiDr) {
144
+ this.multiDr = this.createMultiDr(this.config);
145
+ }
146
146
  }
147
147
 
148
148
  /**
@@ -152,7 +152,7 @@ export default class ActionManager extends EventEmitter {
152
152
  */
153
153
  public setGuidelines(type: GuidesType, guidelines: number[]): void {
154
154
  this.dr.setGuidelines(type, guidelines);
155
- this.multiDr.setGuidelines(type, guidelines);
155
+ this.multiDr?.setGuidelines(type, guidelines);
156
156
  }
157
157
 
158
158
  /**
@@ -160,7 +160,7 @@ export default class ActionManager extends EventEmitter {
160
160
  */
161
161
  public clearGuides(): void {
162
162
  this.dr.clearGuides();
163
- this.multiDr.clearGuides();
163
+ this.multiDr?.clearGuides();
164
164
  }
165
165
 
166
166
  /**
@@ -170,7 +170,7 @@ export default class ActionManager extends EventEmitter {
170
170
  public updateMoveable(el?: HTMLElement): void {
171
171
  this.dr.updateMoveable(el);
172
172
  // 多选时不可配置元素,因此不存在多选元素变更,不需要传el
173
- this.multiDr.updateMoveable();
173
+ this.multiDr?.updateMoveable();
174
174
  }
175
175
 
176
176
  /**
@@ -181,7 +181,7 @@ export default class ActionManager extends EventEmitter {
181
181
  return el.id === this.selectedEl?.id;
182
182
  }
183
183
 
184
- public setSelectedEl(el: HTMLElement): void {
184
+ public setSelectedEl(el?: HTMLElement): void {
185
185
  this.selectedEl = el;
186
186
  }
187
187
 
@@ -197,7 +197,7 @@ export default class ActionManager extends EventEmitter {
197
197
  if (this.dr.getTarget()) {
198
198
  return this.dr.getOption(key);
199
199
  }
200
- if (this.multiDr.targetList.length) {
200
+ if (this.multiDr?.targetList.length) {
201
201
  return this.multiDr.getOption(key);
202
202
  }
203
203
  }
@@ -254,11 +254,11 @@ export default class ActionManager extends EventEmitter {
254
254
  if (selectedEl?.className.includes(PAGE_CLASS)) {
255
255
  return true;
256
256
  }
257
- return this.multiDr.canSelect(el, selectedEl);
257
+ return this.multiDr?.canSelect(el, selectedEl) || false;
258
258
  }
259
259
 
260
260
  public select(el: HTMLElement, event: MouseEvent | undefined): void {
261
- this.selectedEl = el;
261
+ this.setSelectedEl(el);
262
262
  this.clearSelectStatus(SelectStatus.MULTI_SELECT);
263
263
  this.dr.select(el, event);
264
264
  }
@@ -266,7 +266,7 @@ export default class ActionManager extends EventEmitter {
266
266
  public multiSelect(idOrElList: HTMLElement[] | Id[]): void {
267
267
  this.selectedElList = idOrElList.map((idOrEl) => this.getTargetElement(idOrEl));
268
268
  this.clearSelectStatus(SelectStatus.SELECT);
269
- this.multiDr.multiSelect(this.selectedElList);
269
+ this.multiDr?.multiSelect(this.selectedElList);
270
270
  }
271
271
 
272
272
  public getHighlightEl(): HTMLElement | undefined {
@@ -287,7 +287,7 @@ export default class ActionManager extends EventEmitter {
287
287
  }
288
288
 
289
289
  // 选中组件不高亮、多选拖拽状态不高亮
290
- if (el === this.getSelectedEl() || this.multiDr.dragStatus === StageDragStatus.ING) {
290
+ if (el === this.getSelectedEl() || this.multiDr?.dragStatus === StageDragStatus.ING) {
291
291
  this.clearHighlight();
292
292
  return;
293
293
  }
@@ -309,7 +309,7 @@ export default class ActionManager extends EventEmitter {
309
309
  */
310
310
  public clearSelectStatus(selectType: SelectStatus): void {
311
311
  if (selectType === SelectStatus.MULTI_SELECT) {
312
- this.multiDr.clearSelectStatus();
312
+ this.multiDr?.clearSelectStatus();
313
313
  this.selectedElList = [];
314
314
  } else {
315
315
  this.dr.clearSelectStatus();
@@ -361,10 +361,84 @@ export default class ActionManager extends EventEmitter {
361
361
  this.container.removeEventListener('mouseleave', this.mouseLeaveHandler);
362
362
  this.container.removeEventListener('wheel', this.mouseWheelHandler);
363
363
  this.dr.destroy();
364
- this.multiDr.destroy();
364
+ this.multiDr?.destroy();
365
365
  this.highlightLayer.destroy();
366
366
  }
367
367
 
368
+ private createDr(config: ActionManagerConfig) {
369
+ const createDrHelper = () =>
370
+ new DragResizeHelper({
371
+ container: config.container,
372
+ updateDragEl: config.updateDragEl,
373
+ });
374
+
375
+ const dr = new StageDragResize({
376
+ container: config.container,
377
+ disabledDragStart: config.disabledDragStart,
378
+ moveableOptions: this.changeCallback(config.moveableOptions, false),
379
+ dragResizeHelper: createDrHelper(),
380
+ getRootContainer: config.getRootContainer,
381
+ getRenderDocument: config.getRenderDocument,
382
+ markContainerEnd: this.markContainerEnd.bind(this),
383
+ delayedMarkContainer: this.delayedMarkContainer.bind(this),
384
+ });
385
+
386
+ dr.on('update', (data: UpdateEventData) => {
387
+ // 点击组件并立即拖动的场景,要保证select先被触发,延迟update通知
388
+ setTimeout(() => this.emit('update', data));
389
+ })
390
+ .on('sort', (data: UpdateEventData) => {
391
+ // 点击组件并立即拖动的场景,要保证select先被触发,延迟update通知
392
+ setTimeout(() => this.emit('sort', data));
393
+ })
394
+ .on('select-parent', () => {
395
+ this.emit('select-parent');
396
+ })
397
+ .on('remove', () => {
398
+ const drTarget = this.dr.getTarget();
399
+ if (!drTarget) return;
400
+ const data: RemoveEventData = {
401
+ data: [{ el: drTarget }],
402
+ };
403
+ this.emit('remove', data);
404
+ })
405
+ .on('drag-start', (e: OnDragStart) => {
406
+ this.emit('drag-start', e);
407
+ });
408
+
409
+ return dr;
410
+ }
411
+
412
+ private createMultiDr(config: ActionManagerConfig) {
413
+ const createDrHelper = () =>
414
+ new DragResizeHelper({
415
+ container: config.container,
416
+ updateDragEl: config.updateDragEl,
417
+ });
418
+ const multiDr = new StageMultiDragResize({
419
+ container: config.container,
420
+ moveableOptions: this.changeCallback(config.moveableOptions, true),
421
+ dragResizeHelper: createDrHelper(),
422
+ getRootContainer: config.getRootContainer,
423
+ getRenderDocument: config.getRenderDocument,
424
+ markContainerEnd: this.markContainerEnd.bind(this),
425
+ delayedMarkContainer: this.delayedMarkContainer.bind(this),
426
+ });
427
+
428
+ multiDr
429
+ ?.on('update', (data: UpdateEventData) => {
430
+ this.emit('multi-update', data);
431
+ })
432
+ .on('change-to-select', async (id: Id) => {
433
+ // 如果还在多选状态,不触发切换到单选
434
+ if (this.isMultiSelectStatus) return false;
435
+ const el = this.getTargetElement(id);
436
+ this.emit('change-to-select', el);
437
+ });
438
+
439
+ return multiDr;
440
+ }
441
+
368
442
  private changeCallback(options: CustomizeMoveableOptions, isMulti: boolean): CustomizeMoveableOptions {
369
443
  // 在actionManager才能获取到各种参数,在这里传好参数有比较好的扩展性
370
444
  if (typeof options === 'function') {
@@ -399,7 +473,7 @@ export default class ActionManager extends EventEmitter {
399
473
  // 如果已有单选选中元素,不是magic-ui-page就可以加入多选列表
400
474
  if (this.selectedEl && !this.selectedEl.className.includes(PAGE_CLASS)) {
401
475
  this.selectedElList.push(this.selectedEl as HTMLElement);
402
- this.selectedEl = undefined;
476
+ this.setSelectedEl(undefined);
403
477
  }
404
478
  // 判断元素是否已在多选列表
405
479
  const existIndex = this.selectedElList.findIndex((selectedDom) => selectedDom.id === el.id);
@@ -450,15 +524,21 @@ export default class ActionManager extends EventEmitter {
450
524
  // 多选启用状态监听
451
525
  KeyController.global.keydown(ctrl, (e) => {
452
526
  e.inputEvent.preventDefault();
453
- this.isMultiSelectStatus = true;
527
+ if (!this.disabledMultiSelect) {
528
+ this.isMultiSelectStatus = true;
529
+ }
454
530
  });
455
531
  // ctrl+tab切到其他窗口,需要将多选状态置为false
456
532
  KeyController.global.on('blur', () => {
457
- this.isMultiSelectStatus = false;
533
+ if (!this.disabledMultiSelect) {
534
+ this.isMultiSelectStatus = false;
535
+ }
458
536
  });
459
537
  KeyController.global.keyup(ctrl, (e) => {
460
538
  e.inputEvent.preventDefault();
461
- this.isMultiSelectStatus = false;
539
+ if (!this.disabledMultiSelect) {
540
+ this.isMultiSelectStatus = false;
541
+ }
462
542
  });
463
543
 
464
544
  // alt健监听,用于启用拖拽组件加入容器状态
@@ -474,46 +554,6 @@ export default class ActionManager extends EventEmitter {
474
554
  });
475
555
  }
476
556
 
477
- /**
478
- * 处理单选、多选抛出来的事件
479
- */
480
- private initActionEvent(): void {
481
- this.dr
482
- .on('update', (data: UpdateEventData) => {
483
- // 点击组件并立即拖动的场景,要保证select先被触发,延迟update通知
484
- setTimeout(() => this.emit('update', data));
485
- })
486
- .on('sort', (data: UpdateEventData) => {
487
- // 点击组件并立即拖动的场景,要保证select先被触发,延迟update通知
488
- setTimeout(() => this.emit('sort', data));
489
- })
490
- .on('select-parent', () => {
491
- this.emit('select-parent');
492
- })
493
- .on('remove', () => {
494
- const drTarget = this.dr.getTarget();
495
- if (!drTarget) return;
496
- const data: RemoveEventData = {
497
- data: [{ el: drTarget }],
498
- };
499
- this.emit('remove', data);
500
- })
501
- .on('drag-start', (e: OnDragStart) => {
502
- this.emit('drag-start', e);
503
- });
504
-
505
- this.multiDr
506
- .on('update', (data: UpdateEventData) => {
507
- this.emit('multi-update', data);
508
- })
509
- .on('change-to-select', async (id: Id) => {
510
- // 如果还在多选状态,不触发切换到单选
511
- if (this.isMultiSelectStatus) return false;
512
- const el = this.getTargetElement(id);
513
- this.emit('change-to-select', el);
514
- });
515
- }
516
-
517
557
  /**
518
558
  * 在down事件中集中cpu处理画布中选中操作渲染,在up事件中再通知外面的编辑器更新
519
559
  */
@@ -561,13 +601,13 @@ export default class ActionManager extends EventEmitter {
561
601
  /**
562
602
  * 在up事件中负责对外通知选中事件,通知画布之外的编辑器更新
563
603
  */
564
- private mouseUpHandler = (): void => {
604
+ private mouseUpHandler = (event: MouseEvent): void => {
565
605
  getDocument().removeEventListener('mouseup', this.mouseUpHandler);
566
606
  this.container.addEventListener('mousemove', this.mouseMoveHandler);
567
607
  if (this.isMultiSelectStatus) {
568
- this.emit('multi-select', this.selectedElList);
608
+ this.emit('multi-select', this.selectedElList, event);
569
609
  } else {
570
- this.emit('select', this.selectedEl);
610
+ this.emit('select', this.selectedEl, event);
571
611
  }
572
612
  };
573
613
 
@@ -1,7 +1,7 @@
1
1
  import { MoveableManagerInterface, Renderer } from 'moveable';
2
2
 
3
+ import { AbleActionEventType } from './const';
3
4
  import ableCss from './moveable-able.css?raw';
4
- import { AbleActionEventType } from './types';
5
5
 
6
6
  export default (handler: (type: AbleActionEventType) => void) => ({
7
7
  name: 'actions',
@@ -21,9 +21,9 @@ import EventEmitter from 'events';
21
21
  import { merge } from 'lodash-es';
22
22
  import type { ElementGuidelineValueOption, MoveableOptions, MoveableRefType } from 'moveable';
23
23
 
24
- import { GuidesType, Mode } from './const';
24
+ import { AbleActionEventType, GuidesType, Mode } from './const';
25
25
  import MoveableActionsAble from './MoveableActionsAble';
26
- import { AbleActionEventType, GetRootContainer, MoveableOptionsManagerConfig } from './types';
26
+ import type { GetRootContainer, MoveableOptionsManagerConfig } from './types';
27
27
  import { getOffset } from './util';
28
28
 
29
29
  /**
package/src/Rule.ts CHANGED
@@ -1,8 +1,9 @@
1
1
  import EventEmitter from 'events';
2
2
 
3
- import Guides, { GuidesEvents } from '@scena/guides';
3
+ import Guides, { type GuidesEvents, type GuidesOptions } from '@scena/guides';
4
4
 
5
5
  import { GuidesType } from './const';
6
+ import type { RuleOptions } from './types';
6
7
 
7
8
  export default class Rule extends EventEmitter {
8
9
  public hGuides: Guides;
@@ -13,10 +14,13 @@ export default class Rule extends EventEmitter {
13
14
  private container: HTMLDivElement;
14
15
  private containerResizeObserver: ResizeObserver;
15
16
  private isShowGuides = true;
17
+ private guidesOptions?: Partial<GuidesOptions>;
16
18
 
17
- constructor(container: HTMLDivElement) {
19
+ constructor(container: HTMLDivElement, options?: RuleOptions) {
18
20
  super();
19
21
 
22
+ this.guidesOptions = options?.guidesOptions || {};
23
+
20
24
  this.container = container;
21
25
  this.hGuides = this.createGuides(GuidesType.HORIZONTAL, this.horizontalGuidelines);
22
26
  this.vGuides = this.createGuides(GuidesType.VERTICAL, this.verticalGuidelines);
@@ -136,6 +140,7 @@ export default class Rule extends EventEmitter {
136
140
  textColor: '#000',
137
141
  style: this.getGuidesStyle(type),
138
142
  showGuides: this.isShowGuides,
143
+ ...this.guidesOptions,
139
144
  });
140
145
 
141
146
  const changEventHandler = {
package/src/StageCore.ts CHANGED
@@ -61,6 +61,7 @@ export default class StageCore extends EventEmitter {
61
61
  this.renderer = new StageRender({
62
62
  runtimeUrl: config.runtimeUrl,
63
63
  zoom: config.zoom,
64
+ renderType: config.renderType,
64
65
  customizedRender: async (): Promise<HTMLElement | null> => {
65
66
  if (this?.customizedRender) {
66
67
  return await this.customizedRender(this);
@@ -68,7 +69,9 @@ export default class StageCore extends EventEmitter {
68
69
  return null;
69
70
  },
70
71
  });
71
- this.mask = new StageMask();
72
+ this.mask = new StageMask({
73
+ guidesOptions: config.guidesOptions,
74
+ });
72
75
  this.actionManager = new ActionManager(this.getActionManagerConfig(config));
73
76
 
74
77
  this.initRenderEvent();
@@ -221,6 +224,14 @@ export default class StageCore extends EventEmitter {
221
224
  return this.actionManager.getDragStatus();
222
225
  }
223
226
 
227
+ public disableMultiSelect() {
228
+ this.actionManager.disableMultiSelect();
229
+ }
230
+
231
+ public enableMultiSelect() {
232
+ this.actionManager.enableMultiSelect();
233
+ }
234
+
224
235
  /**
225
236
  * 销毁实例
226
237
  */
@@ -259,6 +270,7 @@ export default class StageCore extends EventEmitter {
259
270
  moveableOptions: config.moveableOptions,
260
271
  container: this.mask.content,
261
272
  disabledDragStart: config.disabledDragStart,
273
+ disabledMultiSelect: config.disabledMultiSelect,
262
274
  canSelect: config.canSelect,
263
275
  isContainer: config.isContainer,
264
276
  updateDragEl: config.updateDragEl,
@@ -278,6 +290,8 @@ export default class StageCore extends EventEmitter {
278
290
  this.renderer.on('page-el-update', (el: HTMLElement) => {
279
291
  this.mask?.observe(el);
280
292
  this.observePageResize(el);
293
+
294
+ this.emit('page-el-update', el);
281
295
  });
282
296
  }
283
297
 
@@ -307,14 +321,14 @@ export default class StageCore extends EventEmitter {
307
321
  .on('before-select', (idOrEl: Id | HTMLElement, event?: MouseEvent) => {
308
322
  this.select(idOrEl, event);
309
323
  })
310
- .on('select', (selectedEl: HTMLElement) => {
311
- this.emit('select', selectedEl);
324
+ .on('select', (selectedEl: HTMLElement, event: MouseEvent) => {
325
+ this.emit('select', selectedEl, event);
312
326
  })
313
327
  .on('before-multi-select', (idOrElList: HTMLElement[] | Id[]) => {
314
328
  this.multiSelect(idOrElList);
315
329
  })
316
- .on('multi-select', (selectedElList: HTMLElement[]) => {
317
- this.emit('multi-select', selectedElList);
330
+ .on('multi-select', (selectedElList: HTMLElement[], event: MouseEvent) => {
331
+ this.emit('multi-select', selectedElList, event);
318
332
  });
319
333
  }
320
334
 
package/src/StageMask.ts CHANGED
@@ -20,6 +20,7 @@ import { createDiv, getDocument, injectStyle } from '@tmagic/utils';
20
20
 
21
21
  import { Mode, ZIndex } from './const';
22
22
  import Rule from './Rule';
23
+ import type { RuleOptions } from './types';
23
24
  import { getScrollParent, isFixedParent } from './util';
24
25
 
25
26
  const wrapperClassName = 'editor-mask-wrapper';
@@ -80,9 +81,9 @@ export default class StageMask extends Rule {
80
81
  private intersectionObserver: IntersectionObserver | null = null;
81
82
  private wrapperResizeObserver: ResizeObserver | null = null;
82
83
 
83
- constructor() {
84
+ constructor(options?: RuleOptions) {
84
85
  const wrapper = createWrapper();
85
- super(wrapper);
86
+ super(wrapper, options);
86
87
 
87
88
  this.wrapper = wrapper;
88
89