migrate tree view selection sheet to composition API and typescript

This commit is contained in:
MaysWind
2025-01-12 17:42:01 +08:00
parent cc9a5eea36
commit a285707b53
2 changed files with 115 additions and 108 deletions
+112 -105
View File
@@ -6,32 +6,32 @@
<div class="swipe-handler"></div> <div class="swipe-handler"></div>
<div class="left"></div> <div class="left"></div>
<div class="right"> <div class="right">
<f7-link sheet-close :text="$t('Done')"></f7-link> <f7-link sheet-close :text="tt('Done')"></f7-link>
</div> </div>
</f7-toolbar> </f7-toolbar>
<f7-page-content> <f7-page-content>
<f7-treeview> <f7-treeview>
<f7-treeview-item item-toggle <f7-treeview-item item-toggle
:opened="isPrimaryItemHasSecondaryValue(item)" :opened="isPrimaryItemHasSecondaryValue(item)"
:label="$tIf((primaryTitleField ? item[primaryTitleField] : item), primaryTitleI18n)" :label="ti((primaryTitleField ? item[primaryTitleField] : item) as string, !!primaryTitleI18n)"
:key="primaryKeyField ? item[primaryKeyField] : item" :key="primaryKeyField ? item[primaryKeyField] : item"
v-for="item in items" v-for="item in items"
v-show="item && (!primaryHiddenField || !item[primaryHiddenField])"> v-show="item && (!primaryHiddenField || !item[primaryHiddenField])">
<template #media> <template #media>
<ItemIcon :icon-type="primaryIconType" :icon-id="item[primaryIconField]" <ItemIcon :icon-type="primaryIconType" :icon-id="item[primaryIconField]"
:color="item[primaryColorField]" v-if="primaryIconField"></ItemIcon> :color="primaryColorField ? item[primaryColorField] : undefined" v-if="primaryIconField"></ItemIcon>
</template> </template>
<f7-treeview-item selectable <f7-treeview-item selectable
:selected="isSecondarySelected(subItem)" :selected="isSecondarySelected(subItem)"
:label="$tIf((secondaryTitleField ? subItem[secondaryTitleField] : subItem), secondaryTitleI18n)" :label="ti((secondaryTitleField ? (subItem as Record<string, unknown>)[secondaryTitleField] : subItem) as string, !!secondaryTitleI18n)"
:key="secondaryKeyField ? subItem[secondaryKeyField] : subItem" :key="secondaryKeyField ? (subItem as Record<string, unknown>)[secondaryKeyField] : subItem"
v-for="subItem in item[primarySubItemsField]" v-for="subItem in item[primarySubItemsField]"
v-show="subItem && (!secondaryHiddenField || !subItem[secondaryHiddenField])" v-show="subItem && (!secondaryHiddenField || !(subItem as Record<string, unknown>)[secondaryHiddenField])"
@click="onSecondaryItemClicked(subItem)"> @click="onSecondaryItemClicked(subItem)">
<template #media> <template #media>
<ItemIcon :icon-type="secondaryIconType" :icon-id="subItem[secondaryIconField]" <ItemIcon :icon-type="secondaryIconType" :icon-id="(subItem as Record<string, unknown>)[secondaryIconField]"
:color="subItem[secondaryColorField]" v-if="secondaryIconField"></ItemIcon> :color="secondaryColorField ? (subItem as Record<string, unknown>)[secondaryColorField] : undefined" v-if="secondaryIconField"></ItemIcon>
</template> </template>
</f7-treeview-item> </f7-treeview-item>
</f7-treeview-item> </f7-treeview-item>
@@ -40,112 +40,119 @@
</f7-sheet> </f7-sheet>
</template> </template>
<script> <script setup lang="ts">
import { ref, computed } from 'vue';
import { useI18n } from '@/locales/helpers.ts';
import { isArray } from '@/lib/common.ts'; import { isArray } from '@/lib/common.ts';
import { scrollToSelectedItem } from '@/lib/ui/mobile.ts'; import { type Framework7Dom, scrollToSelectedItem } from '@/lib/ui/mobile.ts';
export default { const props = defineProps<{
props: [ modelValue: unknown;
'modelValue', primaryKeyField?: string;
'primaryKeyField', primaryTitleField?: string;
'primaryValueField', primaryTitleI18n?: boolean;
'primaryTitleField', primaryIconField?: string;
'primaryTitleI18n', primaryIconType?: string;
'primaryIconField', primaryColorField?: string;
'primaryIconType', primaryHiddenField?: string;
'primaryColorField', primarySubItemsField: string;
'primaryHiddenField', secondaryKeyField?: string;
'primarySubItemsField', secondaryValueField?: string;
'secondaryKeyField', secondaryTitleField?: string;
'secondaryValueField', secondaryTitleI18n?: boolean;
'secondaryTitleField', secondaryIconField?: string;
'secondaryTitleI18n', secondaryIconType?: string;
'secondaryIconField', secondaryColorField?: string;
'secondaryIconType', secondaryHiddenField?: string;
'secondaryColorField', items: Record<string, unknown>[];
'secondaryHiddenField', show: boolean;
'items', }>();
'show'
],
emits: [
'update:modelValue',
'update:show'
],
data() {
const self = this;
return { const emit = defineEmits<{
currentValue: self.modelValue (e: 'update:modelValue', value: unknown): void;
} (e: 'update:show', value: boolean): void;
}, }>();
computed: {
heightClass() {
let count = 0;
if (isArray(this.items)) { const { tt, ti } = useI18n();
count = this.items.length;
} else {
for (const field in this.items) {
if (!Object.prototype.hasOwnProperty.call(this.items, field)) {
continue;
}
count++; const currentValue = ref<unknown>(props.modelValue);
}
const heightClass = computed<string>(() => {
let count = 0;
if (isArray(props.items)) {
count = props.items.length;
} else {
for (const field in props.items) {
if (!Object.prototype.hasOwnProperty.call(props.items, field)) {
continue;
} }
if (count > 6) { count++;
return 'tree-view-selection-huge-sheet';
} else if (count > 2) {
return 'tree-view-selection-large-sheet';
} else {
return '';
}
}
},
methods: {
onSheetOpen(event) {
this.currentValue = this.modelValue;
scrollToSelectedItem(event.$el, '.page-content', '.treeview-item .treeview-item-selected');
},
onSheetClosed() {
this.$emit('update:show', false);
},
onSecondaryItemClicked(subItem) {
if (this.secondaryValueField) {
this.currentValue = subItem[this.secondaryValueField];
} else {
this.currentValue = subItem;
}
this.$emit('update:modelValue', this.currentValue);
this.$emit('update:show', false);
},
isPrimaryItemHasSecondaryValue(primaryItem) {
for (let i = 0; i < primaryItem[this.primarySubItemsField].length; i++) {
const secondaryItem = primaryItem[this.primarySubItemsField][i];
if (this.secondaryHiddenField && secondaryItem[this.secondaryHiddenField]) {
continue;
}
if (this.secondaryValueField && secondaryItem[this.secondaryValueField] === this.currentValue) {
return true;
} else if (!this.secondaryValueField && secondaryItem === this.currentValue) {
return true;
}
}
return false;
},
isSecondarySelected(subItem) {
if (this.secondaryValueField) {
return this.currentValue === subItem[this.secondaryValueField];
} else {
return this.currentValue === subItem;
}
} }
} }
if (count > 6) {
return 'tree-view-selection-huge-sheet';
} else if (count > 2) {
return 'tree-view-selection-large-sheet';
} else {
return '';
}
});
function isPrimaryItemHasSecondaryValue(primaryItem: Record<string, unknown>): boolean {
const subItems = primaryItem[props.primarySubItemsField] as unknown[];
if (subItems.length < 1) {
return false;
}
for (let i = 0; i < subItems.length; i++) {
const secondaryItem = subItems[i];
if (props.secondaryHiddenField && (secondaryItem as Record<string, unknown>)[props.secondaryHiddenField]) {
continue;
}
if (props.secondaryValueField && (secondaryItem as Record<string, unknown>)[props.secondaryValueField] === currentValue.value) {
return true;
} else if (!props.secondaryValueField && secondaryItem === currentValue.value) {
return true;
}
}
return false;
}
function isSecondarySelected(subItem: unknown): boolean {
if (props.secondaryValueField) {
return currentValue.value === (subItem as Record<string, unknown>)[props.secondaryValueField];
} else {
return currentValue.value === subItem;
}
}
function onSecondaryItemClicked(subItem: unknown): void {
if (props.secondaryValueField) {
currentValue.value = (subItem as Record<string, unknown>)[props.secondaryValueField];
} else {
currentValue.value = subItem;
}
emit('update:modelValue', currentValue.value);
emit('update:show', false);
}
function onSheetOpen(event: { $el: Framework7Dom }): void {
currentValue.value = props.modelValue;
scrollToSelectedItem(event.$el, '.page-content', '.treeview-item .treeview-item-selected');
}
function onSheetClosed() {
emit('update:show', false);
} }
</script> </script>
+3 -3
View File
@@ -112,7 +112,7 @@
<span>{{ $t('None') }}</span> <span>{{ $t('None') }}</span>
</div> </div>
</template> </template>
<tree-view-selection-sheet primary-key-field="id" primary-value-field="id" primary-title-field="name" <tree-view-selection-sheet primary-key-field="id" primary-title-field="name"
primary-icon-field="icon" primary-icon-type="category" primary-color-field="color" primary-icon-field="icon" primary-icon-type="category" primary-color-field="color"
primary-hidden-field="hidden" primary-sub-items-field="subCategories" primary-hidden-field="hidden" primary-sub-items-field="subCategories"
secondary-key-field="id" secondary-value-field="id" secondary-title-field="name" secondary-key-field="id" secondary-value-field="id" secondary-title-field="name"
@@ -143,7 +143,7 @@
<span>{{ $t('None') }}</span> <span>{{ $t('None') }}</span>
</div> </div>
</template> </template>
<tree-view-selection-sheet primary-key-field="id" primary-value-field="id" primary-title-field="name" <tree-view-selection-sheet primary-key-field="id" primary-title-field="name"
primary-icon-field="icon" primary-icon-type="category" primary-color-field="color" primary-icon-field="icon" primary-icon-type="category" primary-color-field="color"
primary-hidden-field="hidden" primary-sub-items-field="subCategories" primary-hidden-field="hidden" primary-sub-items-field="subCategories"
secondary-key-field="id" secondary-value-field="id" secondary-title-field="name" secondary-key-field="id" secondary-value-field="id" secondary-title-field="name"
@@ -174,7 +174,7 @@
<span>{{ $t('None') }}</span> <span>{{ $t('None') }}</span>
</div> </div>
</template> </template>
<tree-view-selection-sheet primary-key-field="id" primary-value-field="id" primary-title-field="name" <tree-view-selection-sheet primary-key-field="id" primary-title-field="name"
primary-icon-field="icon" primary-icon-type="category" primary-color-field="color" primary-icon-field="icon" primary-icon-type="category" primary-color-field="color"
primary-hidden-field="hidden" primary-sub-items-field="subCategories" primary-hidden-field="hidden" primary-sub-items-field="subCategories"
secondary-key-field="id" secondary-value-field="id" secondary-title-field="name" secondary-key-field="id" secondary-value-field="id" secondary-title-field="name"