migrate number pad sheet to composition API and typescript

This commit is contained in:
MaysWind
2025-01-06 22:32:36 +08:00
parent 60ba3b7977
commit 2b71723ba1
2 changed files with 288 additions and 263 deletions
+160 -146
View File
@@ -65,91 +65,97 @@
</f7-sheet> </f7-sheet>
</template> </template>
<script> <script setup lang="ts">
import { mapStores } from 'pinia'; import { type Ref, ref, computed } from 'vue';
import { useI18n } from '@/lib/i18n.js';
import { useI18nUIComponents } from '@/lib/ui/mobile.js';
import { useUserStore } from '@/stores/user.ts'; import { useUserStore } from '@/stores/user.ts';
import { ALL_CURRENCIES } from '@/consts/currency.ts'; import { ALL_CURRENCIES } from '@/consts/currency.ts';
import { isString, isNumber, removeAll } from '@/lib/common.ts'; import { isString, isNumber, removeAll } from '@/lib/common.ts';
export default { const {
props: [ tt,
'modelValue', getCurrentDecimalSeparator,
'minValue', getCurrentDigitGroupingSymbol,
'maxValue', appendDigitGroupingSymbol,
'currency', parseAmount,
'show' formatAmount
], } = useI18n();
emits: [ const { showToast } = useI18nUIComponents();
'update:modelValue', const userStore = useUserStore();
'update:show'
],
data() {
const self = this;
const userStore = useUserStore();
return { const props = defineProps<{
previousValue: '', modelValue: number | string;
currentSymbol: '', minValue?: number;
currentValue: self.getStringValue(userStore, self.modelValue) maxValue?: number;
} currency?: string;
}, show: boolean;
computed: { }>();
...mapStores(useUserStore),
decimalSeparator() { const emit = defineEmits<{
return this.$locale.getCurrentDecimalSeparator(this.userStore); (e: 'update:modelValue', value: number): void,
}, (e: 'update:show', value: boolean): void
supportDecimalSeparator() { }>();
if (!this.currency || !ALL_CURRENCIES[this.currency] || !isNumber(ALL_CURRENCIES[this.currency].fraction)) {
const previousValue: Ref<string> = ref('');
const currentSymbol: Ref<string> = ref('');
const currentValue: Ref<string> = ref(getStringValue(props.modelValue));
const decimalSeparator = computed<string>(() => getCurrentDecimalSeparator(userStore));
const supportDecimalSeparator = computed<boolean>(() => {
if (!props.currency || !ALL_CURRENCIES[props.currency] || !isNumber(ALL_CURRENCIES[props.currency].fraction)) {
return true; return true;
} }
return ALL_CURRENCIES[this.currency].fraction > 0; return (ALL_CURRENCIES[props.currency].fraction as number) > 0;
}, });
currentDisplay() {
const previousValue = this.$locale.appendDigitGroupingSymbol(this.userStore, this.previousValue);
const currentValue = this.$locale.appendDigitGroupingSymbol(this.userStore, this.currentValue);
if (this.currentSymbol) { const currentDisplay = computed<string>(() => {
return `${previousValue} ${this.currentSymbol} ${currentValue}`; const finalPreviousValue = appendDigitGroupingSymbol(userStore, previousValue.value);
const finalCurrentValue = appendDigitGroupingSymbol(userStore, currentValue.value);
if (currentSymbol.value) {
return `${finalPreviousValue} ${currentSymbol.value} ${finalCurrentValue}`;
} else { } else {
return currentValue; return finalCurrentValue;
} }
}, });
currentDisplayNumClass() {
const currentDisplay = this.currentDisplay || '';
if (currentDisplay.length >= 24) { const currentDisplayNumClass = computed<string>(() => {
if (currentDisplay.value && currentDisplay.value.length >= 24) {
return 'numpad-value-small'; return 'numpad-value-small';
} else if (currentDisplay.length >= 16) { } else if (currentDisplay.value && currentDisplay.value.length >= 16) {
return 'numpad-value-normal'; return 'numpad-value-normal';
} else { } else {
return 'numpad-value-large'; return 'numpad-value-large';
} }
}, });
confirmText() {
if (this.currentSymbol) { const confirmText = computed<string>(() => {
if (currentSymbol.value) {
return '='; return '=';
} else { } else {
return this.$t('OK'); return tt('OK');
} }
} });
},
methods: { function getStringValue(value: number | string): string {
getStringValue(userStore, value) {
if (!isNumber(value) && !isString(value)) { if (!isNumber(value) && !isString(value)) {
return ''; return '';
} }
let str = this.$locale.formatAmount(userStore, value, this.currency); let str = formatAmount(userStore, value, props.currency);
const digitGroupingSymbol = this.$locale.getCurrentDigitGroupingSymbol(userStore); const digitGroupingSymbol = getCurrentDigitGroupingSymbol(userStore);
if (str.indexOf(digitGroupingSymbol) >= 0) { if (str.indexOf(digitGroupingSymbol) >= 0) {
str = removeAll(str, digitGroupingSymbol); str = removeAll(str, digitGroupingSymbol);
} }
const decimalSeparator = this.$locale.getCurrentDecimalSeparator(userStore); const decimalSeparator = getCurrentDecimalSeparator(userStore);
const decimalSeparatorPos = str.indexOf(decimalSeparator); const decimalSeparatorPos = str.indexOf(decimalSeparator);
if (decimalSeparatorPos < 0) { if (decimalSeparatorPos < 0) {
@@ -179,167 +185,175 @@ export default {
} }
return `${integer}${decimalSeparator}${newDecimals}`; return `${integer}${decimalSeparator}${newDecimals}`;
}, }
inputNum(num) {
if (!this.previousValue && this.currentSymbol === '') { function inputNum(num: number): void {
this.currentValue = '-' + this.currentValue; if (!previousValue.value && currentSymbol.value === '') {
this.currentSymbol = ''; currentValue.value = '-' + currentValue.value;
currentSymbol.value = '';
} }
if (this.currentValue === '0') { if (currentValue.value === '0') {
this.currentValue = num.toString(); currentValue.value = num.toString();
return; return;
} else if (this.currentValue === '-0') { } else if (currentValue.value === '-0') {
this.currentValue = '-' + num.toString(); currentValue.value = '-' + num.toString();
return; return;
} }
const decimalSeparatorPos = this.currentValue.indexOf(this.decimalSeparator); const decimalSeparatorPos = currentValue.value.indexOf(decimalSeparator.value);
if (decimalSeparatorPos >= 0 && this.currentValue.substring(decimalSeparatorPos + 1, this.currentValue.length).length >= 2) { if (decimalSeparatorPos >= 0 && currentValue.value.substring(decimalSeparatorPos + 1, currentValue.value.length).length >= 2) {
return; return;
} }
const newValue = this.currentValue + num.toString(); const newValue = currentValue.value + num.toString();
if (isNumber(this.minValue)) { if (isNumber(props.minValue)) {
const current = this.$locale.parseAmount(this.userStore, newValue); const current = parseAmount(userStore, newValue);
if (current < this.minValue) { if (current < (props.minValue as number)) {
return; return;
} }
} }
if (isNumber(this.maxValue)) { if (isNumber(props.maxValue)) {
const current = this.$locale.parseAmount(this.userStore, newValue); const current = parseAmount(userStore, newValue);
if (current > this.maxValue) { if (current > (props.maxValue as number)) {
return; return;
} }
} }
this.currentValue = newValue; currentValue.value = newValue;
}, }
inputDoubleNum(num) {
this.inputNum(num); function inputDoubleNum(num: number): void {
this.inputNum(num); inputNum(num);
}, inputNum(num);
inputDecimalSeparator() { }
if (this.currentValue.indexOf(this.decimalSeparator) >= 0) {
function inputDecimalSeparator(): void {
if (currentValue.value.indexOf(decimalSeparator.value) >= 0) {
return; return;
} }
if (!this.previousValue && this.currentSymbol === '') { if (!previousValue.value && currentSymbol.value === '') {
this.currentValue = '-' + this.currentValue; currentValue.value = '-' + currentValue.value;
this.currentSymbol = ''; currentSymbol.value = '';
} }
if (this.currentValue.length < 1) { if (currentValue.value.length < 1) {
this.currentValue = '0'; currentValue.value = '0';
} else if (this.currentValue === '-') { } else if (currentValue.value === '-') {
this.currentValue = '-0'; currentValue.value = '-0';
} }
this.currentValue = this.currentValue + this.decimalSeparator; currentValue.value = currentValue.value + decimalSeparator.value;
}, }
setSymbol(symbol) {
if (this.currentValue) { function setSymbol(symbol: string): void {
if (this.currentSymbol) { if (currentValue.value) {
const lastFormulaCalcResult = this.confirm(); if (currentSymbol.value) {
const lastFormulaCalcResult = confirm();
if (!lastFormulaCalcResult) { if (!lastFormulaCalcResult) {
return; return;
} }
} }
this.previousValue = this.currentValue; previousValue.value = currentValue.value;
this.currentValue = ''; currentValue.value = '';
} }
this.currentSymbol = symbol; currentSymbol.value = symbol;
}, }
backspace() {
if (!this.currentValue || this.currentValue.length < 1) { function backspace(): void {
if (this.currentSymbol) { if (!currentValue.value || currentValue.value.length < 1) {
this.currentValue = this.previousValue; if (currentSymbol.value) {
this.previousValue = ''; currentValue.value = previousValue.value;
this.currentSymbol = ''; previousValue.value = '';
currentSymbol.value = '';
} }
return; return;
} }
this.currentValue = this.currentValue.substring(0, this.currentValue.length - 1); currentValue.value = currentValue.value.substring(0, currentValue.value.length - 1);
}, }
clear() {
this.currentValue = ''; function clear(): void {
this.previousValue = ''; currentValue.value = '';
this.currentSymbol = ''; previousValue.value = '';
}, currentSymbol.value = '';
confirm() { }
if (this.currentSymbol && this.currentValue.length >= 1) {
const previousValue = this.$locale.parseAmount(this.userStore, this.previousValue); function confirm(): boolean {
const currentValue = this.$locale.parseAmount(this.userStore, this.currentValue); if (currentSymbol.value && currentValue.value.length >= 1) {
const previous = parseAmount(userStore, previousValue.value);
const current = parseAmount(userStore, currentValue.value);
let finalValue = 0; let finalValue = 0;
switch (this.currentSymbol) { switch (currentSymbol.value) {
case '+': case '+':
finalValue = previousValue + currentValue; finalValue = previous + current;
break; break;
case '': case '':
finalValue = previousValue - currentValue; finalValue = previous - current;
break; break;
case '×': case '×':
finalValue = Math.round(previousValue * currentValue / 100); finalValue = Math.round(previous * current / 100);
break; break;
default: default:
finalValue = previousValue; finalValue = previous;
} }
if (isNumber(this.minValue)) { if (isNumber(props.minValue)) {
if (finalValue < this.minValue) { if (finalValue < (props.minValue as number)) {
this.$toast('Numeric Overflow'); showToast('Numeric Overflow');
return false; return false;
} }
} }
if (isNumber(this.maxValue)) { if (isNumber(props.maxValue)) {
if (finalValue > this.maxValue) { if (finalValue > (props.maxValue as number)) {
this.$toast('Numeric Overflow'); showToast('Numeric Overflow');
return false; return false;
} }
} }
this.currentValue = this.getStringValue(this.userStore, finalValue); currentValue.value = getStringValue(finalValue);
this.previousValue = ''; previousValue.value = '';
this.currentSymbol = ''; currentSymbol.value = '';
return true; return true;
} else if (this.currentSymbol && this.currentValue.length < 1) { } else if (currentSymbol.value && currentValue.value.length < 1) {
this.currentValue = this.previousValue; currentValue.value = previousValue.value;
this.previousValue = ''; previousValue.value = '';
this.currentSymbol = ''; currentSymbol.value = '';
return true; return true;
} else { } else {
const value = this.$locale.parseAmount(this.userStore, this.currentValue); const value = parseAmount(userStore, currentValue.value);
this.$emit('update:modelValue', value); emit('update:modelValue', value);
this.close(); close();
return true; return true;
} }
}, }
close() {
this.$emit('update:show', false); function close(): void {
}, emit('update:show', false);
onSheetOpen() { }
this.currentValue = this.getStringValue(this.userStore, this.modelValue);
}, function onSheetOpen(): void {
onSheetClosed() { currentValue.value = getStringValue(props.modelValue);
this.close(); }
}
} function onSheetClosed(): void {
close();
} }
</script> </script>
+11
View File
@@ -1,3 +1,4 @@
import { useI18n as useVueI18n } from 'vue-i18n';
import { f7, f7ready } from 'framework7-vue'; import { f7, f7ready } from 'framework7-vue';
import { FontSize, FONT_SIZE_PREVIEW_CLASSNAME_PREFIX } from '@/core/font.ts'; import { FontSize, FONT_SIZE_PREVIEW_CLASSNAME_PREFIX } from '@/core/font.ts';
@@ -192,3 +193,13 @@ export function scrollToSelectedItem(parentEl, containerSelector, selectedItemSe
container.scrollTop(targetPos); container.scrollTop(targetPos);
} }
export function useI18nUIComponents() {
const i18nGlobal = useVueI18n();
return {
showAlert: (message, confirmCallback) => showAlert(message, confirmCallback, i18nGlobal.t),
showConfirm: (message, confirmCallback, cancelCallback) => showConfirm(message, confirmCallback, cancelCallback, i18nGlobal.t),
showToast: (message, timeout) => showToast(message, timeout, i18nGlobal.t)
};
}