timered-counter
Version:
Make the value change more vivid and natural
158 lines • 5.93 kB
JavaScript
import { __decorate } from "tslib";
import { property, state } from 'lit/decorators.js';
import { isNonNullish, isNullish, isString } from 'remeda';
import { TimeredCounterAdapter } from '../timered-counter-adapter.js';
export const CounterBaseMixin = (superClass) => {
class CounterBaseMixinClass extends superClass {
get value() {
return this.numberAdapter.create(this.__value);
}
set value(value) {
value = TimeredCounterAdapter.NUMBER_ADAPTER.create(isNullish(value) || (isString(value) && value.trim() === '')
? 0
: value);
const old = this.__value;
this.__value = value;
if (!this.numberAdapter.eq(this.__value, old)) {
this.requestUpdate('value', old);
}
}
/**
* 用于记录上一次的值.
*
* 初始化时({@link connectedCallback}), oldValue 将被设置为 `initialValue` 或 `value` 的值.
*/
get oldValue() {
return this.numberAdapter.create(this.__oldValue);
}
set oldValue(value) {
const old = this.__oldValue;
this.__oldValue = value;
this.requestUpdate('oldValue', old);
}
/**
* 如果初始值被设置, {@link oldValue} 的初始值, 会使用该值而不是 `value`.
*
* 这对于初始化完成后启动动画效果非常有用.
*/
get initialValue() {
return isNullish(this.__initialValue)
? this.__initialValue
: this.numberAdapter.create(this.__initialValue);
}
set initialValue(value) {
const old = this.__initialValue;
this.__initialValue = value;
this.requestUpdate('initialValue', old);
}
/**
* 自定义本地化配置, 否则从浏览器环境中获取.
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale
*
* @default "en-US"
*/
get locale() {
return this.__locale;
}
set locale(value) {
const old = this.__locale;
this.__locale = value;
this.requestUpdate('locale', old);
this.localeInstance = isString(this.__locale)
? new Intl.Locale(this.__locale)
: new Intl.Locale(...this.__locale);
}
constructor(...args) {
super(...args);
this.__value = TimeredCounterAdapter.NUMBER_ADAPTER.create(0);
// value: V = CounterBaseMixinClass.NUMBER_ADAPTER.create(0);
this.__oldValue = TimeredCounterAdapter.NUMBER_ADAPTER.create(0);
// oldValue: V = CounterBaseMixinClass.NUMBER_ADAPTER.create(0);
this.__initialValue = null;
this.__locale = 'en-US';
this.localeInstance = isString(this.locale)
? new Intl.Locale(this.locale)
: new Intl.Locale(...this.locale);
this.direction = 'up';
this.oldDirection = this.direction;
// @ts-ignore
this.numberAdapter = TimeredCounterAdapter.NUMBER_ADAPTER;
// @ts-ignore
this.stringAdapter = TimeredCounterAdapter.STRING_ADAPTER;
}
willUpdate(changedProperties) {
super.willUpdate(changedProperties);
if (changedProperties.has('value') &&
!changedProperties.has('oldValue')) {
// oldValue 未被手动设置时, 使用默认策略更新 oldValue.
this.oldValue = changedProperties.get('value') ?? this.value;
}
this.oldDirection = this.direction;
if (!this.numberAdapter.eq(this.value, this.oldValue)) {
this.direction = this.numberAdapter.gt(this.value, this.oldValue)
? 'down'
: 'up';
}
}
/**
* oldValue 的默认初始值应当来自 initialValue 或 value.
* 以保证 oldValue 始终有值.
*/
connectedCallback() {
super.connectedCallback();
this.oldValue = isNonNullish(this.initialValue)
? this.initialValue
: this.value;
}
}
__decorate([
property({
attribute: 'value',
reflect: true,
converter: {
toAttribute: TimeredCounterAdapter.VALUE_CONVERTER.toAttribute,
},
noAccessor: true,
})
], CounterBaseMixinClass.prototype, "value", null);
__decorate([
property({
attribute: 'old-value',
reflect: true,
converter: TimeredCounterAdapter.VALUE_CONVERTER,
noAccessor: true,
})
], CounterBaseMixinClass.prototype, "oldValue", null);
__decorate([
property({
attribute: 'initial-value',
reflect: true,
converter: TimeredCounterAdapter.VALUE_CONVERTER,
noAccessor: true,
})
], CounterBaseMixinClass.prototype, "initialValue", null);
__decorate([
property({
converter: value => {
if (isNullish(value))
return value;
try {
return JSON.parse(value);
}
catch (error) {
return value;
}
},
reflect: true,
noAccessor: true,
})
], CounterBaseMixinClass.prototype, "locale", null);
__decorate([
state()
], CounterBaseMixinClass.prototype, "direction", void 0);
__decorate([
state()
], CounterBaseMixinClass.prototype, "oldDirection", void 0);
return CounterBaseMixinClass;
};
//# sourceMappingURL=counter-base.js.map