@douyinfe/semi-foundation 2.70.1 → 2.71.0-alpha.3
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/cascader/constants.ts +2 -0
- package/cascader/foundation.ts +49 -2
- package/dragMove/foundation.ts +194 -0
- package/highlight/foundation.ts +211 -0
- package/jsonViewer/constants.ts +7 -0
- package/jsonViewer/foundation.ts +72 -0
- package/jsonViewer/jsonViewer.scss +200 -0
- package/jsonViewer/script/build.js +51 -0
- package/jsonViewer/variables.scss +15 -0
- package/lib/cjs/cascader/constants.d.ts +2 -0
- package/lib/cjs/cascader/constants.js +3 -1
- package/lib/cjs/cascader/foundation.d.ts +3 -0
- package/lib/cjs/cascader/foundation.js +55 -3
- package/lib/cjs/dragMove/foundation.d.ts +45 -0
- package/lib/cjs/dragMove/foundation.js +162 -0
- package/lib/cjs/highlight/foundation.d.ts +84 -0
- package/lib/cjs/highlight/foundation.js +184 -0
- package/lib/cjs/jsonViewer/constants.d.ts +4 -0
- package/lib/cjs/jsonViewer/constants.js +10 -0
- package/lib/cjs/jsonViewer/foundation.d.ts +24 -0
- package/lib/cjs/jsonViewer/foundation.js +69 -0
- package/lib/cjs/jsonViewer/jsonViewer.css +168 -0
- package/lib/cjs/jsonViewer/jsonViewer.scss +200 -0
- package/lib/cjs/jsonViewer/variables.scss +15 -0
- package/lib/cjs/lottie/foundation.d.ts +1 -1
- package/lib/cjs/resizable/foundation.d.ts +6 -2
- package/lib/cjs/tree/tree.css +1 -0
- package/lib/cjs/tree/tree.scss +2 -0
- package/lib/es/cascader/constants.d.ts +2 -0
- package/lib/es/cascader/constants.js +3 -1
- package/lib/es/cascader/foundation.d.ts +3 -0
- package/lib/es/cascader/foundation.js +55 -3
- package/lib/es/dragMove/foundation.d.ts +45 -0
- package/lib/es/dragMove/foundation.js +153 -0
- package/lib/es/highlight/foundation.d.ts +84 -0
- package/lib/es/highlight/foundation.js +174 -0
- package/lib/es/jsonViewer/constants.d.ts +4 -0
- package/lib/es/jsonViewer/constants.js +5 -0
- package/lib/es/jsonViewer/foundation.d.ts +24 -0
- package/lib/es/jsonViewer/foundation.js +62 -0
- package/lib/es/jsonViewer/jsonViewer.css +168 -0
- package/lib/es/jsonViewer/jsonViewer.scss +200 -0
- package/lib/es/jsonViewer/variables.scss +15 -0
- package/lib/es/lottie/foundation.d.ts +1 -1
- package/lib/es/resizable/foundation.d.ts +6 -2
- package/lib/es/resizable/foundation.js +3 -2
- package/lib/es/tree/tree.css +1 -0
- package/lib/es/tree/tree.scss +2 -0
- package/lottie/foundation.ts +2 -2
- package/package.json +5 -3
- package/resizable/foundation.ts +19 -5
- package/tree/tree.scss +2 -0
- package/tsconfig.json +1 -1
- package/lib/cjs/utils/getHighlight.d.ts +0 -45
- package/lib/cjs/utils/getHighlight.js +0 -175
- package/lib/es/utils/getHighlight.d.ts +0 -45
- package/lib/es/utils/getHighlight.js +0 -166
- package/utils/getHighlight.ts +0 -178
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
@import './variables.scss';
|
|
2
|
+
|
|
3
|
+
$module: #{$prefix}-json-viewer;
|
|
4
|
+
|
|
5
|
+
.#{$module} {
|
|
6
|
+
&-background {
|
|
7
|
+
background-color: $color-json-viewer-background;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
&-string-key {
|
|
11
|
+
color: $color-json-viewer-key;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
&-string-value {
|
|
15
|
+
color: $color-json-viewer-value;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
&-keyword {
|
|
19
|
+
color: $color-json-viewer-keyword;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
&-number {
|
|
23
|
+
color: $color-json-viewer-number;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
&-delimiter-comma {
|
|
27
|
+
color: $color-json-viewer-delimiter-comma;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
&-delimiter-bracket-0 {
|
|
31
|
+
color: rgba(var(--semi-blue-7), 1);
|
|
32
|
+
}
|
|
33
|
+
&-delimiter-bracket-1 {
|
|
34
|
+
color: rgba(var(--semi-green-7), 1);
|
|
35
|
+
}
|
|
36
|
+
&-delimiter-bracket-2 {
|
|
37
|
+
color: rgba(var(--semi-orange-7), 1);
|
|
38
|
+
}
|
|
39
|
+
&-delimiter-array-0 {
|
|
40
|
+
color: rgba(var(--semi-blue-7), 1);
|
|
41
|
+
}
|
|
42
|
+
&-delimiter-array-1 {
|
|
43
|
+
color: rgba(var(--semi-green-7), 1);
|
|
44
|
+
}
|
|
45
|
+
&-delimiter-array-2 {
|
|
46
|
+
color: rgba(var(--semi-orange-7), 1);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
&-search-result {
|
|
50
|
+
background-color: $color-json-viewer-search-result-background;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
&-current-search-result {
|
|
54
|
+
background-color: $color-json-viewer-current-search-result-background !important;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
&-folding-icon {
|
|
58
|
+
opacity: 0.7;
|
|
59
|
+
transition: opacity 0.8s;
|
|
60
|
+
color: $color-json-viewer-folding-icon;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
&-view-line {
|
|
64
|
+
font-family: Menlo, Firecode, Monaco, 'Courier New', monospace;
|
|
65
|
+
font-weight: normal;
|
|
66
|
+
font-size: 12px;
|
|
67
|
+
font-feature-settings: 'liga' 0, 'calt' 0;
|
|
68
|
+
font-variation-settings: normal;
|
|
69
|
+
letter-spacing: 0px;
|
|
70
|
+
color: #237893;
|
|
71
|
+
word-wrap: break-word;
|
|
72
|
+
white-space: pre-wrap;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
&-line-number {
|
|
76
|
+
font-family: Menlo, Firecode, Monaco, 'Courier New', monospace;
|
|
77
|
+
font-weight: normal;
|
|
78
|
+
font-size: 12px;
|
|
79
|
+
font-feature-settings: 'liga' 0, 'calt' 0;
|
|
80
|
+
font-variation-settings: normal;
|
|
81
|
+
letter-spacing: 0px;
|
|
82
|
+
color: $color-json-viewer-line-number;
|
|
83
|
+
text-align: center;
|
|
84
|
+
width: 50px;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
&-content-container {
|
|
88
|
+
scrollbar-width: none; /* 隐藏滚动条(Firefox) */
|
|
89
|
+
-ms-overflow-style: none; /* 隐藏滚动条(IE 和 Edge) */
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
&-content-container::-webkit-scrollbar {
|
|
93
|
+
display: none; /* 隐藏滚动条(Webkit 浏览器) */
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
&-search-bar-container {
|
|
97
|
+
width: 458px;
|
|
98
|
+
box-sizing: border-box;
|
|
99
|
+
border: 1px solid var(--semi-color-border);
|
|
100
|
+
border-radius: var(--semi-border-radius-small);
|
|
101
|
+
display: flex;
|
|
102
|
+
flex-direction: column;
|
|
103
|
+
padding: 8px;
|
|
104
|
+
gap: 8px;
|
|
105
|
+
background-color: var(--semi-color-bg-0);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
&-search-bar {
|
|
109
|
+
display: flex;
|
|
110
|
+
align-items: flex-start;
|
|
111
|
+
gap: 8px;
|
|
112
|
+
&-input {
|
|
113
|
+
width: 200px;
|
|
114
|
+
flex-shrink: 0;
|
|
115
|
+
}
|
|
116
|
+
.#{$prefix}-button-group {
|
|
117
|
+
flex-wrap: nowrap;
|
|
118
|
+
}
|
|
119
|
+
// next icon btn
|
|
120
|
+
.#{$prefix}-button:nth-of-type(1) {
|
|
121
|
+
width: 40px;
|
|
122
|
+
}
|
|
123
|
+
// prev icon btn
|
|
124
|
+
.#{$prefix}-button:nth-of-type(2) {
|
|
125
|
+
width: 40px;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
&-replace-bar {
|
|
130
|
+
display: flex;
|
|
131
|
+
align-items: flex-start;
|
|
132
|
+
gap: 8px;
|
|
133
|
+
&-input {
|
|
134
|
+
width: 261px;
|
|
135
|
+
}
|
|
136
|
+
// replace btn
|
|
137
|
+
.#{$prefix}-button:nth-of-type(1) {
|
|
138
|
+
width: 52px;
|
|
139
|
+
}
|
|
140
|
+
// all replace btn
|
|
141
|
+
.#{$prefix}-button:nth-of-type(2) {
|
|
142
|
+
width: 80px;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
&-search-options {
|
|
147
|
+
display: flex;
|
|
148
|
+
align-items: center;
|
|
149
|
+
justify-content: center;
|
|
150
|
+
list-style: none;
|
|
151
|
+
padding-inline-start: 0;
|
|
152
|
+
margin-block-start: 0;
|
|
153
|
+
margin-block-end: 0;
|
|
154
|
+
gap: 8px;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
&-search-options-item {
|
|
158
|
+
min-width: 32px;
|
|
159
|
+
height: 32px;
|
|
160
|
+
display: flex;
|
|
161
|
+
align-items: center;
|
|
162
|
+
justify-content: center;
|
|
163
|
+
cursor: pointer;
|
|
164
|
+
border-radius: var(--semi-border-radius-small);
|
|
165
|
+
color: var(--semi-color-text-2);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
&-search-options-item:hover {
|
|
169
|
+
background-color: var(--semi-color-default);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
&-search-options-item-active {
|
|
173
|
+
color: var(--semi-color-primary);
|
|
174
|
+
background-color: var(--semi-color-primary-light-default);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
&-complete-suggestions-container {
|
|
178
|
+
border-radius: var(--semi-border-radius-medium);
|
|
179
|
+
background-color: var(--semi-color-bg-3);
|
|
180
|
+
box-shadow: var(--semi-shadow-elevated);
|
|
181
|
+
z-index: 1000;
|
|
182
|
+
min-width: 200px;
|
|
183
|
+
max-width: 400px;
|
|
184
|
+
list-style: none;
|
|
185
|
+
padding: 4px 0;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
&-complete-container {
|
|
189
|
+
position: absolute;
|
|
190
|
+
z-index: 1000;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
&-complete-suggestions-item {
|
|
194
|
+
padding: 8px 16px;
|
|
195
|
+
color: var(--semi-color-text-0);
|
|
196
|
+
cursor: pointer;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const esbuild = require('esbuild');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
const compileWorker = async ()=>{
|
|
9
|
+
const workerEntry = path.join(__dirname, "..", "core/src/worker/json.worker.ts");
|
|
10
|
+
|
|
11
|
+
const result = await esbuild.build({
|
|
12
|
+
entryPoints: [workerEntry],
|
|
13
|
+
bundle: true,
|
|
14
|
+
write: false,
|
|
15
|
+
});
|
|
16
|
+
return result.outputFiles[0].text;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
const buildMain = async ()=>{
|
|
21
|
+
const mainEntry = path.join(__dirname, "..", "core/src/index.ts");
|
|
22
|
+
|
|
23
|
+
const result = await esbuild.build({
|
|
24
|
+
entryPoints: [mainEntry],
|
|
25
|
+
bundle: true,
|
|
26
|
+
packages: 'external',
|
|
27
|
+
write: false,
|
|
28
|
+
format: 'esm'
|
|
29
|
+
});
|
|
30
|
+
return result.outputFiles[0].text;
|
|
31
|
+
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
const compile = async ()=>{
|
|
37
|
+
const workerRaw = await compileWorker();
|
|
38
|
+
|
|
39
|
+
const mainRaw = await buildMain();
|
|
40
|
+
|
|
41
|
+
const finalRaw = mainRaw.replaceAll("%WORKER_RAW%", encodeURIComponent(workerRaw));
|
|
42
|
+
|
|
43
|
+
const saveDir = path.join(__dirname, "..", "core/lib");
|
|
44
|
+
|
|
45
|
+
if (!fs.existsSync(saveDir)) {
|
|
46
|
+
fs.mkdirSync(saveDir);
|
|
47
|
+
}
|
|
48
|
+
fs.writeFileSync(path.join(saveDir, "index.js"), finalRaw, 'utf8');
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
compile();
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
$color-json-viewer-background: var(--semi-color-default); // JSON背景颜色
|
|
2
|
+
$color-json-viewer-key: rgba(var(--semi-red-5), 1); // JSON key 颜色
|
|
3
|
+
$color-json-viewer-value: rgba(var(--semi-blue-5), 1);
|
|
4
|
+
$color-json-viewer-number: rgba(var(--semi-green-5), 1); // JSON number 颜色
|
|
5
|
+
$color-json-viewer-keyword: rgba(var(--semi-blue-5), 1); // JSON keyword 颜色
|
|
6
|
+
$color-json-viewer-delimiter-comma: rgba(var(--semi-blue-6), 1); // JSON delimiter comma 颜色
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
$color-json-viewer-search-result-background: rgba(var(--semi-green-2), 1); // JSON search result background 颜色
|
|
10
|
+
$color-json-viewer-current-search-result-background: rgba(var(--semi-yellow-4), 1); // JSON current search result background 颜色
|
|
11
|
+
|
|
12
|
+
$color-json-viewer-folding-icon: rgba(var(--semi-blue-7), 1); // JSON folding icon 颜色
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
$color-json-viewer-line-number: rgba(var(--semi-grey-5), 1); // JSON line number 颜色
|
|
@@ -14,6 +14,8 @@ declare const strings: {
|
|
|
14
14
|
readonly NONE_MERGE_TYPE: "none";
|
|
15
15
|
readonly SEARCH_POSITION_TRIGGER: "trigger";
|
|
16
16
|
readonly SEARCH_POSITION_CUSTOM: "custom";
|
|
17
|
+
readonly RELATED: "related";
|
|
18
|
+
readonly UN_RELATED: "unRelated";
|
|
17
19
|
};
|
|
18
20
|
declare const numbers: {};
|
|
19
21
|
export { cssClasses, strings, numbers };
|
|
@@ -21,7 +21,9 @@ const strings = exports.strings = {
|
|
|
21
21
|
AUTO_MERGE_VALUE_MERGE_TYPE: 'autoMergeValue',
|
|
22
22
|
NONE_MERGE_TYPE: 'none',
|
|
23
23
|
SEARCH_POSITION_TRIGGER: 'trigger',
|
|
24
|
-
SEARCH_POSITION_CUSTOM: 'custom'
|
|
24
|
+
SEARCH_POSITION_CUSTOM: 'custom',
|
|
25
|
+
RELATED: 'related',
|
|
26
|
+
UN_RELATED: 'unRelated'
|
|
25
27
|
};
|
|
26
28
|
const numbers = exports.numbers = {};
|
|
27
29
|
const VALUE_SPLIT = exports.VALUE_SPLIT = '_SEMI_CASCADER_SPLIT_';
|
|
@@ -112,6 +112,7 @@ export interface BasicCascaderProps {
|
|
|
112
112
|
enableLeafClick?: boolean;
|
|
113
113
|
preventScroll?: boolean;
|
|
114
114
|
virtualizeInSearch?: Virtualize;
|
|
115
|
+
checkRelation?: string;
|
|
115
116
|
onClear?: () => void;
|
|
116
117
|
triggerRender?: (props: BasicTriggerRenderProps) => any;
|
|
117
118
|
onListScroll?: (e: any, panel: BasicScrollPanelProps) => void;
|
|
@@ -228,6 +229,8 @@ export default class CascaderFoundation extends BaseFoundation<CascaderAdapter,
|
|
|
228
229
|
notifyIfLoadData(item: BasicEntity | BasicData): void;
|
|
229
230
|
handleSingleSelect(e: any, item: BasicEntity | BasicData): void;
|
|
230
231
|
_handleMultipleSelect(item: BasicEntity | BasicData): void;
|
|
232
|
+
_handleRelatedMultipleSelect(item: BasicEntity | BasicData): void;
|
|
233
|
+
_handleUnRelatedMultipleSelect(item: BasicEntity | BasicData): void;
|
|
231
234
|
calcNonDisabledCheckedKeys(eventKey: string, targetStatus: boolean): {
|
|
232
235
|
checkedKeys: Set<string>;
|
|
233
236
|
halfCheckedKeys: Set<any>;
|
|
@@ -602,6 +602,19 @@ class CascaderFoundation extends _foundation.default {
|
|
|
602
602
|
}
|
|
603
603
|
}
|
|
604
604
|
_handleMultipleSelect(item) {
|
|
605
|
+
const {
|
|
606
|
+
checkRelation
|
|
607
|
+
} = this.getProps();
|
|
608
|
+
if (checkRelation === _constants.strings.RELATED) {
|
|
609
|
+
this._handleRelatedMultipleSelect(item);
|
|
610
|
+
} else if (checkRelation === 'unRelated') {
|
|
611
|
+
this._handleUnRelatedMultipleSelect(item);
|
|
612
|
+
}
|
|
613
|
+
this._adapter.updateStates({
|
|
614
|
+
inputValue: ''
|
|
615
|
+
});
|
|
616
|
+
}
|
|
617
|
+
_handleRelatedMultipleSelect(item) {
|
|
605
618
|
const {
|
|
606
619
|
key
|
|
607
620
|
} = item;
|
|
@@ -666,9 +679,48 @@ class CascaderFoundation extends _foundation.default {
|
|
|
666
679
|
if (curCheckedStatus) {
|
|
667
680
|
this._notifySelect(curRealCheckedKeys);
|
|
668
681
|
}
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
682
|
+
}
|
|
683
|
+
_handleUnRelatedMultipleSelect(item) {
|
|
684
|
+
const {
|
|
685
|
+
key
|
|
686
|
+
} = item;
|
|
687
|
+
const {
|
|
688
|
+
checkedKeys,
|
|
689
|
+
keyEntities
|
|
690
|
+
} = this.getStates();
|
|
691
|
+
const {
|
|
692
|
+
max
|
|
693
|
+
} = this.getProps();
|
|
694
|
+
const newCheckedKeys = new Set(checkedKeys);
|
|
695
|
+
let targetStatus;
|
|
696
|
+
const prevCheckedStatus = checkedKeys.has(key);
|
|
697
|
+
if (prevCheckedStatus) {
|
|
698
|
+
newCheckedKeys.delete(key);
|
|
699
|
+
targetStatus = false;
|
|
700
|
+
} else {
|
|
701
|
+
// 查看是否超出 max
|
|
702
|
+
if ((0, _isNumber2.default)(max)) {
|
|
703
|
+
if (checkedKeys.size >= max) {
|
|
704
|
+
const checkedEntities = [];
|
|
705
|
+
checkedKeys.forEach(itemKey => {
|
|
706
|
+
checkedEntities.push(keyEntities[itemKey]);
|
|
707
|
+
});
|
|
708
|
+
this._adapter.notifyOnExceed(checkedEntities);
|
|
709
|
+
return;
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
newCheckedKeys.add(key);
|
|
713
|
+
targetStatus = true;
|
|
714
|
+
}
|
|
715
|
+
if (!this._isControlledComponent()) {
|
|
716
|
+
this._adapter.updateStates({
|
|
717
|
+
checkedKeys: newCheckedKeys
|
|
718
|
+
});
|
|
719
|
+
}
|
|
720
|
+
this._notifyChange(newCheckedKeys);
|
|
721
|
+
if (targetStatus) {
|
|
722
|
+
this._notifySelect(newCheckedKeys);
|
|
723
|
+
}
|
|
672
724
|
}
|
|
673
725
|
calcNonDisabledCheckedKeys(eventKey, targetStatus) {
|
|
674
726
|
const {
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import BaseFoundation, { DefaultAdapter } from '../base/foundation';
|
|
2
|
+
export declare function clampValueInRange(value: number, min: number, max: number): number;
|
|
3
|
+
export interface DragMoveAdapter<P = Record<string, any>, S = Record<string, any>> extends DefaultAdapter<P, S> {
|
|
4
|
+
getDragElement: () => HTMLElement;
|
|
5
|
+
getConstrainer: () => HTMLElement | null;
|
|
6
|
+
getHandler: () => HTMLElement;
|
|
7
|
+
notifyMouseDown?: (e: MouseEvent) => void;
|
|
8
|
+
notifyMouseMove?: (e: MouseEvent) => void;
|
|
9
|
+
notifyMouseUp?: (e: MouseEvent) => void;
|
|
10
|
+
notifyTouchStart?: (e: TouchEvent) => void;
|
|
11
|
+
notifyTouchMove?: (e: TouchEvent) => void;
|
|
12
|
+
notifyTouchEnd?: (e: TouchEvent) => void;
|
|
13
|
+
notifyTouchCancel?: (e: TouchEvent) => void;
|
|
14
|
+
}
|
|
15
|
+
export default class DragMoveFoundation<P = Record<string, any>, S = Record<string, any>> extends BaseFoundation<DragMoveAdapter<P, S>, P, S> {
|
|
16
|
+
element: HTMLElement;
|
|
17
|
+
xMax: number;
|
|
18
|
+
xMin: number;
|
|
19
|
+
yMax: number;
|
|
20
|
+
yMin: number;
|
|
21
|
+
startOffsetX: number;
|
|
22
|
+
startOffsetY: number;
|
|
23
|
+
get constrainer(): HTMLElement;
|
|
24
|
+
get handler(): HTMLElement;
|
|
25
|
+
constructor(adapter: DragMoveAdapter<P, S>);
|
|
26
|
+
init(): void;
|
|
27
|
+
destroy(): void;
|
|
28
|
+
_registerDocMouseEvent: () => void;
|
|
29
|
+
_unRegisterDocMouseEvent: () => void;
|
|
30
|
+
_registerDocTouchEvent: () => void;
|
|
31
|
+
_unRegisterDocTouchEvent: () => void;
|
|
32
|
+
_unRegisterEvent(): void;
|
|
33
|
+
_calcMoveRange(): void;
|
|
34
|
+
_allowMove(e: MouseEvent | TouchEvent): any;
|
|
35
|
+
_calcOffset: (e: Touch | MouseEvent) => void;
|
|
36
|
+
_preventDefault: (e: MouseEvent | TouchEvent) => void;
|
|
37
|
+
onMouseDown: (e: MouseEvent) => void;
|
|
38
|
+
onTouchStart: (e: TouchEvent) => void;
|
|
39
|
+
_changePos: (e: Touch | MouseEvent) => void;
|
|
40
|
+
_onMouseMove: (e: MouseEvent) => void;
|
|
41
|
+
_onTouchMove: (e: TouchEvent) => void;
|
|
42
|
+
_onMouseUp: (e: MouseEvent) => void;
|
|
43
|
+
_onTouchEnd: (e: TouchEvent) => void;
|
|
44
|
+
_onTouchCancel: (e: TouchEvent) => void;
|
|
45
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.clampValueInRange = clampValueInRange;
|
|
7
|
+
exports.default = void 0;
|
|
8
|
+
var _foundation = _interopRequireDefault(require("../base/foundation"));
|
|
9
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
|
+
function clampValueInRange(value, min, max) {
|
|
11
|
+
return Math.min(Math.max(value, min), max);
|
|
12
|
+
}
|
|
13
|
+
class DragMoveFoundation extends _foundation.default {
|
|
14
|
+
get constrainer() {
|
|
15
|
+
return this._adapter.getConstrainer();
|
|
16
|
+
}
|
|
17
|
+
get handler() {
|
|
18
|
+
return this._adapter.getHandler();
|
|
19
|
+
}
|
|
20
|
+
constructor(adapter) {
|
|
21
|
+
super(Object.assign({}, adapter));
|
|
22
|
+
this._registerDocMouseEvent = () => {
|
|
23
|
+
document.addEventListener('mousemove', this._onMouseMove);
|
|
24
|
+
document.addEventListener('mouseup', this._onMouseUp);
|
|
25
|
+
};
|
|
26
|
+
this._unRegisterDocMouseEvent = () => {
|
|
27
|
+
document.removeEventListener('mousemove', this._onMouseMove);
|
|
28
|
+
document.removeEventListener('mouseup', this._onMouseUp);
|
|
29
|
+
};
|
|
30
|
+
this._registerDocTouchEvent = () => {
|
|
31
|
+
document.addEventListener('touchend', this._onTouchEnd);
|
|
32
|
+
document.addEventListener('touchmove', this._onTouchMove);
|
|
33
|
+
document.addEventListener('touchcancel', this._onTouchCancel);
|
|
34
|
+
};
|
|
35
|
+
this._unRegisterDocTouchEvent = () => {
|
|
36
|
+
document.removeEventListener('touchend', this._onTouchEnd);
|
|
37
|
+
document.removeEventListener('touchmove', this._onTouchMove);
|
|
38
|
+
document.removeEventListener('touchcancel', this._onTouchCancel);
|
|
39
|
+
};
|
|
40
|
+
this._calcOffset = e => {
|
|
41
|
+
this.startOffsetX = e.clientX - this.element.offsetLeft;
|
|
42
|
+
this.startOffsetY = e.clientY - this.element.offsetTop;
|
|
43
|
+
};
|
|
44
|
+
this._preventDefault = e => {
|
|
45
|
+
// prevent default behavior, avoid other element(like img, text) be selected
|
|
46
|
+
e.preventDefault();
|
|
47
|
+
};
|
|
48
|
+
this.onMouseDown = e => {
|
|
49
|
+
this._calcMoveRange();
|
|
50
|
+
this._adapter.notifyMouseDown(e);
|
|
51
|
+
if (!this._allowMove(e)) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
this._registerDocMouseEvent();
|
|
55
|
+
// store origin offset
|
|
56
|
+
this._calcOffset(e);
|
|
57
|
+
this._preventDefault(e);
|
|
58
|
+
};
|
|
59
|
+
this.onTouchStart = e => {
|
|
60
|
+
this._calcMoveRange();
|
|
61
|
+
this._adapter.notifyTouchStart(e);
|
|
62
|
+
if (!this._allowMove(e)) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
this._registerDocTouchEvent();
|
|
66
|
+
const touch = e.targetTouches[0];
|
|
67
|
+
this._calcOffset(touch);
|
|
68
|
+
this._preventDefault(e);
|
|
69
|
+
};
|
|
70
|
+
this._changePos = e => {
|
|
71
|
+
const {
|
|
72
|
+
customMove
|
|
73
|
+
} = this.getProps();
|
|
74
|
+
let newLeft = e.clientX - this.startOffsetX;
|
|
75
|
+
let newTop = e.clientY - this.startOffsetY;
|
|
76
|
+
if (this.constrainer) {
|
|
77
|
+
newLeft = clampValueInRange(newLeft, this.xMin, this.xMax);
|
|
78
|
+
newTop = clampValueInRange(newTop, this.yMin, this.yMax);
|
|
79
|
+
}
|
|
80
|
+
requestAnimationFrame(() => {
|
|
81
|
+
if (customMove) {
|
|
82
|
+
customMove(this.element, newTop, newLeft);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
this.element.style.top = newTop + 'px';
|
|
86
|
+
this.element.style.left = newLeft + 'px';
|
|
87
|
+
});
|
|
88
|
+
};
|
|
89
|
+
this._onMouseMove = e => {
|
|
90
|
+
this._adapter.notifyMouseMove(e);
|
|
91
|
+
this._changePos(e);
|
|
92
|
+
};
|
|
93
|
+
this._onTouchMove = e => {
|
|
94
|
+
this._adapter.notifyTouchMove(e);
|
|
95
|
+
const touch = e.targetTouches[0];
|
|
96
|
+
this._changePos(touch);
|
|
97
|
+
};
|
|
98
|
+
this._onMouseUp = e => {
|
|
99
|
+
this._adapter.notifyMouseUp(e);
|
|
100
|
+
this._unRegisterDocMouseEvent();
|
|
101
|
+
};
|
|
102
|
+
this._onTouchEnd = e => {
|
|
103
|
+
this._adapter.notifyTouchEnd(e);
|
|
104
|
+
this._unRegisterDocTouchEvent();
|
|
105
|
+
};
|
|
106
|
+
this._onTouchCancel = e => {
|
|
107
|
+
this._adapter.notifyTouchCancel(e);
|
|
108
|
+
this._unRegisterDocTouchEvent();
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
init() {
|
|
112
|
+
const element = this._adapter.getDragElement();
|
|
113
|
+
if (!element) {
|
|
114
|
+
throw new Error('drag element must be a valid element');
|
|
115
|
+
}
|
|
116
|
+
this.element = element;
|
|
117
|
+
this.element.style.position = 'absolute';
|
|
118
|
+
this.handler.style.cursor = 'move';
|
|
119
|
+
}
|
|
120
|
+
destroy() {
|
|
121
|
+
this._unRegisterEvent();
|
|
122
|
+
}
|
|
123
|
+
_unRegisterEvent() {
|
|
124
|
+
this._unRegisterDocMouseEvent();
|
|
125
|
+
this._unRegisterDocTouchEvent();
|
|
126
|
+
}
|
|
127
|
+
_calcMoveRange() {
|
|
128
|
+
// Calculate the range within which an element can move
|
|
129
|
+
if (this.constrainer) {
|
|
130
|
+
let node = this.element.offsetParent;
|
|
131
|
+
let startX = 0;
|
|
132
|
+
let startY = 0;
|
|
133
|
+
while (node !== this.constrainer && node !== null) {
|
|
134
|
+
startX -= node.offsetLeft;
|
|
135
|
+
startY -= node.offsetTop;
|
|
136
|
+
node = node.offsetParent;
|
|
137
|
+
}
|
|
138
|
+
this.xMin = startX;
|
|
139
|
+
this.xMax = startX + this.constrainer.offsetWidth - this.element.offsetWidth;
|
|
140
|
+
this.yMin = startY;
|
|
141
|
+
this.yMax = startY + this.constrainer.offsetHeight - this.element.offsetHeight;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
_allowMove(e) {
|
|
145
|
+
const {
|
|
146
|
+
allowMove,
|
|
147
|
+
allowInputDrag
|
|
148
|
+
} = this.getProps();
|
|
149
|
+
// When the clicked object is an input or textarea, clicking should be allowed but dragging should not be allowed.
|
|
150
|
+
if (!allowInputDrag) {
|
|
151
|
+
let target = e.target.tagName.toLowerCase();
|
|
152
|
+
if (target === 'input' || target === 'textarea') {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
if (allowMove) {
|
|
157
|
+
return allowMove(e, this.element);
|
|
158
|
+
}
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
exports.default = DragMoveFoundation;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import BaseFoundation, { DefaultAdapter } from '../base/foundation';
|
|
2
|
+
interface HighlightAdapter extends Partial<DefaultAdapter> {
|
|
3
|
+
}
|
|
4
|
+
interface ChunkQuery {
|
|
5
|
+
autoEscape?: boolean;
|
|
6
|
+
caseSensitive?: boolean;
|
|
7
|
+
searchWords: SearchWords;
|
|
8
|
+
sourceString: string;
|
|
9
|
+
}
|
|
10
|
+
export interface Chunk {
|
|
11
|
+
start: number;
|
|
12
|
+
end: number;
|
|
13
|
+
highlight: boolean;
|
|
14
|
+
className: string;
|
|
15
|
+
style: Record<string, string>;
|
|
16
|
+
}
|
|
17
|
+
export interface ComplexSearchWord {
|
|
18
|
+
text: string;
|
|
19
|
+
className?: string;
|
|
20
|
+
style?: Record<string, string>;
|
|
21
|
+
}
|
|
22
|
+
export type SearchWord = string | ComplexSearchWord | undefined;
|
|
23
|
+
export type SearchWords = SearchWord[];
|
|
24
|
+
export default class HighlightFoundation extends BaseFoundation<HighlightAdapter> {
|
|
25
|
+
constructor(adapter?: HighlightAdapter);
|
|
26
|
+
/**
|
|
27
|
+
* Creates an array of chunk objects representing both higlightable and non highlightable pieces of text that match each search word.
|
|
28
|
+
*
|
|
29
|
+
findAll ['z'], 'aaazaaazaaa'
|
|
30
|
+
result #=> [
|
|
31
|
+
{ start: 0, end: 3, highlight: false }
|
|
32
|
+
{ start: 3, end: 4, highlight: true }
|
|
33
|
+
{ start: 4, end: 7, highlight: false }
|
|
34
|
+
{ start: 7, end: 8, highlight: true }
|
|
35
|
+
{ start: 8, end: 11, highlight: false }
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
findAll ['do', 'dollar'], 'aaa do dollar aaa'
|
|
39
|
+
#=> chunks: [
|
|
40
|
+
{ start: 4, end: 6 },
|
|
41
|
+
{ start: 7, end: 9 },
|
|
42
|
+
{ start: 7, end: 13 },
|
|
43
|
+
]
|
|
44
|
+
#=> chunksToHight: [
|
|
45
|
+
{ start: 4, end: 6 },
|
|
46
|
+
{ start: 7, end: 13 },
|
|
47
|
+
]
|
|
48
|
+
#=> result: [
|
|
49
|
+
{ start: 0, end: 4, highlight: false },
|
|
50
|
+
{ start: 4, end: 6, highlight: true },
|
|
51
|
+
{ start: 6, end: 7, highlight: false },
|
|
52
|
+
{ start: 7, end: 13, highlight: true },
|
|
53
|
+
{ start: 13, end: 17, highlight: false },
|
|
54
|
+
]
|
|
55
|
+
|
|
56
|
+
* @return Array of "chunks" (where a Chunk is { start:number, end:number, highlight:boolean })
|
|
57
|
+
*/
|
|
58
|
+
findAll: ({ autoEscape, caseSensitive, searchWords, sourceString }: ChunkQuery) => Chunk[];
|
|
59
|
+
/**
|
|
60
|
+
* Examine text for any matches.
|
|
61
|
+
* If we find matches, add them to the returned array as a "chunk" object ({start:number, end:number}).
|
|
62
|
+
* @return { start:number, end:number }[]
|
|
63
|
+
*/
|
|
64
|
+
findChunks: ({ autoEscape, caseSensitive, searchWords, sourceString }: ChunkQuery) => Chunk[];
|
|
65
|
+
/**
|
|
66
|
+
* Takes an array of {start:number, end:number} objects and combines chunks that overlap into single chunks.
|
|
67
|
+
* @return {start:number, end:number}[]
|
|
68
|
+
*/
|
|
69
|
+
combineChunks: ({ chunks }: {
|
|
70
|
+
chunks: Chunk[];
|
|
71
|
+
}) => Chunk[];
|
|
72
|
+
/**
|
|
73
|
+
* Given a set of chunks to highlight, create an additional set of chunks
|
|
74
|
+
* to represent the bits of text between the highlighted text.
|
|
75
|
+
* @param chunksToHighlight {start:number, end:number}[]
|
|
76
|
+
* @param totalLength number
|
|
77
|
+
* @return {start:number, end:number, highlight:boolean}[]
|
|
78
|
+
*/
|
|
79
|
+
fillInChunks: ({ chunksToHighlight, totalLength }: {
|
|
80
|
+
chunksToHighlight: Chunk[];
|
|
81
|
+
totalLength: number;
|
|
82
|
+
}) => Chunk[];
|
|
83
|
+
}
|
|
84
|
+
export {};
|