@hairy/vue-lib 1.3.16
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/LICENSE +23 -0
- package/dist/index.cjs +426 -0
- package/dist/index.d.ts +181 -0
- package/dist/index.mjs +380 -0
- package/package.json +37 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2019-PRESENT Hairyf<https://github.com/hairyf>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
23
|
+
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var src_exports = {};
|
|
32
|
+
__export(src_exports, {
|
|
33
|
+
CollapseTransition: () => CollapseTransition,
|
|
34
|
+
Field: () => Field,
|
|
35
|
+
ehr: () => ehr,
|
|
36
|
+
propertyToRef: () => propertyToRef,
|
|
37
|
+
syncElementSize: () => syncElementSize,
|
|
38
|
+
syncElementSyncScroll: () => syncElementSyncScroll,
|
|
39
|
+
useCheckedState: () => useCheckedState,
|
|
40
|
+
useSelectedMultiple: () => useSelectedMultiple,
|
|
41
|
+
useSelectedSingle: () => useSelectedSingle,
|
|
42
|
+
useServerPagination: () => useServerPagination
|
|
43
|
+
});
|
|
44
|
+
module.exports = __toCommonJS(src_exports);
|
|
45
|
+
|
|
46
|
+
// src/components/CollapseTransition.ts
|
|
47
|
+
var import_vue_demi = require("vue-demi");
|
|
48
|
+
var import_css_render = __toESM(require("css-render"));
|
|
49
|
+
var { c } = (0, import_css_render.default)();
|
|
50
|
+
var CollapseTransition = (0, import_vue_demi.defineComponent)({
|
|
51
|
+
name: "CollapseTransition",
|
|
52
|
+
setup(_, { slots }) {
|
|
53
|
+
const on = {
|
|
54
|
+
onBeforeEnter(el) {
|
|
55
|
+
el.classList.add("collapse-transition");
|
|
56
|
+
if (!el.dataset)
|
|
57
|
+
el.dataset = {};
|
|
58
|
+
el.dataset.oldPaddingTop = el.style.paddingTop;
|
|
59
|
+
el.dataset.oldPaddingBottom = el.style.paddingBottom;
|
|
60
|
+
el.style.height = "0";
|
|
61
|
+
el.style.paddingTop = "0";
|
|
62
|
+
el.style.paddingBottom = "0";
|
|
63
|
+
},
|
|
64
|
+
onEnter(el) {
|
|
65
|
+
el.dataset.oldOverflow = el.style.overflow;
|
|
66
|
+
if (el.scrollHeight !== 0) {
|
|
67
|
+
el.style.height = `${el.scrollHeight}px`;
|
|
68
|
+
el.style.paddingTop = el.dataset.oldPaddingTop || "0";
|
|
69
|
+
el.style.paddingBottom = el.dataset.oldPaddingBottom || "0";
|
|
70
|
+
} else {
|
|
71
|
+
el.style.height = "";
|
|
72
|
+
el.style.paddingTop = el.dataset.oldPaddingTop || "0";
|
|
73
|
+
el.style.paddingBottom = el.dataset.oldPaddingBottom || "0";
|
|
74
|
+
}
|
|
75
|
+
el.style.overflow = "hidden";
|
|
76
|
+
},
|
|
77
|
+
onAfterEnter(el) {
|
|
78
|
+
el.classList.remove("collapse-transition");
|
|
79
|
+
el.style.height = "";
|
|
80
|
+
el.style.overflow = el.dataset.oldOverflow || "0";
|
|
81
|
+
},
|
|
82
|
+
onBeforeLeave(el) {
|
|
83
|
+
if (!el.dataset)
|
|
84
|
+
el.dataset = {};
|
|
85
|
+
el.dataset.oldPaddingTop = el.style.paddingTop;
|
|
86
|
+
el.dataset.oldPaddingBottom = el.style.paddingBottom;
|
|
87
|
+
el.dataset.oldOverflow = el.style.overflow;
|
|
88
|
+
el.style.height = `${el.scrollHeight}px`;
|
|
89
|
+
el.style.overflow = "hidden";
|
|
90
|
+
},
|
|
91
|
+
onLeave(el) {
|
|
92
|
+
if (el.scrollHeight !== 0) {
|
|
93
|
+
el.classList.add("collapse-transition");
|
|
94
|
+
el.style.transitionProperty = "height";
|
|
95
|
+
el.style.height = "0";
|
|
96
|
+
el.style.paddingTop = "0";
|
|
97
|
+
el.style.paddingBottom = "0";
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
onAfterLeave(el) {
|
|
101
|
+
el.classList.remove("collapse-transition");
|
|
102
|
+
el.style.height = "";
|
|
103
|
+
el.style.overflow = el.dataset.oldOverflow || "0";
|
|
104
|
+
el.style.paddingTop = el.dataset.oldPaddingTop || "0";
|
|
105
|
+
el.style.paddingBottom = el.dataset.oldPaddingBottom || "0";
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
style.mount();
|
|
109
|
+
return () => (0, import_vue_demi.h)(import_vue_demi.Transition, on, slots);
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
var style = c(".collapse-transition", {
|
|
113
|
+
transition: "0.2s height ease-in-out, 0.2s padding-top ease-in-out,0.2s padding-bottom ease-in-out"
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
// src/components/Field.ts
|
|
117
|
+
var import_vue_demi2 = require("vue-demi");
|
|
118
|
+
var Field = (0, import_vue_demi2.defineComponent)({
|
|
119
|
+
name: "Field",
|
|
120
|
+
props: {
|
|
121
|
+
is: {
|
|
122
|
+
type: [String, Number, Object],
|
|
123
|
+
default: ""
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
setup(props) {
|
|
127
|
+
return () => {
|
|
128
|
+
if (typeof props.is === "string" || typeof props.is === "number")
|
|
129
|
+
return props.is;
|
|
130
|
+
return props.is ? (0, import_vue_demi2.h)(props.is) : null;
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
// src/composition/syncElementScroll/index.ts
|
|
136
|
+
var import_core = require("@vueuse/core");
|
|
137
|
+
var import_throttle = __toESM(require("lodash/throttle"));
|
|
138
|
+
var import_debounce = __toESM(require("lodash/debounce"));
|
|
139
|
+
var import_vue = require("vue");
|
|
140
|
+
function syncElementSyncScroll(fromTarget, toTarget, options = {}) {
|
|
141
|
+
const { left = true, top = true, wait, immediate = true } = options;
|
|
142
|
+
const debounceScrollLocks = (0, import_vue.reactive)({ from: false, to: false });
|
|
143
|
+
const onChangeLockScrollListener = (0, import_debounce.default)(
|
|
144
|
+
(type) => {
|
|
145
|
+
debounceScrollLocks[type] = true;
|
|
146
|
+
},
|
|
147
|
+
20,
|
|
148
|
+
{ leading: true, trailing: false }
|
|
149
|
+
);
|
|
150
|
+
const offChangeLockScrollListener = (0, import_debounce.default)(
|
|
151
|
+
(type) => {
|
|
152
|
+
debounceScrollLocks[type] = false;
|
|
153
|
+
},
|
|
154
|
+
20,
|
|
155
|
+
{ leading: false, trailing: true }
|
|
156
|
+
);
|
|
157
|
+
const syncScroll = (type) => {
|
|
158
|
+
const positive = type;
|
|
159
|
+
const opposite = type === "from" ? "to" : "from";
|
|
160
|
+
const elements = (0, import_vue.reactive)({
|
|
161
|
+
from: fromTarget,
|
|
162
|
+
to: toTarget
|
|
163
|
+
});
|
|
164
|
+
if (debounceScrollLocks[type])
|
|
165
|
+
return;
|
|
166
|
+
onChangeLockScrollListener(opposite);
|
|
167
|
+
const aElement = elements[positive];
|
|
168
|
+
const bElement = elements[opposite];
|
|
169
|
+
const options2 = {};
|
|
170
|
+
if (left)
|
|
171
|
+
options2.left = aElement.scrollLeft;
|
|
172
|
+
if (top)
|
|
173
|
+
options2.top = aElement.scrollTop;
|
|
174
|
+
if (!aElement || !bElement)
|
|
175
|
+
return;
|
|
176
|
+
bElement == null ? void 0 : bElement.scroll(options2);
|
|
177
|
+
offChangeLockScrollListener(opposite);
|
|
178
|
+
};
|
|
179
|
+
const syncFromTo = () => syncScroll("from");
|
|
180
|
+
const syncToFrom = () => syncScroll("to");
|
|
181
|
+
let toStopHandle;
|
|
182
|
+
let formStopHandle;
|
|
183
|
+
const stop = () => {
|
|
184
|
+
toStopHandle == null ? void 0 : toStopHandle();
|
|
185
|
+
formStopHandle == null ? void 0 : formStopHandle();
|
|
186
|
+
};
|
|
187
|
+
const start = () => {
|
|
188
|
+
toStopHandle = (0, import_core.useEventListener)(fromTarget, "scroll", (0, import_throttle.default)(syncFromTo, wait));
|
|
189
|
+
formStopHandle = (0, import_core.useEventListener)(toTarget, "scroll", (0, import_throttle.default)(syncToFrom, wait));
|
|
190
|
+
};
|
|
191
|
+
if (immediate)
|
|
192
|
+
start();
|
|
193
|
+
return { stop, start, syncFromTo, syncToFrom };
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// src/composition/syncElementSize/index.ts
|
|
197
|
+
var import_utils = require("@hairy/utils");
|
|
198
|
+
var import_core2 = require("@vueuse/core");
|
|
199
|
+
var import_vue2 = require("vue");
|
|
200
|
+
function syncElementSize(fromTarget, toTarget, options = {}) {
|
|
201
|
+
const { width: isOnWidth = true, height: isOnHeight = false } = options;
|
|
202
|
+
const defaultSize = { width: "", height: "" };
|
|
203
|
+
const fromSize = (0, import_core2.useElementSize)(fromTarget);
|
|
204
|
+
let widthStopHandle;
|
|
205
|
+
let heightStopHandle;
|
|
206
|
+
const sync = (type) => {
|
|
207
|
+
const sources = [fromSize[type], toTarget];
|
|
208
|
+
const callback = () => {
|
|
209
|
+
const element = (0, import_core2.unrefElement)(toTarget);
|
|
210
|
+
if (!element)
|
|
211
|
+
return void 0;
|
|
212
|
+
element.style[type] = (0, import_utils.formatUnit)(fromSize[type].value);
|
|
213
|
+
};
|
|
214
|
+
return (0, import_vue2.watch)(sources, callback, { immediate: true, ...options });
|
|
215
|
+
};
|
|
216
|
+
const stop = () => {
|
|
217
|
+
widthStopHandle == null ? void 0 : widthStopHandle();
|
|
218
|
+
heightStopHandle == null ? void 0 : heightStopHandle();
|
|
219
|
+
const element = (0, import_core2.unrefElement)(toTarget);
|
|
220
|
+
element.style.width = defaultSize.width;
|
|
221
|
+
element.style.height = defaultSize.height;
|
|
222
|
+
};
|
|
223
|
+
const start = () => {
|
|
224
|
+
if (isOnWidth)
|
|
225
|
+
widthStopHandle = sync("width");
|
|
226
|
+
if (isOnHeight)
|
|
227
|
+
heightStopHandle = sync("height");
|
|
228
|
+
};
|
|
229
|
+
(0, import_vue2.watch)(
|
|
230
|
+
() => (0, import_vue2.unref)(toTarget),
|
|
231
|
+
() => {
|
|
232
|
+
const element = (0, import_core2.unrefElement)(toTarget);
|
|
233
|
+
defaultSize.width = element.style.width;
|
|
234
|
+
defaultSize.height = element.style.height;
|
|
235
|
+
}
|
|
236
|
+
);
|
|
237
|
+
start();
|
|
238
|
+
return { start, stop };
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// src/composition/useCheckedState/index.ts
|
|
242
|
+
var import_vue3 = require("vue");
|
|
243
|
+
function useCheckedState(target, checked = true, unchecked = false) {
|
|
244
|
+
return (0, import_vue3.computed)({
|
|
245
|
+
get: () => target.value === (0, import_vue3.unref)(checked),
|
|
246
|
+
set: (_value) => {
|
|
247
|
+
target.value = _value ? (0, import_vue3.unref)(checked) : (0, import_vue3.unref)(unchecked);
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// src/composition/usePaginationServer/index.ts
|
|
253
|
+
var import_core3 = require("@vueuse/core");
|
|
254
|
+
var import_vue4 = require("vue");
|
|
255
|
+
var import_debounce2 = __toESM(require("lodash/debounce"));
|
|
256
|
+
function useServerPagination(options) {
|
|
257
|
+
const total = (0, import_vue4.ref)(Infinity);
|
|
258
|
+
const pagination = (0, import_core3.useOffsetPagination)({ total, ...options });
|
|
259
|
+
const resolveOptions = (0, import_vue4.reactive)({
|
|
260
|
+
currentPage: pagination.currentPage,
|
|
261
|
+
currentPageSize: pagination.currentPageSize,
|
|
262
|
+
total
|
|
263
|
+
});
|
|
264
|
+
const paginationRef = (0, import_vue4.reactive)({
|
|
265
|
+
currentPage: pagination.currentPage,
|
|
266
|
+
currentPageSize: pagination.currentPageSize,
|
|
267
|
+
pageCount: pagination.pageCount,
|
|
268
|
+
isFirstPage: pagination.isFirstPage,
|
|
269
|
+
isLastPage: pagination.isLastPage,
|
|
270
|
+
total
|
|
271
|
+
});
|
|
272
|
+
const state = (0, import_vue4.ref)([]);
|
|
273
|
+
const {
|
|
274
|
+
execute: _execute,
|
|
275
|
+
isLoading: loading,
|
|
276
|
+
error
|
|
277
|
+
} = (0, import_core3.useAsyncState)(async () => {
|
|
278
|
+
const resolved = await options.resolve(resolveOptions);
|
|
279
|
+
return resolved;
|
|
280
|
+
}, []);
|
|
281
|
+
const execute = (0, import_debounce2.default)(async () => {
|
|
282
|
+
state.value = await _execute();
|
|
283
|
+
}, 100);
|
|
284
|
+
(0, import_vue4.nextTick)(() => {
|
|
285
|
+
(0, import_vue4.watch)([pagination.currentPageSize, ...options.sources || []], execute, { immediate: true, ...options });
|
|
286
|
+
(0, import_vue4.watch)(pagination.currentPage, (newValue, oldValue) => newValue !== oldValue && execute());
|
|
287
|
+
});
|
|
288
|
+
return {
|
|
289
|
+
state,
|
|
290
|
+
loading,
|
|
291
|
+
error,
|
|
292
|
+
execute,
|
|
293
|
+
pagination: paginationRef,
|
|
294
|
+
next: pagination.next,
|
|
295
|
+
prev: pagination.prev
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// src/composition/useSelectedMultiple/index.ts
|
|
300
|
+
var import_vue6 = require("vue");
|
|
301
|
+
|
|
302
|
+
// src/composition/utils/extendSelected.ts
|
|
303
|
+
var import_vue5 = require("vue");
|
|
304
|
+
var import_core4 = require("@vueuse/core");
|
|
305
|
+
function extendSelected(array, fieldName) {
|
|
306
|
+
(0, import_vue5.watch)(
|
|
307
|
+
array,
|
|
308
|
+
(items) => {
|
|
309
|
+
for (const item of items) {
|
|
310
|
+
if (typeof item[fieldName] === "undefined")
|
|
311
|
+
(0, import_core4.extendRef)(item, { [fieldName]: (0, import_vue5.ref)(false) });
|
|
312
|
+
}
|
|
313
|
+
},
|
|
314
|
+
{ immediate: true, flush: "sync" }
|
|
315
|
+
);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// src/composition/useSelectedMultiple/index.ts
|
|
319
|
+
function useSelectedMultiple(array, options = {}) {
|
|
320
|
+
const { fieldName = "select", disabled } = options;
|
|
321
|
+
extendSelected(array, fieldName);
|
|
322
|
+
const selected = (0, import_vue6.computed)(() => (0, import_vue6.unref)(array).filter((item) => item[fieldName]));
|
|
323
|
+
const isSelectedAll = (0, import_vue6.computed)({
|
|
324
|
+
get: () => {
|
|
325
|
+
var _a;
|
|
326
|
+
return !((_a = selected.value) == null ? void 0 : _a.length) && !(0, import_vue6.unref)(array).some((item) => !item[fieldName]);
|
|
327
|
+
},
|
|
328
|
+
set: (value) => (0, import_vue6.unref)(array).forEach((item, index) => {
|
|
329
|
+
if (!(disabled == null ? void 0 : disabled(item, index)))
|
|
330
|
+
item[fieldName] = value;
|
|
331
|
+
})
|
|
332
|
+
});
|
|
333
|
+
const isSelected = (0, import_vue6.computed)(() => !!(0, import_vue6.unref)(array).some((item) => item[fieldName]));
|
|
334
|
+
const isIndeterminate = (0, import_vue6.computed)(() => {
|
|
335
|
+
const selectCount = selected.value.length;
|
|
336
|
+
return selectCount > 0 && selectCount < (0, import_vue6.unref)(array).length;
|
|
337
|
+
});
|
|
338
|
+
return { selected, isSelectedAll, isSelected, isIndeterminate };
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// src/composition/useSelectedSingle/index.ts
|
|
342
|
+
var import_vue7 = require("vue");
|
|
343
|
+
function useSelectedSingle(array, options = {}) {
|
|
344
|
+
var _a, _b;
|
|
345
|
+
const fieldName = (_a = options.fieldName) != null ? _a : "select";
|
|
346
|
+
const required = (_b = options.required) != null ? _b : false;
|
|
347
|
+
extendSelected(array, fieldName);
|
|
348
|
+
const SELECTED_SINGLE_KEY = "selected_single_key";
|
|
349
|
+
const isLocked = (0, import_vue7.ref)(false);
|
|
350
|
+
const isSelected = (0, import_vue7.computed)(() => !!(0, import_vue7.unref)(array).some((item) => item.select));
|
|
351
|
+
if (required) {
|
|
352
|
+
const recover = (bool) => {
|
|
353
|
+
const index = required === true ? 0 : required;
|
|
354
|
+
if (!bool && (0, import_vue7.unref)(array).length > 0)
|
|
355
|
+
(0, import_vue7.unref)(array)[index][fieldName] = true;
|
|
356
|
+
};
|
|
357
|
+
(0, import_vue7.watch)(isSelected, recover, { flush: "sync", immediate: true });
|
|
358
|
+
}
|
|
359
|
+
const itemChange = (neglect) => {
|
|
360
|
+
if (isLocked.value)
|
|
361
|
+
return;
|
|
362
|
+
isLocked.value = true;
|
|
363
|
+
const _array = (0, import_vue7.unref)(array);
|
|
364
|
+
const _value = !_array[neglect][fieldName];
|
|
365
|
+
if (required && !_value)
|
|
366
|
+
_array[neglect][fieldName] = true;
|
|
367
|
+
_array.forEach((target, index) => {
|
|
368
|
+
if (neglect === index)
|
|
369
|
+
return void 0;
|
|
370
|
+
if (!target[fieldName])
|
|
371
|
+
return void 0;
|
|
372
|
+
target[fieldName] = false;
|
|
373
|
+
});
|
|
374
|
+
isLocked.value = false;
|
|
375
|
+
};
|
|
376
|
+
const targetEffect = (target, index) => {
|
|
377
|
+
if (!target[SELECTED_SINGLE_KEY]) {
|
|
378
|
+
return (0, import_vue7.watch)(
|
|
379
|
+
() => target[fieldName],
|
|
380
|
+
() => itemChange(index),
|
|
381
|
+
{ flush: "sync" }
|
|
382
|
+
);
|
|
383
|
+
}
|
|
384
|
+
Object.defineProperty(target, SELECTED_SINGLE_KEY, { value: true });
|
|
385
|
+
};
|
|
386
|
+
(0, import_vue7.watch)(
|
|
387
|
+
array,
|
|
388
|
+
() => {
|
|
389
|
+
(0, import_vue7.unref)(array).forEach(targetEffect);
|
|
390
|
+
},
|
|
391
|
+
{ immediate: true, flush: "sync" }
|
|
392
|
+
);
|
|
393
|
+
const selected = (0, import_vue7.computed)(() => (0, import_vue7.unref)(array).find((v) => v[fieldName]));
|
|
394
|
+
return { selected, isSelected };
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// src/utils/index.ts
|
|
398
|
+
var import_vue_demi3 = require("vue-demi");
|
|
399
|
+
function ehr(component, tag) {
|
|
400
|
+
const container = document.createElement(tag || "dev");
|
|
401
|
+
(0, import_vue_demi3.render)((0, import_vue_demi3.h)(component), container);
|
|
402
|
+
return container;
|
|
403
|
+
}
|
|
404
|
+
function propertyToRef(data, prop) {
|
|
405
|
+
return (0, import_vue_demi3.computed)({
|
|
406
|
+
get() {
|
|
407
|
+
return data[prop];
|
|
408
|
+
},
|
|
409
|
+
set(v) {
|
|
410
|
+
data[prop] = v;
|
|
411
|
+
}
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
415
|
+
0 && (module.exports = {
|
|
416
|
+
CollapseTransition,
|
|
417
|
+
Field,
|
|
418
|
+
ehr,
|
|
419
|
+
propertyToRef,
|
|
420
|
+
syncElementSize,
|
|
421
|
+
syncElementSyncScroll,
|
|
422
|
+
useCheckedState,
|
|
423
|
+
useSelectedMultiple,
|
|
424
|
+
useSelectedSingle,
|
|
425
|
+
useServerPagination
|
|
426
|
+
});
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import * as vue_demi from 'vue-demi';
|
|
2
|
+
import { DefineComponent, PropType, VNode, Component, FunctionalComponent } from 'vue-demi';
|
|
3
|
+
import { MaybeRef, MaybeElementRef, UseOffsetPaginationReturn, UseOffsetPaginationOptions } from '@vueuse/core';
|
|
4
|
+
import * as vue from 'vue';
|
|
5
|
+
import { WatchOptions, Ref, UnwrapRef, ComputedRef } from 'vue';
|
|
6
|
+
import { DebouncedFunc } from 'lodash';
|
|
7
|
+
|
|
8
|
+
declare const CollapseTransition: DefineComponent;
|
|
9
|
+
|
|
10
|
+
declare const Field: vue_demi.DefineComponent<vue_demi.ExtractPropTypes<{
|
|
11
|
+
is: {
|
|
12
|
+
type: PropType<string | number | VNode<vue_demi.RendererNode, vue_demi.RendererElement, {
|
|
13
|
+
[key: string]: any;
|
|
14
|
+
}> | Component<any, any, any, vue_demi.ComputedOptions, vue_demi.MethodOptions, {}, any>>;
|
|
15
|
+
default: string;
|
|
16
|
+
};
|
|
17
|
+
}>, () => string | number | VNode<vue_demi.RendererNode, vue_demi.RendererElement, {
|
|
18
|
+
[key: string]: any;
|
|
19
|
+
}> | null, {}, {}, {}, vue_demi.ComponentOptionsMixin, vue_demi.ComponentOptionsMixin, {}, string, vue_demi.PublicProps, Readonly<vue_demi.ExtractPropTypes<{
|
|
20
|
+
is: {
|
|
21
|
+
type: PropType<string | number | VNode<vue_demi.RendererNode, vue_demi.RendererElement, {
|
|
22
|
+
[key: string]: any;
|
|
23
|
+
}> | Component<any, any, any, vue_demi.ComputedOptions, vue_demi.MethodOptions, {}, any>>;
|
|
24
|
+
default: string;
|
|
25
|
+
};
|
|
26
|
+
}>> & Readonly<{}>, {
|
|
27
|
+
is: string | number | VNode<vue_demi.RendererNode, vue_demi.RendererElement, {
|
|
28
|
+
[key: string]: any;
|
|
29
|
+
}> | Component<any, any, any, vue_demi.ComputedOptions, vue_demi.MethodOptions, {}, any>;
|
|
30
|
+
}, {}, {}, {}, string, vue_demi.ComponentProvideOptions, true, {}, any>;
|
|
31
|
+
|
|
32
|
+
interface SyncElementSyncScrollOptions {
|
|
33
|
+
left?: boolean;
|
|
34
|
+
top?: boolean;
|
|
35
|
+
wait?: number;
|
|
36
|
+
immediate?: boolean;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* 同步两个具有相同滚动条的DOM的滚动
|
|
40
|
+
* @param fromTarget DOM-A
|
|
41
|
+
* @param toTarget DOM-B
|
|
42
|
+
* @param options
|
|
43
|
+
* @todo 优化 useEventListener 复用
|
|
44
|
+
* @todo 使用 wait 可能存在 BUG
|
|
45
|
+
*/
|
|
46
|
+
declare function syncElementSyncScroll(fromTarget: MaybeRef<EventTarget | null | undefined>, toTarget: MaybeRef<EventTarget | null | undefined>, options?: SyncElementSyncScrollOptions): {
|
|
47
|
+
stop: () => void;
|
|
48
|
+
start: () => void;
|
|
49
|
+
syncFromTo: () => void;
|
|
50
|
+
syncToFrom: () => void;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
interface SyncElementSizeOptions extends WatchOptions {
|
|
54
|
+
/** 是否开启宽度 @default true */
|
|
55
|
+
width?: boolean;
|
|
56
|
+
/** 是否开启高度 @default true */
|
|
57
|
+
height?: boolean;
|
|
58
|
+
}
|
|
59
|
+
interface SyncElementSizeReturn {
|
|
60
|
+
start?: Function;
|
|
61
|
+
stop?: Function;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* 同步 from DOM 的宽或高到指定的 to DOM
|
|
65
|
+
* @param fromTarget 宽高来源元素
|
|
66
|
+
* @param toTarget 宽高设置元素
|
|
67
|
+
* @param options
|
|
68
|
+
*/
|
|
69
|
+
declare function syncElementSize(fromTarget: MaybeElementRef, toTarget: MaybeElementRef, options?: SyncElementSizeOptions): SyncElementSizeReturn;
|
|
70
|
+
|
|
71
|
+
type CheckedState = string | boolean | number | symbol;
|
|
72
|
+
/**
|
|
73
|
+
* 获取 checked 的状态,自定义设置 checked | unchecked 的值
|
|
74
|
+
* @param target
|
|
75
|
+
* @param checked
|
|
76
|
+
* @param unchecked
|
|
77
|
+
* @returns
|
|
78
|
+
*/
|
|
79
|
+
declare function useCheckedState(target: Ref<any>, checked?: MaybeRef<CheckedState>, unchecked?: MaybeRef<CheckedState>): vue.WritableComputedRef<boolean, boolean>;
|
|
80
|
+
|
|
81
|
+
type UseServerPaginationResolve = UnwrapRef<Pick<UseOffsetPaginationReturn, 'currentPage' | 'currentPageSize'> & {
|
|
82
|
+
total: number;
|
|
83
|
+
}>;
|
|
84
|
+
type UseServerPagination = UnwrapRef<Omit<UseOffsetPaginationReturn, 'next' | 'prev'> & {
|
|
85
|
+
total: Ref<number>;
|
|
86
|
+
}>;
|
|
87
|
+
interface UseServerPaginationOptions<T> extends UseOffsetPaginationOptions, WatchOptions {
|
|
88
|
+
resolve: (pagination: UseServerPaginationResolve) => T | Promise<T>;
|
|
89
|
+
/** 监听源, 当源数据改变触发 reset, 默认监听 pagination */
|
|
90
|
+
sources?: any[];
|
|
91
|
+
}
|
|
92
|
+
interface UseServerPaginationReturn<T> {
|
|
93
|
+
state: Ref<T>;
|
|
94
|
+
loading: Ref<boolean>;
|
|
95
|
+
error: Ref<any>;
|
|
96
|
+
pagination: UseServerPagination;
|
|
97
|
+
next: () => void;
|
|
98
|
+
prev: () => void;
|
|
99
|
+
execute: DebouncedFunc<() => Promise<void>>;
|
|
100
|
+
}
|
|
101
|
+
declare function useServerPagination<T extends any[]>(options: UseServerPaginationOptions<T>): UseServerPaginationReturn<T>;
|
|
102
|
+
|
|
103
|
+
type SelectedMultipleArray = MaybeRef<{
|
|
104
|
+
[key: string]: any;
|
|
105
|
+
}[]>;
|
|
106
|
+
interface SelectedMultipleOptions<T extends SelectedMultipleArray> {
|
|
107
|
+
/**
|
|
108
|
+
* 选择字段
|
|
109
|
+
*
|
|
110
|
+
* @default 'select'
|
|
111
|
+
*/
|
|
112
|
+
fieldName?: string;
|
|
113
|
+
/**
|
|
114
|
+
* 处理禁用, 在 isSelectAll 更改时生效
|
|
115
|
+
*/
|
|
116
|
+
disabled?: (item: UnwrapRef<T>[number], index: number) => boolean | void;
|
|
117
|
+
}
|
|
118
|
+
interface SelectedMultipleResult<T extends SelectedMultipleArray> {
|
|
119
|
+
/**
|
|
120
|
+
* 当前选中的所有项
|
|
121
|
+
*/
|
|
122
|
+
selected: ComputedRef<UnwrapRef<T>>;
|
|
123
|
+
/**
|
|
124
|
+
* 当前是否全选, 更改后将影响列表的选择
|
|
125
|
+
*/
|
|
126
|
+
isSelectedAll: Ref<boolean>;
|
|
127
|
+
/**
|
|
128
|
+
* 是否选择
|
|
129
|
+
*/
|
|
130
|
+
isSelected: ComputedRef<boolean>;
|
|
131
|
+
/**
|
|
132
|
+
* 选中,但没有完全选完(一般用于 checkbox 组件)
|
|
133
|
+
*/
|
|
134
|
+
isIndeterminate: ComputedRef<boolean>;
|
|
135
|
+
}
|
|
136
|
+
declare function useSelectedMultiple<T extends SelectedMultipleArray>(array: T, options?: SelectedMultipleOptions<T>): SelectedMultipleResult<T>;
|
|
137
|
+
|
|
138
|
+
type SelectedSingleArray = MaybeRef<{
|
|
139
|
+
[key: string]: any;
|
|
140
|
+
}[]>;
|
|
141
|
+
interface SelectedSingleOptions {
|
|
142
|
+
/**
|
|
143
|
+
* 选择字段
|
|
144
|
+
*
|
|
145
|
+
* @default 'select'
|
|
146
|
+
*/
|
|
147
|
+
fieldName?: string;
|
|
148
|
+
/**
|
|
149
|
+
* 是否必选, 必选项是哪项
|
|
150
|
+
* @default false
|
|
151
|
+
*
|
|
152
|
+
*/
|
|
153
|
+
required?: true | number;
|
|
154
|
+
}
|
|
155
|
+
interface SelectedSingleResult<T extends SelectedSingleArray> {
|
|
156
|
+
/**
|
|
157
|
+
* 当前选中项
|
|
158
|
+
*/
|
|
159
|
+
selected: ComputedRef<UnwrapRef<T>[number] | undefined>;
|
|
160
|
+
/**
|
|
161
|
+
* 是否已经选择
|
|
162
|
+
*/
|
|
163
|
+
isSelected: ComputedRef<boolean>;
|
|
164
|
+
}
|
|
165
|
+
declare function useSelectedSingle<T extends SelectedSingleArray>(array: T, options?: SelectedSingleOptions): SelectedSingleResult<T>;
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* 直接渲染传入的组件(function component)
|
|
169
|
+
* @param component
|
|
170
|
+
* @param tag 渲染的容器(默认 div)
|
|
171
|
+
*/
|
|
172
|
+
declare function ehr<K extends keyof HTMLElementTagNameMap = 'div'>(component: FunctionalComponent, tag?: K): HTMLElementTagNameMap[K];
|
|
173
|
+
/**
|
|
174
|
+
* 将对象的属性转换为 ref
|
|
175
|
+
* @param data
|
|
176
|
+
* @param prop
|
|
177
|
+
* @returns
|
|
178
|
+
*/
|
|
179
|
+
declare function propertyToRef<T>(data: T, prop: keyof T): vue_demi.WritableComputedRef<T[keyof T], T[keyof T]>;
|
|
180
|
+
|
|
181
|
+
export { CheckedState, CollapseTransition, Field, SelectedMultipleArray, SelectedMultipleOptions, SelectedMultipleResult, SelectedSingleArray, SelectedSingleOptions, SelectedSingleResult, SyncElementSizeOptions, SyncElementSizeReturn, UseServerPagination, UseServerPaginationOptions, UseServerPaginationResolve, UseServerPaginationReturn, ehr, propertyToRef, syncElementSize, syncElementSyncScroll, useCheckedState, useSelectedMultiple, useSelectedSingle, useServerPagination };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
// src/components/CollapseTransition.ts
|
|
2
|
+
import { Transition, defineComponent, h } from "vue-demi";
|
|
3
|
+
import CssRender from "css-render";
|
|
4
|
+
var { c } = CssRender();
|
|
5
|
+
var CollapseTransition = defineComponent({
|
|
6
|
+
name: "CollapseTransition",
|
|
7
|
+
setup(_, { slots }) {
|
|
8
|
+
const on = {
|
|
9
|
+
onBeforeEnter(el) {
|
|
10
|
+
el.classList.add("collapse-transition");
|
|
11
|
+
if (!el.dataset)
|
|
12
|
+
el.dataset = {};
|
|
13
|
+
el.dataset.oldPaddingTop = el.style.paddingTop;
|
|
14
|
+
el.dataset.oldPaddingBottom = el.style.paddingBottom;
|
|
15
|
+
el.style.height = "0";
|
|
16
|
+
el.style.paddingTop = "0";
|
|
17
|
+
el.style.paddingBottom = "0";
|
|
18
|
+
},
|
|
19
|
+
onEnter(el) {
|
|
20
|
+
el.dataset.oldOverflow = el.style.overflow;
|
|
21
|
+
if (el.scrollHeight !== 0) {
|
|
22
|
+
el.style.height = `${el.scrollHeight}px`;
|
|
23
|
+
el.style.paddingTop = el.dataset.oldPaddingTop || "0";
|
|
24
|
+
el.style.paddingBottom = el.dataset.oldPaddingBottom || "0";
|
|
25
|
+
} else {
|
|
26
|
+
el.style.height = "";
|
|
27
|
+
el.style.paddingTop = el.dataset.oldPaddingTop || "0";
|
|
28
|
+
el.style.paddingBottom = el.dataset.oldPaddingBottom || "0";
|
|
29
|
+
}
|
|
30
|
+
el.style.overflow = "hidden";
|
|
31
|
+
},
|
|
32
|
+
onAfterEnter(el) {
|
|
33
|
+
el.classList.remove("collapse-transition");
|
|
34
|
+
el.style.height = "";
|
|
35
|
+
el.style.overflow = el.dataset.oldOverflow || "0";
|
|
36
|
+
},
|
|
37
|
+
onBeforeLeave(el) {
|
|
38
|
+
if (!el.dataset)
|
|
39
|
+
el.dataset = {};
|
|
40
|
+
el.dataset.oldPaddingTop = el.style.paddingTop;
|
|
41
|
+
el.dataset.oldPaddingBottom = el.style.paddingBottom;
|
|
42
|
+
el.dataset.oldOverflow = el.style.overflow;
|
|
43
|
+
el.style.height = `${el.scrollHeight}px`;
|
|
44
|
+
el.style.overflow = "hidden";
|
|
45
|
+
},
|
|
46
|
+
onLeave(el) {
|
|
47
|
+
if (el.scrollHeight !== 0) {
|
|
48
|
+
el.classList.add("collapse-transition");
|
|
49
|
+
el.style.transitionProperty = "height";
|
|
50
|
+
el.style.height = "0";
|
|
51
|
+
el.style.paddingTop = "0";
|
|
52
|
+
el.style.paddingBottom = "0";
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
onAfterLeave(el) {
|
|
56
|
+
el.classList.remove("collapse-transition");
|
|
57
|
+
el.style.height = "";
|
|
58
|
+
el.style.overflow = el.dataset.oldOverflow || "0";
|
|
59
|
+
el.style.paddingTop = el.dataset.oldPaddingTop || "0";
|
|
60
|
+
el.style.paddingBottom = el.dataset.oldPaddingBottom || "0";
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
style.mount();
|
|
64
|
+
return () => h(Transition, on, slots);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
var style = c(".collapse-transition", {
|
|
68
|
+
transition: "0.2s height ease-in-out, 0.2s padding-top ease-in-out,0.2s padding-bottom ease-in-out"
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// src/components/Field.ts
|
|
72
|
+
import { defineComponent as defineComponent2, h as h2 } from "vue-demi";
|
|
73
|
+
var Field = defineComponent2({
|
|
74
|
+
name: "Field",
|
|
75
|
+
props: {
|
|
76
|
+
is: {
|
|
77
|
+
type: [String, Number, Object],
|
|
78
|
+
default: ""
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
setup(props) {
|
|
82
|
+
return () => {
|
|
83
|
+
if (typeof props.is === "string" || typeof props.is === "number")
|
|
84
|
+
return props.is;
|
|
85
|
+
return props.is ? h2(props.is) : null;
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
// src/composition/syncElementScroll/index.ts
|
|
91
|
+
import { useEventListener } from "@vueuse/core";
|
|
92
|
+
import throttle from "lodash/throttle";
|
|
93
|
+
import debounce from "lodash/debounce";
|
|
94
|
+
import { reactive } from "vue";
|
|
95
|
+
function syncElementSyncScroll(fromTarget, toTarget, options = {}) {
|
|
96
|
+
const { left = true, top = true, wait, immediate = true } = options;
|
|
97
|
+
const debounceScrollLocks = reactive({ from: false, to: false });
|
|
98
|
+
const onChangeLockScrollListener = debounce(
|
|
99
|
+
(type) => {
|
|
100
|
+
debounceScrollLocks[type] = true;
|
|
101
|
+
},
|
|
102
|
+
20,
|
|
103
|
+
{ leading: true, trailing: false }
|
|
104
|
+
);
|
|
105
|
+
const offChangeLockScrollListener = debounce(
|
|
106
|
+
(type) => {
|
|
107
|
+
debounceScrollLocks[type] = false;
|
|
108
|
+
},
|
|
109
|
+
20,
|
|
110
|
+
{ leading: false, trailing: true }
|
|
111
|
+
);
|
|
112
|
+
const syncScroll = (type) => {
|
|
113
|
+
const positive = type;
|
|
114
|
+
const opposite = type === "from" ? "to" : "from";
|
|
115
|
+
const elements = reactive({
|
|
116
|
+
from: fromTarget,
|
|
117
|
+
to: toTarget
|
|
118
|
+
});
|
|
119
|
+
if (debounceScrollLocks[type])
|
|
120
|
+
return;
|
|
121
|
+
onChangeLockScrollListener(opposite);
|
|
122
|
+
const aElement = elements[positive];
|
|
123
|
+
const bElement = elements[opposite];
|
|
124
|
+
const options2 = {};
|
|
125
|
+
if (left)
|
|
126
|
+
options2.left = aElement.scrollLeft;
|
|
127
|
+
if (top)
|
|
128
|
+
options2.top = aElement.scrollTop;
|
|
129
|
+
if (!aElement || !bElement)
|
|
130
|
+
return;
|
|
131
|
+
bElement == null ? void 0 : bElement.scroll(options2);
|
|
132
|
+
offChangeLockScrollListener(opposite);
|
|
133
|
+
};
|
|
134
|
+
const syncFromTo = () => syncScroll("from");
|
|
135
|
+
const syncToFrom = () => syncScroll("to");
|
|
136
|
+
let toStopHandle;
|
|
137
|
+
let formStopHandle;
|
|
138
|
+
const stop = () => {
|
|
139
|
+
toStopHandle == null ? void 0 : toStopHandle();
|
|
140
|
+
formStopHandle == null ? void 0 : formStopHandle();
|
|
141
|
+
};
|
|
142
|
+
const start = () => {
|
|
143
|
+
toStopHandle = useEventListener(fromTarget, "scroll", throttle(syncFromTo, wait));
|
|
144
|
+
formStopHandle = useEventListener(toTarget, "scroll", throttle(syncToFrom, wait));
|
|
145
|
+
};
|
|
146
|
+
if (immediate)
|
|
147
|
+
start();
|
|
148
|
+
return { stop, start, syncFromTo, syncToFrom };
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// src/composition/syncElementSize/index.ts
|
|
152
|
+
import { formatUnit } from "@hairy/utils";
|
|
153
|
+
import { unrefElement, useElementSize } from "@vueuse/core";
|
|
154
|
+
import { unref, watch } from "vue";
|
|
155
|
+
function syncElementSize(fromTarget, toTarget, options = {}) {
|
|
156
|
+
const { width: isOnWidth = true, height: isOnHeight = false } = options;
|
|
157
|
+
const defaultSize = { width: "", height: "" };
|
|
158
|
+
const fromSize = useElementSize(fromTarget);
|
|
159
|
+
let widthStopHandle;
|
|
160
|
+
let heightStopHandle;
|
|
161
|
+
const sync = (type) => {
|
|
162
|
+
const sources = [fromSize[type], toTarget];
|
|
163
|
+
const callback = () => {
|
|
164
|
+
const element = unrefElement(toTarget);
|
|
165
|
+
if (!element)
|
|
166
|
+
return void 0;
|
|
167
|
+
element.style[type] = formatUnit(fromSize[type].value);
|
|
168
|
+
};
|
|
169
|
+
return watch(sources, callback, { immediate: true, ...options });
|
|
170
|
+
};
|
|
171
|
+
const stop = () => {
|
|
172
|
+
widthStopHandle == null ? void 0 : widthStopHandle();
|
|
173
|
+
heightStopHandle == null ? void 0 : heightStopHandle();
|
|
174
|
+
const element = unrefElement(toTarget);
|
|
175
|
+
element.style.width = defaultSize.width;
|
|
176
|
+
element.style.height = defaultSize.height;
|
|
177
|
+
};
|
|
178
|
+
const start = () => {
|
|
179
|
+
if (isOnWidth)
|
|
180
|
+
widthStopHandle = sync("width");
|
|
181
|
+
if (isOnHeight)
|
|
182
|
+
heightStopHandle = sync("height");
|
|
183
|
+
};
|
|
184
|
+
watch(
|
|
185
|
+
() => unref(toTarget),
|
|
186
|
+
() => {
|
|
187
|
+
const element = unrefElement(toTarget);
|
|
188
|
+
defaultSize.width = element.style.width;
|
|
189
|
+
defaultSize.height = element.style.height;
|
|
190
|
+
}
|
|
191
|
+
);
|
|
192
|
+
start();
|
|
193
|
+
return { start, stop };
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// src/composition/useCheckedState/index.ts
|
|
197
|
+
import { computed, unref as unref2 } from "vue";
|
|
198
|
+
function useCheckedState(target, checked = true, unchecked = false) {
|
|
199
|
+
return computed({
|
|
200
|
+
get: () => target.value === unref2(checked),
|
|
201
|
+
set: (_value) => {
|
|
202
|
+
target.value = _value ? unref2(checked) : unref2(unchecked);
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// src/composition/usePaginationServer/index.ts
|
|
208
|
+
import { useAsyncState, useOffsetPagination } from "@vueuse/core";
|
|
209
|
+
import { nextTick, reactive as reactive2, ref, watch as watch2 } from "vue";
|
|
210
|
+
import debounce2 from "lodash/debounce";
|
|
211
|
+
function useServerPagination(options) {
|
|
212
|
+
const total = ref(Infinity);
|
|
213
|
+
const pagination = useOffsetPagination({ total, ...options });
|
|
214
|
+
const resolveOptions = reactive2({
|
|
215
|
+
currentPage: pagination.currentPage,
|
|
216
|
+
currentPageSize: pagination.currentPageSize,
|
|
217
|
+
total
|
|
218
|
+
});
|
|
219
|
+
const paginationRef = reactive2({
|
|
220
|
+
currentPage: pagination.currentPage,
|
|
221
|
+
currentPageSize: pagination.currentPageSize,
|
|
222
|
+
pageCount: pagination.pageCount,
|
|
223
|
+
isFirstPage: pagination.isFirstPage,
|
|
224
|
+
isLastPage: pagination.isLastPage,
|
|
225
|
+
total
|
|
226
|
+
});
|
|
227
|
+
const state = ref([]);
|
|
228
|
+
const {
|
|
229
|
+
execute: _execute,
|
|
230
|
+
isLoading: loading,
|
|
231
|
+
error
|
|
232
|
+
} = useAsyncState(async () => {
|
|
233
|
+
const resolved = await options.resolve(resolveOptions);
|
|
234
|
+
return resolved;
|
|
235
|
+
}, []);
|
|
236
|
+
const execute = debounce2(async () => {
|
|
237
|
+
state.value = await _execute();
|
|
238
|
+
}, 100);
|
|
239
|
+
nextTick(() => {
|
|
240
|
+
watch2([pagination.currentPageSize, ...options.sources || []], execute, { immediate: true, ...options });
|
|
241
|
+
watch2(pagination.currentPage, (newValue, oldValue) => newValue !== oldValue && execute());
|
|
242
|
+
});
|
|
243
|
+
return {
|
|
244
|
+
state,
|
|
245
|
+
loading,
|
|
246
|
+
error,
|
|
247
|
+
execute,
|
|
248
|
+
pagination: paginationRef,
|
|
249
|
+
next: pagination.next,
|
|
250
|
+
prev: pagination.prev
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// src/composition/useSelectedMultiple/index.ts
|
|
255
|
+
import { computed as computed2, unref as unref3 } from "vue";
|
|
256
|
+
|
|
257
|
+
// src/composition/utils/extendSelected.ts
|
|
258
|
+
import { ref as ref2, watch as watch3 } from "vue";
|
|
259
|
+
import { extendRef } from "@vueuse/core";
|
|
260
|
+
function extendSelected(array, fieldName) {
|
|
261
|
+
watch3(
|
|
262
|
+
array,
|
|
263
|
+
(items) => {
|
|
264
|
+
for (const item of items) {
|
|
265
|
+
if (typeof item[fieldName] === "undefined")
|
|
266
|
+
extendRef(item, { [fieldName]: ref2(false) });
|
|
267
|
+
}
|
|
268
|
+
},
|
|
269
|
+
{ immediate: true, flush: "sync" }
|
|
270
|
+
);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// src/composition/useSelectedMultiple/index.ts
|
|
274
|
+
function useSelectedMultiple(array, options = {}) {
|
|
275
|
+
const { fieldName = "select", disabled } = options;
|
|
276
|
+
extendSelected(array, fieldName);
|
|
277
|
+
const selected = computed2(() => unref3(array).filter((item) => item[fieldName]));
|
|
278
|
+
const isSelectedAll = computed2({
|
|
279
|
+
get: () => {
|
|
280
|
+
var _a;
|
|
281
|
+
return !((_a = selected.value) == null ? void 0 : _a.length) && !unref3(array).some((item) => !item[fieldName]);
|
|
282
|
+
},
|
|
283
|
+
set: (value) => unref3(array).forEach((item, index) => {
|
|
284
|
+
if (!(disabled == null ? void 0 : disabled(item, index)))
|
|
285
|
+
item[fieldName] = value;
|
|
286
|
+
})
|
|
287
|
+
});
|
|
288
|
+
const isSelected = computed2(() => !!unref3(array).some((item) => item[fieldName]));
|
|
289
|
+
const isIndeterminate = computed2(() => {
|
|
290
|
+
const selectCount = selected.value.length;
|
|
291
|
+
return selectCount > 0 && selectCount < unref3(array).length;
|
|
292
|
+
});
|
|
293
|
+
return { selected, isSelectedAll, isSelected, isIndeterminate };
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// src/composition/useSelectedSingle/index.ts
|
|
297
|
+
import { computed as computed3, ref as ref3, unref as unref4, watch as watch4 } from "vue";
|
|
298
|
+
function useSelectedSingle(array, options = {}) {
|
|
299
|
+
var _a, _b;
|
|
300
|
+
const fieldName = (_a = options.fieldName) != null ? _a : "select";
|
|
301
|
+
const required = (_b = options.required) != null ? _b : false;
|
|
302
|
+
extendSelected(array, fieldName);
|
|
303
|
+
const SELECTED_SINGLE_KEY = "selected_single_key";
|
|
304
|
+
const isLocked = ref3(false);
|
|
305
|
+
const isSelected = computed3(() => !!unref4(array).some((item) => item.select));
|
|
306
|
+
if (required) {
|
|
307
|
+
const recover = (bool) => {
|
|
308
|
+
const index = required === true ? 0 : required;
|
|
309
|
+
if (!bool && unref4(array).length > 0)
|
|
310
|
+
unref4(array)[index][fieldName] = true;
|
|
311
|
+
};
|
|
312
|
+
watch4(isSelected, recover, { flush: "sync", immediate: true });
|
|
313
|
+
}
|
|
314
|
+
const itemChange = (neglect) => {
|
|
315
|
+
if (isLocked.value)
|
|
316
|
+
return;
|
|
317
|
+
isLocked.value = true;
|
|
318
|
+
const _array = unref4(array);
|
|
319
|
+
const _value = !_array[neglect][fieldName];
|
|
320
|
+
if (required && !_value)
|
|
321
|
+
_array[neglect][fieldName] = true;
|
|
322
|
+
_array.forEach((target, index) => {
|
|
323
|
+
if (neglect === index)
|
|
324
|
+
return void 0;
|
|
325
|
+
if (!target[fieldName])
|
|
326
|
+
return void 0;
|
|
327
|
+
target[fieldName] = false;
|
|
328
|
+
});
|
|
329
|
+
isLocked.value = false;
|
|
330
|
+
};
|
|
331
|
+
const targetEffect = (target, index) => {
|
|
332
|
+
if (!target[SELECTED_SINGLE_KEY]) {
|
|
333
|
+
return watch4(
|
|
334
|
+
() => target[fieldName],
|
|
335
|
+
() => itemChange(index),
|
|
336
|
+
{ flush: "sync" }
|
|
337
|
+
);
|
|
338
|
+
}
|
|
339
|
+
Object.defineProperty(target, SELECTED_SINGLE_KEY, { value: true });
|
|
340
|
+
};
|
|
341
|
+
watch4(
|
|
342
|
+
array,
|
|
343
|
+
() => {
|
|
344
|
+
unref4(array).forEach(targetEffect);
|
|
345
|
+
},
|
|
346
|
+
{ immediate: true, flush: "sync" }
|
|
347
|
+
);
|
|
348
|
+
const selected = computed3(() => unref4(array).find((v) => v[fieldName]));
|
|
349
|
+
return { selected, isSelected };
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// src/utils/index.ts
|
|
353
|
+
import { computed as computed4, h as h3, render } from "vue-demi";
|
|
354
|
+
function ehr(component, tag) {
|
|
355
|
+
const container = document.createElement(tag || "dev");
|
|
356
|
+
render(h3(component), container);
|
|
357
|
+
return container;
|
|
358
|
+
}
|
|
359
|
+
function propertyToRef(data, prop) {
|
|
360
|
+
return computed4({
|
|
361
|
+
get() {
|
|
362
|
+
return data[prop];
|
|
363
|
+
},
|
|
364
|
+
set(v) {
|
|
365
|
+
data[prop] = v;
|
|
366
|
+
}
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
export {
|
|
370
|
+
CollapseTransition,
|
|
371
|
+
Field,
|
|
372
|
+
ehr,
|
|
373
|
+
propertyToRef,
|
|
374
|
+
syncElementSize,
|
|
375
|
+
syncElementSyncScroll,
|
|
376
|
+
useCheckedState,
|
|
377
|
+
useSelectedMultiple,
|
|
378
|
+
useSelectedSingle,
|
|
379
|
+
useServerPagination
|
|
380
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@hairy/vue-lib",
|
|
3
|
+
"version": "1.3.16",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"main": "./dist/index.cjs",
|
|
6
|
+
"publishConfig": {
|
|
7
|
+
"jsdelivr": "./dist/index.iife.min.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist"
|
|
11
|
+
],
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"@vueuse/core": "^8.5.0",
|
|
14
|
+
"css-render": "^0.15.12",
|
|
15
|
+
"lodash": "^4",
|
|
16
|
+
"vue": "^3",
|
|
17
|
+
"vue-demi": "^0.14.5",
|
|
18
|
+
"@hairy/utils": "0.7.3"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@types/lodash": "^4"
|
|
22
|
+
},
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "ptsup src/index.ts --dts"
|
|
25
|
+
},
|
|
26
|
+
"module": "./dist/index.mjs",
|
|
27
|
+
"types": "./dist/index.d.ts",
|
|
28
|
+
"unpkg": "./dist/index.iife.min.js",
|
|
29
|
+
"exports": {
|
|
30
|
+
".": {
|
|
31
|
+
"import": "./dist/index.mjs",
|
|
32
|
+
"require": "./dist/index.cjs",
|
|
33
|
+
"types": "./dist/index.d.ts"
|
|
34
|
+
},
|
|
35
|
+
"./*": "./*"
|
|
36
|
+
}
|
|
37
|
+
}
|