@sdata/web-vue 4.0.0 → 4.1.0
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/sd.css +71 -0
- package/dist/sd.min.css +2 -2
- package/es/badge/badge.vue.d.ts +2 -0
- package/es/badge/badge.vue_vue_type_script_setup_true_lang.js +19 -4
- package/es/badge/index.d.ts +3 -0
- package/es/components.d.ts +2 -0
- package/es/index.css +71 -0
- package/es/index.d.ts +2 -0
- package/es/index.js +4 -1
- package/es/index.scss +1 -0
- package/es/number-flow/continuous.d.ts +2 -0
- package/es/number-flow/continuous.js +7 -0
- package/es/number-flow/formatter.d.ts +15 -0
- package/es/number-flow/formatter.js +54 -0
- package/es/number-flow/group-key.d.ts +11 -0
- package/es/number-flow/group-key.js +4 -0
- package/es/number-flow/index.d.ts +63 -0
- package/es/number-flow/index.js +15 -0
- package/es/number-flow/number-flow-group.js +5 -0
- package/es/number-flow/number-flow-group.vue.d.ts +12 -0
- package/es/number-flow/number-flow-group.vue_vue_type_script_setup_true_lang.js +58 -0
- package/es/number-flow/number-flow.js +5 -0
- package/es/number-flow/number-flow.vue.d.ts +20 -0
- package/es/number-flow/number-flow.vue_vue_type_script_setup_true_lang.js +284 -0
- package/es/number-flow/style/css.js +2 -0
- package/es/number-flow/style/index.css +85 -0
- package/es/number-flow/style/index.d.ts +2 -0
- package/es/number-flow/style/index.js +2 -0
- package/es/number-flow/style/index.scss +93 -0
- package/es/number-flow/style/token.scss +5 -0
- package/es/number-flow/types.d.ts +46 -0
- package/es/number-flow/use-can-animate.d.ts +4 -0
- package/es/number-flow/use-can-animate.js +30 -0
- package/es/rich-text-editor/index.d.ts +3 -3
- package/es/rich-text-editor/rich-text-editor.vue.d.ts +1 -1
- package/es/sd-vue.js +3 -0
- package/es/statistic/countdown.vue.d.ts +9 -0
- package/es/statistic/countdown.vue_vue_type_script_setup_true_lang.js +29 -2
- package/es/statistic/index.d.ts +15 -0
- package/es/statistic/statistic.vue.d.ts +3 -3
- package/es/statistic/statistic.vue_vue_type_script_setup_true_lang.js +31 -62
- package/es/statistic/style/index.css +3 -0
- package/es/statistic/style/index.scss +5 -0
- package/json/vetur-attributes.json +8 -0
- package/json/vetur-tags.json +9 -1
- package/json/web-types.json +29 -1
- package/package.json +1 -1
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
import _objectSpread2 from "../_virtual/_@oxc-project_runtime@0.142.0/helpers/esm/objectSpread2.js";
|
|
2
|
+
import { getPrefixCls } from "../_utils/global-config.js";
|
|
3
|
+
import _asyncToGenerator from "../_virtual/_@oxc-project_runtime@0.142.0/helpers/esm/asyncToGenerator.js";
|
|
4
|
+
import { GROUP_KEY } from "./group-key.js";
|
|
5
|
+
import { formatNumberFlow } from "./formatter.js";
|
|
6
|
+
import { useCanAnimate } from "./use-can-animate.js";
|
|
7
|
+
import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, defineComponent, inject, nextTick, normalizeClass, onBeforeUnmount, onMounted, openBlock, renderList, renderSlot, resolveDynamicComponent, shallowRef, toDisplayString, unref, useSlots, useTemplateRef, watch, withCtx } from "vue";
|
|
8
|
+
//#region components/number-flow/number-flow.vue?vue&type=script&setup=true&lang.ts
|
|
9
|
+
var _hoisted_1 = ["data-number-flow-id", "aria-label"];
|
|
10
|
+
var _hoisted_2 = ["data-number-flow-part"];
|
|
11
|
+
var number_flow_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent(_objectSpread2(_objectSpread2({}, { name: "NumberFlow" }), {}, {
|
|
12
|
+
__name: "number-flow",
|
|
13
|
+
props: {
|
|
14
|
+
value: {},
|
|
15
|
+
locales: {},
|
|
16
|
+
format: {},
|
|
17
|
+
prefix: {},
|
|
18
|
+
suffix: {},
|
|
19
|
+
trend: {
|
|
20
|
+
type: [Number, Function],
|
|
21
|
+
default: (oldValue, newValue) => Math.sign(newValue - oldValue)
|
|
22
|
+
},
|
|
23
|
+
plugins: {},
|
|
24
|
+
animated: {
|
|
25
|
+
type: Boolean,
|
|
26
|
+
default: true
|
|
27
|
+
},
|
|
28
|
+
transformTiming: { default: () => (() => ({
|
|
29
|
+
duration: 900,
|
|
30
|
+
easing: "cubic-bezier(0.16, 1, 0.3, 1)"
|
|
31
|
+
})) },
|
|
32
|
+
spinTiming: {},
|
|
33
|
+
opacityTiming: { default: () => (() => ({
|
|
34
|
+
duration: 450,
|
|
35
|
+
easing: "ease-out"
|
|
36
|
+
})) },
|
|
37
|
+
respectMotionPreference: {
|
|
38
|
+
type: Boolean,
|
|
39
|
+
default: true
|
|
40
|
+
},
|
|
41
|
+
digits: {},
|
|
42
|
+
willChange: {
|
|
43
|
+
type: Boolean,
|
|
44
|
+
default: false
|
|
45
|
+
},
|
|
46
|
+
nonce: {}
|
|
47
|
+
},
|
|
48
|
+
emits: ["animationsstart", "animationsfinish"],
|
|
49
|
+
setup(__props, { expose: __expose, emit: __emit }) {
|
|
50
|
+
const emit = __emit;
|
|
51
|
+
const prefixCls = getPrefixCls("number-flow");
|
|
52
|
+
const slots = useSlots();
|
|
53
|
+
const rootRef = useTemplateRef("rootRef");
|
|
54
|
+
const styleScope = shallowRef();
|
|
55
|
+
onMounted(() => {
|
|
56
|
+
styleScope.value = `sd-number-flow-${crypto.randomUUID()}`;
|
|
57
|
+
});
|
|
58
|
+
const numberFormatter = computed(() => new Intl.NumberFormat(__props.locales, __props.format));
|
|
59
|
+
function formatData(val) {
|
|
60
|
+
return formatNumberFlow(val, numberFormatter.value, slots.prefix ? void 0 : __props.prefix, slots.suffix ? void 0 : __props.suffix);
|
|
61
|
+
}
|
|
62
|
+
const previousData = shallowRef(formatData(__props.value));
|
|
63
|
+
const currentValue = computed(() => __props.value);
|
|
64
|
+
const currentData = computed(() => formatData(__props.value));
|
|
65
|
+
const animationPhase = shallowRef("idle");
|
|
66
|
+
const isAnimating = computed(() => animationPhase.value === "animating");
|
|
67
|
+
let animationVersion = 0;
|
|
68
|
+
let finishTimer;
|
|
69
|
+
const resolvedTransformTiming = computed(() => typeof __props.transformTiming === "function" ? __props.transformTiming() : __props.transformTiming);
|
|
70
|
+
const resolvedOpacityTiming = computed(() => typeof __props.opacityTiming === "function" ? __props.opacityTiming() : __props.opacityTiming);
|
|
71
|
+
const transformDuration = computed(() => typeof resolvedTransformTiming.value.duration === "number" ? resolvedTransformTiming.value.duration : 900);
|
|
72
|
+
const transformEasing = computed(() => {
|
|
73
|
+
var _resolvedTransformTim, _resolvedTransformTim2;
|
|
74
|
+
return (_resolvedTransformTim = (_resolvedTransformTim2 = resolvedTransformTiming.value.easing) === null || _resolvedTransformTim2 === void 0 ? void 0 : _resolvedTransformTim2.toString()) !== null && _resolvedTransformTim !== void 0 ? _resolvedTransformTim : "cubic-bezier(0.16, 1, 0.3, 1)";
|
|
75
|
+
});
|
|
76
|
+
const spinDuration = computed(() => {
|
|
77
|
+
if (__props.spinTiming && typeof __props.spinTiming.duration === "number") return __props.spinTiming.duration;
|
|
78
|
+
return transformDuration.value;
|
|
79
|
+
});
|
|
80
|
+
const spinEasing = computed(() => {
|
|
81
|
+
var _props$spinTiming;
|
|
82
|
+
if ((_props$spinTiming = __props.spinTiming) === null || _props$spinTiming === void 0 ? void 0 : _props$spinTiming.easing) return __props.spinTiming.easing.toString();
|
|
83
|
+
return transformEasing.value;
|
|
84
|
+
});
|
|
85
|
+
const opacityDuration = computed(() => typeof resolvedOpacityTiming.value.duration === "number" ? resolvedOpacityTiming.value.duration : 450);
|
|
86
|
+
const motionCanAnimate = useCanAnimate({ respectMotionPreference: () => __props.respectMotionPreference });
|
|
87
|
+
const canAnimate = computed(() => __props.animated && motionCanAnimate.value);
|
|
88
|
+
const computedTrend = computed(() => typeof __props.trend === "function" ? __props.trend(previousData.value.value, currentData.value.value) : __props.trend);
|
|
89
|
+
const classes = computed(() => [prefixCls, {
|
|
90
|
+
[`${prefixCls}-animated`]: canAnimate.value,
|
|
91
|
+
[`${prefixCls}-prepared`]: animationPhase.value === "prepared",
|
|
92
|
+
[`${prefixCls}-animating`]: isAnimating.value,
|
|
93
|
+
[`${prefixCls}-will-change`]: __props.willChange
|
|
94
|
+
}]);
|
|
95
|
+
function sanitizeDuration(duration) {
|
|
96
|
+
return Number.isFinite(duration) && duration >= 0 ? duration : 0;
|
|
97
|
+
}
|
|
98
|
+
function sanitizeEasing(easing) {
|
|
99
|
+
return /^[a-zA-Z0-9(),.\s+-]+$/.test(easing) ? easing : "linear";
|
|
100
|
+
}
|
|
101
|
+
const dynamicStyles = computed(() => {
|
|
102
|
+
if (!styleScope.value) return "";
|
|
103
|
+
const rootSelector = `[data-number-flow-id="${styleScope.value}"]`;
|
|
104
|
+
const rules = [`${rootSelector}{--sd-number-flow-duration:${sanitizeDuration(transformDuration.value)}ms;--sd-number-flow-easing:${sanitizeEasing(transformEasing.value)};--sd-number-flow-spin-duration:${sanitizeDuration(spinDuration.value)}ms;--sd-number-flow-spin-easing:${sanitizeEasing(spinEasing.value)};--sd-number-flow-opacity-duration:${sanitizeDuration(opacityDuration.value)}ms}`];
|
|
105
|
+
currentData.value.parts.forEach((part, index) => {
|
|
106
|
+
if (part.digit === void 0) return;
|
|
107
|
+
const delta = getDigitDelta(part);
|
|
108
|
+
const distance = Math.abs(delta);
|
|
109
|
+
rules.push(`${rootSelector} [data-number-flow-part="${index}"]{--sd-number-flow-start:${delta < 0 ? -distance : 0};--sd-number-flow-end:${delta > 0 ? -distance : 0}}`);
|
|
110
|
+
});
|
|
111
|
+
return rules.join("");
|
|
112
|
+
});
|
|
113
|
+
function getPreviousDigit(part) {
|
|
114
|
+
var _previousData$value$p, _previousData$value$p2;
|
|
115
|
+
return (_previousData$value$p = (_previousData$value$p2 = previousData.value.parts.find((candidate) => candidate.key === part.key)) === null || _previousData$value$p2 === void 0 ? void 0 : _previousData$value$p2.digit) !== null && _previousData$value$p !== void 0 ? _previousData$value$p : part.digit;
|
|
116
|
+
}
|
|
117
|
+
const highestChangedPosition = computed(() => {
|
|
118
|
+
const previousDigits = new Map(previousData.value.parts.filter((part) => part.digit !== void 0).map((part) => [part.key, part]));
|
|
119
|
+
const changedPositions = currentData.value.parts.flatMap((part) => {
|
|
120
|
+
var _part$position;
|
|
121
|
+
if (part.digit === void 0) return [];
|
|
122
|
+
const previous = previousDigits.get(part.key);
|
|
123
|
+
return (previous === null || previous === void 0 ? void 0 : previous.digit) === part.digit ? [] : [(_part$position = part.position) !== null && _part$position !== void 0 ? _part$position : 0];
|
|
124
|
+
});
|
|
125
|
+
return changedPositions.length === 0 ? void 0 : Math.max(...changedPositions);
|
|
126
|
+
});
|
|
127
|
+
function getDigitDelta(part) {
|
|
128
|
+
var _props$digits$max, _props$digits, _part$position2, _part$position3, _props$plugins;
|
|
129
|
+
const current = part.digit;
|
|
130
|
+
const previous = getPreviousDigit(part);
|
|
131
|
+
const length = ((_props$digits$max = (_props$digits = __props.digits) === null || _props$digits === void 0 || (_props$digits = _props$digits[(_part$position2 = part.position) !== null && _part$position2 !== void 0 ? _part$position2 : 0]) === null || _props$digits === void 0 ? void 0 : _props$digits.max) !== null && _props$digits$max !== void 0 ? _props$digits$max : 9) + 1;
|
|
132
|
+
const context = {
|
|
133
|
+
position: (_part$position3 = part.position) !== null && _part$position3 !== void 0 ? _part$position3 : 0,
|
|
134
|
+
length,
|
|
135
|
+
trend: computedTrend.value,
|
|
136
|
+
highestChangedPosition: highestChangedPosition.value
|
|
137
|
+
};
|
|
138
|
+
for (const plugin of (_props$plugins = __props.plugins) !== null && _props$plugins !== void 0 ? _props$plugins : []) {
|
|
139
|
+
var _plugin$getDelta;
|
|
140
|
+
const delta = (_plugin$getDelta = plugin.getDelta) === null || _plugin$getDelta === void 0 ? void 0 : _plugin$getDelta.call(plugin, current, previous, context);
|
|
141
|
+
if (delta !== void 0) return delta;
|
|
142
|
+
}
|
|
143
|
+
const difference = current - previous;
|
|
144
|
+
if (computedTrend.value < 0 && current > previous) return current - length - previous;
|
|
145
|
+
if (computedTrend.value > 0 && current < previous) return length - previous + current;
|
|
146
|
+
return difference;
|
|
147
|
+
}
|
|
148
|
+
function getDigitSequence(part) {
|
|
149
|
+
var _props$digits$max2, _props$digits2, _part$position4;
|
|
150
|
+
const current = part.digit;
|
|
151
|
+
const previous = getPreviousDigit(part);
|
|
152
|
+
const delta = getDigitDelta(part);
|
|
153
|
+
if (animationPhase.value === "idle" || delta === 0) return [{
|
|
154
|
+
key: `current-${current}`,
|
|
155
|
+
value: current
|
|
156
|
+
}];
|
|
157
|
+
const length = ((_props$digits$max2 = (_props$digits2 = __props.digits) === null || _props$digits2 === void 0 || (_props$digits2 = _props$digits2[(_part$position4 = part.position) !== null && _part$position4 !== void 0 ? _part$position4 : 0]) === null || _props$digits2 === void 0 ? void 0 : _props$digits2.max) !== null && _props$digits$max2 !== void 0 ? _props$digits$max2 : 9) + 1;
|
|
158
|
+
const start = delta > 0 ? previous : current;
|
|
159
|
+
return Array.from({ length: Math.abs(delta) + 1 }, (_, index) => ({
|
|
160
|
+
key: `step-${index}`,
|
|
161
|
+
value: (start + index) % length
|
|
162
|
+
}));
|
|
163
|
+
}
|
|
164
|
+
function finishAnimation(version = animationVersion) {
|
|
165
|
+
if (version !== animationVersion || animationPhase.value === "idle") return;
|
|
166
|
+
clearTimeout(finishTimer);
|
|
167
|
+
finishTimer = void 0;
|
|
168
|
+
previousData.value = currentData.value;
|
|
169
|
+
animationPhase.value = "idle";
|
|
170
|
+
emit("animationsfinish");
|
|
171
|
+
}
|
|
172
|
+
const group = inject(GROUP_KEY, void 0);
|
|
173
|
+
function prepareAnimation(oldData, data, force = false) {
|
|
174
|
+
var _props$plugins2;
|
|
175
|
+
const version = ++animationVersion;
|
|
176
|
+
clearTimeout(finishTimer);
|
|
177
|
+
finishTimer = void 0;
|
|
178
|
+
previousData.value = oldData;
|
|
179
|
+
(_props$plugins2 = __props.plugins) === null || _props$plugins2 === void 0 || _props$plugins2.forEach((plugin) => {
|
|
180
|
+
var _plugin$onUpdate;
|
|
181
|
+
return (_plugin$onUpdate = plugin.onUpdate) === null || _plugin$onUpdate === void 0 ? void 0 : _plugin$onUpdate.call(plugin, {
|
|
182
|
+
value: data.value,
|
|
183
|
+
previousValue: oldData.value,
|
|
184
|
+
trend: computedTrend.value
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
if (!canAnimate.value || !force && data.value === oldData.value) {
|
|
188
|
+
previousData.value = data;
|
|
189
|
+
animationPhase.value = "idle";
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
animationPhase.value = "prepared";
|
|
193
|
+
return version;
|
|
194
|
+
}
|
|
195
|
+
function commitAnimationStart(version) {
|
|
196
|
+
var _rootRef$value;
|
|
197
|
+
if (version !== animationVersion || animationPhase.value !== "prepared") return false;
|
|
198
|
+
(_rootRef$value = rootRef.value) === null || _rootRef$value === void 0 || _rootRef$value.getBoundingClientRect();
|
|
199
|
+
return true;
|
|
200
|
+
}
|
|
201
|
+
function startAnimation(version) {
|
|
202
|
+
if (version !== animationVersion || animationPhase.value !== "prepared") return;
|
|
203
|
+
animationPhase.value = "animating";
|
|
204
|
+
emit("animationsstart");
|
|
205
|
+
finishTimer = setTimeout(() => finishAnimation(version), spinDuration.value + 50);
|
|
206
|
+
}
|
|
207
|
+
if (group) {
|
|
208
|
+
const unregister = group.register({
|
|
209
|
+
value: currentValue,
|
|
210
|
+
prepare: () => prepareAnimation(previousData.value, currentData.value, true),
|
|
211
|
+
commit: commitAnimationStart,
|
|
212
|
+
start: startAnimation
|
|
213
|
+
});
|
|
214
|
+
onBeforeUnmount(unregister);
|
|
215
|
+
} else watch(currentValue, function() {
|
|
216
|
+
var _ref = _asyncToGenerator(function* (data, oldData) {
|
|
217
|
+
const version = prepareAnimation(formatData(oldData), formatData(data));
|
|
218
|
+
if (version === void 0) return;
|
|
219
|
+
yield nextTick();
|
|
220
|
+
if (!commitAnimationStart(version)) return;
|
|
221
|
+
startAnimation(version);
|
|
222
|
+
});
|
|
223
|
+
return function(_x, _x2) {
|
|
224
|
+
return _ref.apply(this, arguments);
|
|
225
|
+
};
|
|
226
|
+
}(), { flush: "pre" });
|
|
227
|
+
onBeforeUnmount(() => clearTimeout(finishTimer));
|
|
228
|
+
__expose({ get el() {
|
|
229
|
+
return rootRef.value;
|
|
230
|
+
} });
|
|
231
|
+
return (_ctx, _cache) => {
|
|
232
|
+
return openBlock(), createElementBlock("span", {
|
|
233
|
+
ref_key: "rootRef",
|
|
234
|
+
ref: rootRef,
|
|
235
|
+
class: normalizeClass(classes.value),
|
|
236
|
+
"data-number-flow-id": styleScope.value,
|
|
237
|
+
role: "img",
|
|
238
|
+
"aria-label": currentData.value.valueAsString
|
|
239
|
+
}, [
|
|
240
|
+
(openBlock(), createBlock(resolveDynamicComponent("style"), { nonce: __props.nonce }, {
|
|
241
|
+
default: withCtx(() => [createTextVNode(toDisplayString(dynamicStyles.value), 1)]),
|
|
242
|
+
_: 1
|
|
243
|
+
}, 8, ["nonce"])),
|
|
244
|
+
_ctx.$slots.prefix ? (openBlock(), createElementBlock("span", {
|
|
245
|
+
key: 0,
|
|
246
|
+
class: normalizeClass(`${unref(prefixCls)}-custom-prefix`),
|
|
247
|
+
"aria-hidden": "true"
|
|
248
|
+
}, [renderSlot(_ctx.$slots, "prefix")], 2)) : createCommentVNode("", true),
|
|
249
|
+
createElementVNode("span", {
|
|
250
|
+
class: normalizeClass(`${unref(prefixCls)}-content`),
|
|
251
|
+
"aria-hidden": "true"
|
|
252
|
+
}, [(openBlock(true), createElementBlock(Fragment, null, renderList(currentData.value.parts, (part, partIndex) => {
|
|
253
|
+
return openBlock(), createElementBlock("span", {
|
|
254
|
+
key: part.key,
|
|
255
|
+
"data-number-flow-part": partIndex,
|
|
256
|
+
class: normalizeClass([
|
|
257
|
+
`${unref(prefixCls)}-part`,
|
|
258
|
+
`${unref(prefixCls)}-${part.type}`,
|
|
259
|
+
{ [`${unref(prefixCls)}-digit`]: part.digit !== void 0 }
|
|
260
|
+
])
|
|
261
|
+
}, [part.digit !== void 0 ? (openBlock(), createElementBlock("span", {
|
|
262
|
+
key: 0,
|
|
263
|
+
class: normalizeClass(`${unref(prefixCls)}-digit-track`)
|
|
264
|
+
}, [(openBlock(true), createElementBlock(Fragment, null, renderList(getDigitSequence(part), (digit) => {
|
|
265
|
+
return openBlock(), createElementBlock("span", {
|
|
266
|
+
key: digit.key,
|
|
267
|
+
class: normalizeClass(`${unref(prefixCls)}-digit-value`)
|
|
268
|
+
}, toDisplayString(digit.value), 3);
|
|
269
|
+
}), 128))], 2)) : (openBlock(), createElementBlock("span", {
|
|
270
|
+
key: 1,
|
|
271
|
+
class: normalizeClass(`${unref(prefixCls)}-symbol`)
|
|
272
|
+
}, toDisplayString(part.value), 3))], 10, _hoisted_2);
|
|
273
|
+
}), 128))], 2),
|
|
274
|
+
_ctx.$slots.suffix ? (openBlock(), createElementBlock("span", {
|
|
275
|
+
key: 1,
|
|
276
|
+
class: normalizeClass(`${unref(prefixCls)}-custom-suffix`),
|
|
277
|
+
"aria-hidden": "true"
|
|
278
|
+
}, [renderSlot(_ctx.$slots, "suffix")], 2)) : createCommentVNode("", true)
|
|
279
|
+
], 10, _hoisted_1);
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
}));
|
|
283
|
+
//#endregion
|
|
284
|
+
export { number_flow_vue_vue_type_script_setup_true_lang_default as default };
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/******** borderSize *******/
|
|
2
|
+
/******** borderStyle *******/
|
|
3
|
+
/******** radius *******/
|
|
4
|
+
/******** shadow distance *******/
|
|
5
|
+
/******** size *******/
|
|
6
|
+
/******** spacing *******/
|
|
7
|
+
/******** shadow *******/
|
|
8
|
+
/******** opacity *******/
|
|
9
|
+
/******** fontSize *******/
|
|
10
|
+
/******** fontWeight ********/
|
|
11
|
+
/******** Primary *******/
|
|
12
|
+
/******** success *******/
|
|
13
|
+
/******** warning *******/
|
|
14
|
+
/******** danger *******/
|
|
15
|
+
/******** link *******/
|
|
16
|
+
/******** radius *******/
|
|
17
|
+
/********* icon hover *********/
|
|
18
|
+
.sd-number-flow {
|
|
19
|
+
display: inline-flex;
|
|
20
|
+
align-items: baseline;
|
|
21
|
+
line-height: 1;
|
|
22
|
+
direction: ltr;
|
|
23
|
+
white-space: nowrap;
|
|
24
|
+
isolation: isolate;
|
|
25
|
+
}
|
|
26
|
+
.sd-number-flow-content, .sd-number-flow-part, .sd-number-flow-digit-track, .sd-number-flow-digit-value, .sd-number-flow-symbol {
|
|
27
|
+
display: inline-block;
|
|
28
|
+
}
|
|
29
|
+
.sd-number-flow-content {
|
|
30
|
+
margin: -0.25em -0.2em;
|
|
31
|
+
padding: 0.25em 0.2em;
|
|
32
|
+
overflow: hidden;
|
|
33
|
+
}
|
|
34
|
+
.sd-number-flow-part {
|
|
35
|
+
position: relative;
|
|
36
|
+
vertical-align: bottom;
|
|
37
|
+
}
|
|
38
|
+
.sd-number-flow-digit {
|
|
39
|
+
height: 1em;
|
|
40
|
+
overflow: hidden;
|
|
41
|
+
}
|
|
42
|
+
.sd-number-flow-digit-track {
|
|
43
|
+
display: flex;
|
|
44
|
+
flex-direction: column;
|
|
45
|
+
height: 1em;
|
|
46
|
+
transform: translateY(calc(1em * var(--sd-number-flow-start)));
|
|
47
|
+
}
|
|
48
|
+
.sd-number-flow-digit-value {
|
|
49
|
+
flex: 0 0 1em;
|
|
50
|
+
height: 1em;
|
|
51
|
+
line-height: 1;
|
|
52
|
+
text-align: center;
|
|
53
|
+
font-variant-numeric: tabular-nums;
|
|
54
|
+
}
|
|
55
|
+
.sd-number-flow-prepared .sd-number-flow-digit-track {
|
|
56
|
+
transition: none;
|
|
57
|
+
}
|
|
58
|
+
.sd-number-flow-animating .sd-number-flow-digit-track {
|
|
59
|
+
transform: translateY(calc(1em * var(--sd-number-flow-end)));
|
|
60
|
+
transition: transform var(--sd-number-flow-spin-duration, var(--sd-number-flow-duration)) var(--sd-number-flow-spin-easing, var(--sd-number-flow-easing)), opacity var(--sd-number-flow-opacity-duration) ease-out;
|
|
61
|
+
}
|
|
62
|
+
.sd-number-flow-symbol {
|
|
63
|
+
white-space: pre;
|
|
64
|
+
}
|
|
65
|
+
.sd-number-flow-will-change :is(.sd-number-flow-content, .sd-number-flow-part, .sd-number-flow-digit-track, .sd-number-flow-symbol) {
|
|
66
|
+
will-change: transform;
|
|
67
|
+
}
|
|
68
|
+
.sd-number-flow-custom-prefix {
|
|
69
|
+
margin-right: 4px;
|
|
70
|
+
}
|
|
71
|
+
.sd-number-flow-custom-suffix {
|
|
72
|
+
margin-left: 4px;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.sd-number-flow-group {
|
|
76
|
+
display: inline-flex;
|
|
77
|
+
gap: 4px;
|
|
78
|
+
align-items: baseline;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
@media (prefers-reduced-motion: reduce) {
|
|
82
|
+
.sd-number-flow-digit-track {
|
|
83
|
+
transition: none;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
@use 'sass:string';
|
|
2
|
+
@use '@style/theme/index.scss' as theme;
|
|
3
|
+
@use '@components/number-flow/style/token.scss' as *;
|
|
4
|
+
|
|
5
|
+
$number-flow-prefix-cls: string.unquote('#{theme.$prefix}-number-flow');
|
|
6
|
+
|
|
7
|
+
.#{$number-flow-prefix-cls} {
|
|
8
|
+
display: inline-flex;
|
|
9
|
+
align-items: baseline;
|
|
10
|
+
line-height: 1;
|
|
11
|
+
direction: ltr;
|
|
12
|
+
white-space: nowrap;
|
|
13
|
+
isolation: isolate;
|
|
14
|
+
|
|
15
|
+
&-content,
|
|
16
|
+
&-part,
|
|
17
|
+
&-digit-track,
|
|
18
|
+
&-digit-value,
|
|
19
|
+
&-symbol {
|
|
20
|
+
display: inline-block;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
&-content {
|
|
24
|
+
margin: calc(-1 * $number-flow-mask-height) calc(-1 * $number-flow-mask-width);
|
|
25
|
+
padding: $number-flow-mask-height $number-flow-mask-width;
|
|
26
|
+
overflow: hidden;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
&-part {
|
|
30
|
+
position: relative;
|
|
31
|
+
vertical-align: bottom;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
&-digit {
|
|
35
|
+
height: 1em;
|
|
36
|
+
overflow: hidden;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
&-digit-track {
|
|
40
|
+
display: flex;
|
|
41
|
+
flex-direction: column;
|
|
42
|
+
height: 1em;
|
|
43
|
+
transform: translateY(calc(1em * var(--sd-number-flow-start)));
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
&-digit-value {
|
|
47
|
+
flex: 0 0 1em;
|
|
48
|
+
height: 1em;
|
|
49
|
+
line-height: 1;
|
|
50
|
+
text-align: center;
|
|
51
|
+
font-variant-numeric: tabular-nums;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
&-prepared &-digit-track {
|
|
55
|
+
transition: none;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
&-animating &-digit-track {
|
|
59
|
+
transform: translateY(calc(1em * var(--sd-number-flow-end)));
|
|
60
|
+
transition:
|
|
61
|
+
transform var(--sd-number-flow-spin-duration, var(--sd-number-flow-duration))
|
|
62
|
+
var(--sd-number-flow-spin-easing, var(--sd-number-flow-easing)),
|
|
63
|
+
opacity var(--sd-number-flow-opacity-duration) ease-out;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
&-symbol {
|
|
67
|
+
white-space: pre;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
&-will-change :is(&-content, &-part, &-digit-track, &-symbol) {
|
|
71
|
+
will-change: transform;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
&-custom-prefix {
|
|
75
|
+
margin-right: $number-flow-gap;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
&-custom-suffix {
|
|
79
|
+
margin-left: $number-flow-gap;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.#{$number-flow-prefix-cls}-group {
|
|
84
|
+
display: inline-flex;
|
|
85
|
+
gap: $number-flow-gap;
|
|
86
|
+
align-items: baseline;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
@media (prefers-reduced-motion: reduce) {
|
|
90
|
+
.#{$number-flow-prefix-cls}-digit-track {
|
|
91
|
+
transition: none;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { CSSProperties } from 'vue';
|
|
2
|
+
export type NumberFlowValue = number | string;
|
|
3
|
+
export type NumberFlowFormat = Omit<Intl.NumberFormatOptions, 'notation'> & {
|
|
4
|
+
notation?: Exclude<Intl.NumberFormatOptions['notation'], 'scientific' | 'engineering'>;
|
|
5
|
+
};
|
|
6
|
+
export type NumberFlowTrend = number | ((oldValue: number, value: number) => number);
|
|
7
|
+
export type NumberFlowDigitOptions = {
|
|
8
|
+
max?: number;
|
|
9
|
+
};
|
|
10
|
+
export type NumberFlowDigits = Record<number, NumberFlowDigitOptions>;
|
|
11
|
+
export interface NumberFlowDigitContext {
|
|
12
|
+
position: number;
|
|
13
|
+
length: number;
|
|
14
|
+
trend: number;
|
|
15
|
+
highestChangedPosition?: number;
|
|
16
|
+
}
|
|
17
|
+
export interface NumberFlowPluginContext {
|
|
18
|
+
value: number;
|
|
19
|
+
previousValue: number;
|
|
20
|
+
trend: number;
|
|
21
|
+
}
|
|
22
|
+
export interface NumberFlowPlugin {
|
|
23
|
+
onUpdate?(context: NumberFlowPluginContext): void;
|
|
24
|
+
getDelta?(value: number, previousValue: number, context: NumberFlowDigitContext): number | void;
|
|
25
|
+
}
|
|
26
|
+
export interface NumberFlowProps {
|
|
27
|
+
value: NumberFlowValue;
|
|
28
|
+
locales?: Intl.LocalesArgument;
|
|
29
|
+
format?: NumberFlowFormat;
|
|
30
|
+
prefix?: string;
|
|
31
|
+
suffix?: string;
|
|
32
|
+
trend?: NumberFlowTrend;
|
|
33
|
+
plugins?: NumberFlowPlugin[];
|
|
34
|
+
animated?: boolean;
|
|
35
|
+
transformTiming?: KeyframeAnimationOptions;
|
|
36
|
+
spinTiming?: KeyframeAnimationOptions;
|
|
37
|
+
opacityTiming?: KeyframeAnimationOptions;
|
|
38
|
+
respectMotionPreference?: boolean;
|
|
39
|
+
digits?: NumberFlowDigits;
|
|
40
|
+
willChange?: boolean;
|
|
41
|
+
nonce?: string;
|
|
42
|
+
}
|
|
43
|
+
export interface NumberFlowExposed {
|
|
44
|
+
el: HTMLElement | null;
|
|
45
|
+
}
|
|
46
|
+
export type NumberFlowStyle = CSSProperties & Record<`--${string}`, string | number>;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { computed, onMounted, shallowRef, toValue, watchEffect } from "vue";
|
|
2
|
+
//#region components/number-flow/use-can-animate.ts
|
|
3
|
+
/**
|
|
4
|
+
* SSR-safe composable that returns whether number-flow animations can run.
|
|
5
|
+
* Respects `prefers-reduced-motion` and listens for changes.
|
|
6
|
+
*/
|
|
7
|
+
function useCanAnimate({ respectMotionPreference = true } = {}) {
|
|
8
|
+
const canAnimate = shallowRef(false);
|
|
9
|
+
const reducedMotion = shallowRef(false);
|
|
10
|
+
const mediaQuery = shallowRef();
|
|
11
|
+
onMounted(() => {
|
|
12
|
+
canAnimate.value = typeof window !== "undefined";
|
|
13
|
+
mediaQuery.value = window.matchMedia("(prefers-reduced-motion: reduce)");
|
|
14
|
+
reducedMotion.value = mediaQuery.value.matches;
|
|
15
|
+
});
|
|
16
|
+
watchEffect((onCleanup) => {
|
|
17
|
+
if (!toValue(respectMotionPreference)) return;
|
|
18
|
+
const onChange = ({ matches }) => {
|
|
19
|
+
reducedMotion.value = matches;
|
|
20
|
+
};
|
|
21
|
+
const query = mediaQuery.value;
|
|
22
|
+
query === null || query === void 0 || query.addEventListener("change", onChange);
|
|
23
|
+
onCleanup(() => {
|
|
24
|
+
query === null || query === void 0 || query.removeEventListener("change", onChange);
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
return computed(() => canAnimate.value && (!toValue(respectMotionPreference) || !reducedMotion.value));
|
|
28
|
+
}
|
|
29
|
+
//#endregion
|
|
30
|
+
export { useCanAnimate };
|
|
@@ -54,8 +54,8 @@ declare const RichTextEditor: {
|
|
|
54
54
|
}, import("vue").PublicProps, {
|
|
55
55
|
classNames: Partial<Record<import("./types").RichTextEditorSemanticType, string>>;
|
|
56
56
|
autoSize: boolean | import("./types").RichTextEditorAutoSize;
|
|
57
|
-
styles: Partial<Record<import("./types").RichTextEditorSemanticType, import("vue").CSSProperties>>;
|
|
58
57
|
plugins: readonly import("./types").RichTextEditorPlugin[];
|
|
58
|
+
styles: Partial<Record<import("./types").RichTextEditorSemanticType, import("vue").CSSProperties>>;
|
|
59
59
|
transformers: readonly import("@lexical/markdown").Transformer[];
|
|
60
60
|
history: boolean;
|
|
61
61
|
historyDelay: number;
|
|
@@ -112,8 +112,8 @@ declare const RichTextEditor: {
|
|
|
112
112
|
}, {}, {}, {}, {
|
|
113
113
|
classNames: Partial<Record<import("./types").RichTextEditorSemanticType, string>>;
|
|
114
114
|
autoSize: boolean | import("./types").RichTextEditorAutoSize;
|
|
115
|
-
styles: Partial<Record<import("./types").RichTextEditorSemanticType, import("vue").CSSProperties>>;
|
|
116
115
|
plugins: readonly import("./types").RichTextEditorPlugin[];
|
|
116
|
+
styles: Partial<Record<import("./types").RichTextEditorSemanticType, import("vue").CSSProperties>>;
|
|
117
117
|
transformers: readonly import("@lexical/markdown").Transformer[];
|
|
118
118
|
history: boolean;
|
|
119
119
|
historyDelay: number;
|
|
@@ -175,8 +175,8 @@ declare const RichTextEditor: {
|
|
|
175
175
|
}, string, {
|
|
176
176
|
classNames: Partial<Record<import("./types").RichTextEditorSemanticType, string>>;
|
|
177
177
|
autoSize: boolean | import("./types").RichTextEditorAutoSize;
|
|
178
|
-
styles: Partial<Record<import("./types").RichTextEditorSemanticType, import("vue").CSSProperties>>;
|
|
179
178
|
plugins: readonly import("./types").RichTextEditorPlugin[];
|
|
179
|
+
styles: Partial<Record<import("./types").RichTextEditorSemanticType, import("vue").CSSProperties>>;
|
|
180
180
|
transformers: readonly import("@lexical/markdown").Transformer[];
|
|
181
181
|
history: boolean;
|
|
182
182
|
historyDelay: number;
|
|
@@ -58,8 +58,8 @@ declare const __VLS_base: import("vue").DefineComponent<RichTextEditorProps, {
|
|
|
58
58
|
}>, {
|
|
59
59
|
classNames: Partial<Record<import("./types").RichTextEditorSemanticType, string>>;
|
|
60
60
|
autoSize: boolean | import("./types").RichTextEditorAutoSize;
|
|
61
|
-
styles: Partial<Record<import("./types").RichTextEditorSemanticType, CSSProperties>>;
|
|
62
61
|
plugins: readonly import("./types").RichTextEditorPlugin[];
|
|
62
|
+
styles: Partial<Record<import("./types").RichTextEditorSemanticType, CSSProperties>>;
|
|
63
63
|
transformers: readonly import("@lexical/markdown").Transformer[];
|
|
64
64
|
history: boolean;
|
|
65
65
|
historyDelay: number;
|
package/es/sd-vue.js
CHANGED
|
@@ -21,6 +21,7 @@ import Popover from "./popover/index.js";
|
|
|
21
21
|
import avatar_group_default from "./avatar/avatar-group.js";
|
|
22
22
|
import Avatar from "./avatar/index.js";
|
|
23
23
|
import BackTop from "./back-top/index.js";
|
|
24
|
+
import NumberFlow, { NumberFlowGroup } from "./number-flow/index.js";
|
|
24
25
|
import Badge from "./badge/index.js";
|
|
25
26
|
import Ellipsis, { PerformantEllipsis } from "./ellipsis/index.js";
|
|
26
27
|
import Link from "./link/index.js";
|
|
@@ -218,6 +219,7 @@ var components = {
|
|
|
218
219
|
Modal,
|
|
219
220
|
ModelSelector,
|
|
220
221
|
Notification,
|
|
222
|
+
NumberFlow,
|
|
221
223
|
Popconfirm,
|
|
222
224
|
Progress,
|
|
223
225
|
QrCode,
|
|
@@ -299,6 +301,7 @@ var SDVue = _objectSpread2(_objectSpread2({}, components), {}, {
|
|
|
299
301
|
SkeletonLine: line_default,
|
|
300
302
|
SkeletonShape: shape_default,
|
|
301
303
|
Countdown: countdown_default,
|
|
304
|
+
NumberFlowGroup,
|
|
302
305
|
Step: step_default,
|
|
303
306
|
Thead: table_thead_default,
|
|
304
307
|
Td: table_td_default,
|
|
@@ -21,6 +21,10 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
|
|
|
21
21
|
type: BooleanConstructor;
|
|
22
22
|
default: boolean;
|
|
23
23
|
};
|
|
24
|
+
animation: {
|
|
25
|
+
type: BooleanConstructor;
|
|
26
|
+
default: boolean;
|
|
27
|
+
};
|
|
24
28
|
valueStyle: {
|
|
25
29
|
type: PropType<CSSProperties>;
|
|
26
30
|
};
|
|
@@ -44,6 +48,10 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
|
|
|
44
48
|
type: BooleanConstructor;
|
|
45
49
|
default: boolean;
|
|
46
50
|
};
|
|
51
|
+
animation: {
|
|
52
|
+
type: BooleanConstructor;
|
|
53
|
+
default: boolean;
|
|
54
|
+
};
|
|
47
55
|
valueStyle: {
|
|
48
56
|
type: PropType<CSSProperties>;
|
|
49
57
|
};
|
|
@@ -52,6 +60,7 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
|
|
|
52
60
|
}>, {
|
|
53
61
|
value: number;
|
|
54
62
|
start: boolean;
|
|
63
|
+
animation: boolean;
|
|
55
64
|
format: string;
|
|
56
65
|
now: number;
|
|
57
66
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|