@pdfme/ui 5.3.11-dev.7 → 5.3.11-dev.9
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/dist/index.es.js +5671 -5590
- package/dist/index.umd.js +121 -121
- package/dist/types/src/components/Designer/Canvas/Guides.d.ts +3 -9
- package/dist/types/src/components/Designer/Canvas/Moveable.d.ts +2 -49
- package/dist/types/src/components/Designer/Canvas/Selecto.d.ts +5 -16
- package/dist/types/src/components/Designer/PluginIcon.d.ts +2 -2
- package/dist/types/src/components/Designer/RightSidebar/ListView/Item.d.ts +17 -0
- package/dist/types/src/constants.d.ts +1 -1
- package/dist/types/src/contexts.d.ts +1 -1
- package/dist/types/src/helper.d.ts +3 -3
- package/package.json +1 -1
- package/src/components/AppContextProvider.tsx +17 -10
- package/src/components/CtlBar.tsx +2 -2
- package/src/components/Designer/Canvas/Guides.tsx +4 -13
- package/src/components/Designer/Canvas/Moveable.tsx +15 -74
- package/src/components/Designer/Canvas/Selecto.tsx +9 -24
- package/src/components/Designer/Canvas/index.tsx +3 -56
- package/src/components/Designer/LeftSidebar.tsx +2 -2
- package/src/components/Designer/PluginIcon.tsx +14 -3
- package/src/components/Designer/RightSidebar/DetailView/AlignWidget.tsx +91 -16
- package/src/components/Designer/RightSidebar/DetailView/ButtonGroupWidget.tsx +12 -8
- package/src/components/Designer/RightSidebar/DetailView/index.tsx +64 -21
- package/src/components/Designer/RightSidebar/ListView/Item.tsx +30 -2
- package/src/components/Designer/RightSidebar/ListView/SelectableSortableContainer.tsx +23 -4
- package/src/components/Designer/RightSidebar/ListView/SelectableSortableItem.tsx +20 -4
- package/src/components/Designer/index.tsx +14 -9
- package/src/components/Preview.tsx +4 -4
- package/src/components/Renderer.tsx +41 -35
- package/src/components/Root.tsx +1 -1
- package/src/constants.ts +1 -1
- package/src/contexts.ts +1 -1
- package/src/helper.ts +131 -38
- package/src/types/react-guides.d.ts +0 -22
- package/src/types/react-selecto.d.ts +0 -35
@@ -1,6 +1,5 @@
|
|
1
1
|
import React, { useEffect, useContext, ReactNode, useRef, useMemo } from 'react';
|
2
2
|
import {
|
3
|
-
Dict,
|
4
3
|
Mode,
|
5
4
|
ZOOM,
|
6
5
|
UIRenderProps,
|
@@ -29,7 +28,7 @@ type RendererProps = Omit<
|
|
29
28
|
};
|
30
29
|
|
31
30
|
type ReRenderCheckProps = {
|
32
|
-
plugin
|
31
|
+
plugin?: Plugin<Schema>;
|
33
32
|
value: string;
|
34
33
|
mode: Mode;
|
35
34
|
scale: number;
|
@@ -48,12 +47,12 @@ const useRerenderDependencies = (arg: ReRenderCheckProps) => {
|
|
48
47
|
const optionStr = JSON.stringify(_options);
|
49
48
|
|
50
49
|
return useMemo(() => {
|
51
|
-
if (plugin
|
50
|
+
if (plugin?.uninterruptedEditMode && mode === 'designer') {
|
52
51
|
return [mode];
|
53
52
|
} else {
|
54
53
|
return [value, mode, scale, JSON.stringify(schema), optionStr];
|
55
54
|
}
|
56
|
-
}, [plugin
|
55
|
+
}, [plugin?.uninterruptedEditMode, value, mode, scale, schema, optionStr, plugin]);
|
57
56
|
};
|
58
57
|
|
59
58
|
const Wrapper = ({
|
@@ -105,56 +104,63 @@ const Renderer = (props: RendererProps) => {
|
|
105
104
|
|
106
105
|
const pluginsRegistry = useContext(PluginsRegistry);
|
107
106
|
const options = useContext(OptionsContext);
|
108
|
-
const i18n = useContext(I18nContext) as (key:
|
107
|
+
const i18n = useContext(I18nContext) as (key: string) => string;
|
109
108
|
const { token: theme } = antdTheme.useToken();
|
110
109
|
|
111
110
|
const ref = useRef<HTMLDivElement>(null);
|
112
111
|
const _cache = useContext(CacheContext);
|
113
|
-
|
114
|
-
|
115
|
-
|
112
|
+
// Safely extract schema type
|
113
|
+
const schemaType = typeof schema.type === 'string' ? schema.type : '';
|
114
|
+
|
115
|
+
// Find plugin with matching schema type using a type-safe approach
|
116
|
+
const plugin = Object.values(pluginsRegistry || {}).find((plugin) => {
|
117
|
+
const defaultSchema = plugin?.propPanel?.defaultSchema as Record<string, unknown> | undefined;
|
118
|
+
return defaultSchema?.type === schemaType;
|
119
|
+
});
|
116
120
|
|
117
|
-
if (!plugin || !plugin.ui) {
|
118
|
-
console.error(`[@pdfme/ui] Renderer for type ${schema.type} not found.
|
119
|
-
Check this document: https://pdfme.com/docs/custom-schemas`);
|
120
|
-
return <></>;
|
121
|
-
}
|
122
121
|
const reRenderDependencies = useRerenderDependencies({
|
123
|
-
plugin,
|
122
|
+
plugin: plugin || ({} as Plugin<Schema>),
|
124
123
|
value,
|
125
124
|
mode,
|
126
125
|
scale,
|
127
126
|
schema,
|
128
|
-
options
|
127
|
+
options,
|
129
128
|
});
|
130
129
|
|
131
130
|
useEffect(() => {
|
132
|
-
if (ref.current
|
133
|
-
|
134
|
-
|
131
|
+
if (!plugin?.ui || !ref.current || !schema.type) return;
|
132
|
+
|
133
|
+
ref.current.innerHTML = '';
|
134
|
+
const render = plugin.ui;
|
135
|
+
|
136
|
+
void render({
|
137
|
+
value,
|
138
|
+
schema,
|
139
|
+
basePdf,
|
140
|
+
rootElement: ref.current,
|
141
|
+
mode,
|
142
|
+
onChange,
|
143
|
+
stopEditing,
|
144
|
+
tabIndex,
|
145
|
+
placeholder,
|
146
|
+
options,
|
147
|
+
theme,
|
148
|
+
i18n,
|
149
|
+
_cache,
|
150
|
+
});
|
135
151
|
|
136
|
-
void render({
|
137
|
-
value,
|
138
|
-
schema,
|
139
|
-
basePdf,
|
140
|
-
rootElement: ref.current,
|
141
|
-
mode,
|
142
|
-
onChange,
|
143
|
-
stopEditing,
|
144
|
-
tabIndex,
|
145
|
-
placeholder,
|
146
|
-
options: options as UIOptions,
|
147
|
-
theme,
|
148
|
-
i18n,
|
149
|
-
_cache: _cache as Map<any, any>,
|
150
|
-
});
|
151
|
-
}
|
152
152
|
return () => {
|
153
153
|
if (ref.current) {
|
154
154
|
ref.current.innerHTML = '';
|
155
155
|
}
|
156
156
|
};
|
157
|
-
}, reRenderDependencies);
|
157
|
+
}, [plugin?.ui, schema.type, reRenderDependencies]);
|
158
|
+
|
159
|
+
if (!plugin || !plugin.ui) {
|
160
|
+
console.error(`[@pdfme/ui] Renderer for type ${schema.type} not found.
|
161
|
+
Check this document: https://pdfme.com/docs/custom-schemas`);
|
162
|
+
return <></>;
|
163
|
+
}
|
158
164
|
|
159
165
|
return (
|
160
166
|
<Wrapper {...props}>
|
package/src/components/Root.tsx
CHANGED
@@ -19,7 +19,7 @@ const Root = ({ size, scale, children }: Props, ref: Ref<HTMLDivElement>) => {
|
|
19
19
|
);
|
20
20
|
const newFontFaces = fontFaces.filter((fontFace) => !document.fonts.has(fontFace));
|
21
21
|
|
22
|
-
Promise.allSettled(newFontFaces.map((f) => f.load())).then((loadedFontFaces) => {
|
22
|
+
void Promise.allSettled(newFontFaces.map((f) => f.load())).then((loadedFontFaces) => {
|
23
23
|
loadedFontFaces.forEach((loadedFontFace) => {
|
24
24
|
if (loadedFontFace.status === 'fulfilled') {
|
25
25
|
document.fonts.add(loadedFontFace.value);
|
package/src/constants.ts
CHANGED
package/src/contexts.ts
CHANGED
@@ -11,4 +11,4 @@ export const PluginsRegistry = createContext<Plugins>(builtInPlugins);
|
|
11
11
|
|
12
12
|
export const OptionsContext = createContext<UIOptions>({});
|
13
13
|
|
14
|
-
export const CacheContext = createContext<Map<
|
14
|
+
export const CacheContext = createContext<Map<unknown, unknown>>(new Map());
|
package/src/helper.ts
CHANGED
@@ -16,20 +16,28 @@ import { pdf2size } from '@pdfme/converter';
|
|
16
16
|
import { DEFAULT_MAX_ZOOM, RULER_HEIGHT } from './constants.js';
|
17
17
|
import { OptionsContext } from './contexts.js';
|
18
18
|
|
19
|
+
// Define a type for the hotkeys function with additional properties
|
20
|
+
type HotkeysFunction = {
|
21
|
+
(keys: string, callback: (e: KeyboardEvent, handler: { shortcut: string }) => void): unknown;
|
22
|
+
shift: boolean;
|
23
|
+
unbind: (keys: string) => void;
|
24
|
+
};
|
25
|
+
|
19
26
|
// Create a simple mock for hotkeys to avoid TypeScript errors
|
20
27
|
const hotkeys = function (
|
21
28
|
keys: string,
|
22
29
|
callback: (e: KeyboardEvent, handler: { shortcut: string }) => void,
|
23
30
|
) {
|
24
|
-
return
|
25
|
-
};
|
31
|
+
return hotkeysJs(keys, callback);
|
32
|
+
} as HotkeysFunction;
|
26
33
|
|
27
34
|
// Add properties to the hotkeys function
|
28
|
-
|
29
|
-
|
35
|
+
hotkeys.shift = false;
|
36
|
+
hotkeys.unbind = function (keys: string) {
|
30
37
|
// Do nothing if hotkeysJs doesn't have unbind
|
31
|
-
|
32
|
-
|
38
|
+
const hotkeysFn = hotkeysJs as unknown as { unbind?: (keys: string) => void };
|
39
|
+
if (typeof hotkeysFn.unbind === 'function') {
|
40
|
+
hotkeysFn.unbind(keys);
|
33
41
|
}
|
34
42
|
};
|
35
43
|
|
@@ -40,29 +48,30 @@ export const uuid = () =>
|
|
40
48
|
return v.toString(16);
|
41
49
|
});
|
42
50
|
|
43
|
-
|
51
|
+
|
52
|
+
const set = <T extends object>(obj: T, path: string | string[], value: unknown) => {
|
44
53
|
path = Array.isArray(path) ? path : path.replace('[', '.').replace(']', '').split('.');
|
45
|
-
let src:
|
54
|
+
let src: Record<string, unknown> = obj as Record<string, unknown>;
|
46
55
|
path.forEach((key, index, array) => {
|
47
56
|
if (index == path.length - 1) {
|
48
57
|
src[key] = value;
|
49
58
|
} else {
|
50
|
-
if (!
|
59
|
+
if (!Object.prototype.hasOwnProperty.call(src, key)) {
|
51
60
|
const next = array[index + 1];
|
52
61
|
src[key] = String(Number(next)) === next ? [] : {};
|
53
62
|
}
|
54
|
-
src = src[key]
|
63
|
+
src = src[key] as Record<string, unknown>;
|
55
64
|
}
|
56
65
|
});
|
57
66
|
};
|
58
67
|
|
59
|
-
export const debounce = <T extends
|
68
|
+
export const debounce = <T extends (...args: unknown[]) => unknown>(cb: T, wait = 20) => {
|
60
69
|
let h: null | ReturnType<typeof setTimeout> = null;
|
61
|
-
const callable = (...args:
|
70
|
+
const callable = (...args: Parameters<T>) => {
|
62
71
|
if (h) clearTimeout(h);
|
63
72
|
h = setTimeout(() => cb(...args), wait);
|
64
73
|
};
|
65
|
-
return
|
74
|
+
return callable as T;
|
66
75
|
};
|
67
76
|
|
68
77
|
const shift = (number: number, precision: number, reverseShift: boolean) => {
|
@@ -147,22 +156,22 @@ export const initShortCuts = (arg: {
|
|
147
156
|
case up:
|
148
157
|
case shiftUp:
|
149
158
|
e.preventDefault();
|
150
|
-
arg.move('up',
|
159
|
+
arg.move('up', hotkeys.shift);
|
151
160
|
break;
|
152
161
|
case down:
|
153
162
|
case shiftDown:
|
154
163
|
e.preventDefault();
|
155
|
-
arg.move('down',
|
164
|
+
arg.move('down', hotkeys.shift);
|
156
165
|
break;
|
157
166
|
case left:
|
158
167
|
case shiftLeft:
|
159
168
|
e.preventDefault();
|
160
|
-
arg.move('left',
|
169
|
+
arg.move('left', hotkeys.shift);
|
161
170
|
break;
|
162
171
|
case right:
|
163
172
|
case shiftRight:
|
164
173
|
e.preventDefault();
|
165
|
-
arg.move('right',
|
174
|
+
arg.move('right', hotkeys.shift);
|
166
175
|
break;
|
167
176
|
case rmWin:
|
168
177
|
case rmMac:
|
@@ -204,7 +213,7 @@ export const initShortCuts = (arg: {
|
|
204
213
|
};
|
205
214
|
|
206
215
|
export const destroyShortCuts = () => {
|
207
|
-
|
216
|
+
hotkeys.unbind(keys.join());
|
208
217
|
};
|
209
218
|
|
210
219
|
/**
|
@@ -259,10 +268,10 @@ export const arrayBufferToBase64 = (arrayBuffer: ArrayBuffer): string => {
|
|
259
268
|
};
|
260
269
|
|
261
270
|
const convertSchemasForUI = (template: Template): SchemaForUI[][] => {
|
262
|
-
template.schemas.forEach((page
|
263
|
-
page.forEach((schema
|
264
|
-
schema.id = uuid();
|
265
|
-
schema.content = schema.content || '';
|
271
|
+
template.schemas.forEach((page) => {
|
272
|
+
page.forEach((schema) => {
|
273
|
+
(schema as SchemaForUI).id = uuid();
|
274
|
+
(schema as SchemaForUI).content = schema.content || '';
|
266
275
|
});
|
267
276
|
});
|
268
277
|
|
@@ -282,8 +291,8 @@ export const template2SchemasList = async (_template: Template) => {
|
|
282
291
|
}));
|
283
292
|
} else {
|
284
293
|
const b64BasePdf = await getB64BasePdf(basePdf);
|
285
|
-
//
|
286
|
-
const pdfArrayBuffer = b64toUint8Array(b64BasePdf)
|
294
|
+
// pdf2size accepts both ArrayBuffer and Uint8Array
|
295
|
+
const pdfArrayBuffer = b64toUint8Array(b64BasePdf);
|
287
296
|
|
288
297
|
pageSizes = await pdf2size(pdfArrayBuffer);
|
289
298
|
}
|
@@ -317,7 +326,7 @@ export const template2SchemasList = async (_template: Template) => {
|
|
317
326
|
export const schemasList2template = (schemasList: SchemaForUI[][], basePdf: BasePdf): Template => ({
|
318
327
|
schemas: cloneDeep(schemasList).map((page) =>
|
319
328
|
page.map((schema) => {
|
320
|
-
// @ts-
|
329
|
+
// @ts-expect-error Property 'id' is used only in UI
|
321
330
|
delete schema.id;
|
322
331
|
return schema;
|
323
332
|
}),
|
@@ -420,14 +429,14 @@ export const getSidebarContentHeight = (sidebarHeight: number) =>
|
|
420
429
|
const handlePositionSizeChange = (
|
421
430
|
schema: SchemaForUI,
|
422
431
|
key: string,
|
423
|
-
value:
|
432
|
+
value: unknown,
|
424
433
|
basePdf: BasePdf,
|
425
434
|
pageSize: Size,
|
426
435
|
) => {
|
427
436
|
const padding = isBlankPdf(basePdf) ? basePdf.padding : [0, 0, 0, 0];
|
428
437
|
const [pt, pr, pb, pl] = padding;
|
429
438
|
const { width: pw, height: ph } = pageSize;
|
430
|
-
const calcBounds = (v:
|
439
|
+
const calcBounds = (v: unknown, min: number, max: number) => Math.min(Math.max(Number(v), min), max);
|
431
440
|
if (key === 'position.x') {
|
432
441
|
schema.position.x = calcBounds(value, pl, pw - schema.width - pr);
|
433
442
|
} else if (key === 'position.y') {
|
@@ -442,7 +451,7 @@ const handlePositionSizeChange = (
|
|
442
451
|
const handleTypeChange = (
|
443
452
|
schema: SchemaForUI,
|
444
453
|
key: string,
|
445
|
-
value:
|
454
|
+
value: unknown,
|
446
455
|
pluginsRegistry: Plugins,
|
447
456
|
) => {
|
448
457
|
if (key !== 'type') return;
|
@@ -453,21 +462,105 @@ const handleTypeChange = (
|
|
453
462
|
}
|
454
463
|
});
|
455
464
|
// Apply attributes from new defaultSchema
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
465
|
+
// Find the plugin with matching type
|
466
|
+
const pluginValue = value as string;
|
467
|
+
|
468
|
+
// Define a type-safe approach to find the matching plugin
|
469
|
+
interface PluginSchema {
|
470
|
+
type: string;
|
471
|
+
[key: string]: unknown;
|
472
|
+
}
|
473
|
+
|
474
|
+
interface PluginType {
|
475
|
+
propPanel: {
|
476
|
+
defaultSchema: PluginSchema;
|
477
|
+
};
|
478
|
+
}
|
479
|
+
|
480
|
+
// Initialize plugin as undefined
|
481
|
+
let plugin: PluginType | undefined;
|
482
|
+
|
483
|
+
// Safely iterate through plugins to find one with matching type
|
484
|
+
const pluginEntries = Object.entries(pluginsRegistry);
|
485
|
+
for (let i = 0; i < pluginEntries.length; i++) {
|
486
|
+
const [, pluginObj] = pluginEntries[i];
|
487
|
+
|
488
|
+
// Skip invalid plugins
|
489
|
+
if (!pluginObj || typeof pluginObj !== 'object') continue;
|
490
|
+
|
491
|
+
// Check if propPanel exists and is an object
|
492
|
+
if (!('propPanel' in pluginObj) ||
|
493
|
+
!pluginObj.propPanel ||
|
494
|
+
typeof pluginObj.propPanel !== 'object') continue;
|
495
|
+
|
496
|
+
// Check if defaultSchema exists and is an object
|
497
|
+
const propPanel = pluginObj.propPanel as { defaultSchema?: unknown };
|
498
|
+
if (!('defaultSchema' in propPanel) ||
|
499
|
+
!propPanel.defaultSchema ||
|
500
|
+
typeof propPanel.defaultSchema !== 'object') continue;
|
501
|
+
|
502
|
+
// Safely check if type property exists and matches
|
503
|
+
const defaultSchema = propPanel.defaultSchema as Record<string, unknown>;
|
504
|
+
if (!('type' in defaultSchema) ||
|
505
|
+
typeof defaultSchema.type !== 'string') continue;
|
506
|
+
|
507
|
+
// Check if the type matches
|
508
|
+
const schemaType = defaultSchema.type;
|
509
|
+
if (schemaType === pluginValue) {
|
510
|
+
// Create a type-safe copy of the plugin
|
511
|
+
const safeSchema: PluginSchema = {
|
512
|
+
type: schemaType
|
513
|
+
};
|
514
|
+
|
515
|
+
// Copy other properties safely
|
516
|
+
Object.keys(defaultSchema).forEach(key => {
|
517
|
+
if (key !== 'type' && Object.prototype.hasOwnProperty.call(defaultSchema, key)) {
|
518
|
+
safeSchema[key] = defaultSchema[key];
|
519
|
+
}
|
520
|
+
});
|
521
|
+
|
522
|
+
// Found matching plugin with proper typing
|
523
|
+
plugin = {
|
524
|
+
propPanel: {
|
525
|
+
defaultSchema: safeSchema
|
526
|
+
}
|
527
|
+
};
|
528
|
+
break;
|
462
529
|
}
|
463
|
-
}
|
530
|
+
}
|
531
|
+
|
532
|
+
const propPanel = plugin?.propPanel;
|
533
|
+
|
534
|
+
// Apply default schema properties if available
|
535
|
+
if (propPanel?.defaultSchema) {
|
536
|
+
// Create a type-safe copy of the default schema
|
537
|
+
const defaultSchema = propPanel.defaultSchema;
|
538
|
+
const schemaRecord = schema as Record<string, unknown>;
|
539
|
+
|
540
|
+
// Use a type-safe approach to copy properties
|
541
|
+
for (const key of Object.keys(defaultSchema)) {
|
542
|
+
// Only add properties that don't already exist in the schema
|
543
|
+
if (!Object.prototype.hasOwnProperty.call(schema, key)) {
|
544
|
+
// Create a safe copy of the property
|
545
|
+
if (Object.prototype.hasOwnProperty.call(defaultSchema, key)) {
|
546
|
+
// Get the property value safely
|
547
|
+
const propertyValue = defaultSchema[key];
|
548
|
+
|
549
|
+
// Only assign if the value is defined
|
550
|
+
if (propertyValue !== undefined) {
|
551
|
+
schemaRecord[key] = propertyValue;
|
552
|
+
}
|
553
|
+
}
|
554
|
+
}
|
555
|
+
}
|
556
|
+
}
|
464
557
|
if (schema.readOnly) {
|
465
558
|
schema.required = false;
|
466
559
|
}
|
467
560
|
};
|
468
561
|
|
469
562
|
export const changeSchemas = (args: {
|
470
|
-
objs: { key: string; value:
|
563
|
+
objs: { key: string; value: unknown; schemaId: string }[];
|
471
564
|
schemas: SchemaForUI[];
|
472
565
|
basePdf: BasePdf;
|
473
566
|
pluginsRegistry: Plugins;
|
@@ -492,8 +585,8 @@ export const changeSchemas = (args: {
|
|
492
585
|
commitSchemas(newSchemas);
|
493
586
|
};
|
494
587
|
|
495
|
-
export const
|
588
|
+
export const useMaxZoom = () => {
|
496
589
|
const options = useContext(OptionsContext);
|
497
590
|
|
498
|
-
return options.maxZoom ?
|
591
|
+
return options.maxZoom ? options.maxZoom / 100 : DEFAULT_MAX_ZOOM;
|
499
592
|
};
|
@@ -1,22 +0,0 @@
|
|
1
|
-
declare module '@scena/react-guides' {
|
2
|
-
import { Component, ForwardRefExoticComponent, RefAttributes } from 'react';
|
3
|
-
|
4
|
-
interface GuidesInterface {
|
5
|
-
getGuides(): number[];
|
6
|
-
scroll(pos: number): void;
|
7
|
-
scrollGuides(pos: number): void;
|
8
|
-
loadGuides(guides: number[]): void;
|
9
|
-
resize(): void;
|
10
|
-
}
|
11
|
-
|
12
|
-
interface GuidesProps {
|
13
|
-
zoom?: number;
|
14
|
-
style?: React.CSSProperties;
|
15
|
-
type?: 'horizontal' | 'vertical';
|
16
|
-
}
|
17
|
-
|
18
|
-
// Define the component as a ForwardRefExoticComponent to support refs
|
19
|
-
const GuidesComponent: ForwardRefExoticComponent<GuidesProps & RefAttributes<GuidesInterface>>;
|
20
|
-
|
21
|
-
export default GuidesComponent;
|
22
|
-
}
|
@@ -1,35 +0,0 @@
|
|
1
|
-
declare module 'react-selecto' {
|
2
|
-
import { ForwardRefExoticComponent, RefAttributes } from 'react';
|
3
|
-
|
4
|
-
interface OnDragStart {
|
5
|
-
inputEvent: MouseEvent;
|
6
|
-
stop: () => void;
|
7
|
-
isTrusted: boolean;
|
8
|
-
}
|
9
|
-
|
10
|
-
interface OnSelect {
|
11
|
-
selected: Element[];
|
12
|
-
added: Element[];
|
13
|
-
removed: Element[];
|
14
|
-
inputEvent: MouseEvent;
|
15
|
-
rect: DOMRect;
|
16
|
-
}
|
17
|
-
|
18
|
-
interface SelectoProps {
|
19
|
-
className?: string;
|
20
|
-
selectFromInside?: boolean;
|
21
|
-
selectByClick?: boolean;
|
22
|
-
preventDefault?: boolean;
|
23
|
-
hitRate?: number;
|
24
|
-
selectableTargets?: string[];
|
25
|
-
container?: HTMLElement | null;
|
26
|
-
continueSelect?: boolean;
|
27
|
-
onDragStart?: (e: OnDragStart) => void;
|
28
|
-
onSelect?: (e: OnSelect) => void;
|
29
|
-
}
|
30
|
-
|
31
|
-
// Define the component as a ForwardRefExoticComponent
|
32
|
-
const SelectoComponent: ForwardRefExoticComponent<SelectoProps & RefAttributes<any>>;
|
33
|
-
|
34
|
-
export default SelectoComponent;
|
35
|
-
}
|