forked from FoundKeyGang/FoundKey
client: refactor components/tab.vue to composition API
Refactoring this component could be done after changing its method of receiving the list of available tabs by using slots to using an ordinary parameter. This was possible because all uses of this component just provided text as the tab labels. Also removed unused imports of this component. Also removed the use of the click-anime directive. Reviewed-on: FoundKeyGang/FoundKey#184
This commit is contained in:
parent
c5f07ef66c
commit
6ef9069a2f
7 changed files with 67 additions and 49 deletions
|
@ -1,31 +1,29 @@
|
|||
<script lang="ts">
|
||||
import { defineComponent, h, resolveDirective, withDirectives } from 'vue';
|
||||
<template>
|
||||
<div class="pxhvhrfw" v-size="{ max: [500] }">
|
||||
<button
|
||||
v-for="option in options"
|
||||
:key="option.value"
|
||||
:class="{ '_button': true, active: modelValue === option.value }"
|
||||
:disabled="modelValue === option.value"
|
||||
@click.stop="emit('update:modelValue', option.value)"
|
||||
>
|
||||
{{ option.label }}
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
modelValue: {
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
render() {
|
||||
const options = this.$slots.default();
|
||||
<script lang="ts" setup>
|
||||
const emit = defineEmits<{
|
||||
(ev: 'update:modelValue', value: string): void;
|
||||
}>();
|
||||
|
||||
return withDirectives(h('div', {
|
||||
class: 'pxhvhrfw',
|
||||
}, options.map(option => withDirectives(h('button', {
|
||||
class: ['_button', { active: this.modelValue === option.props.value }],
|
||||
key: option.key,
|
||||
disabled: this.modelValue === option.props.value,
|
||||
onClick: () => {
|
||||
this.$emit('update:modelValue', option.props.value);
|
||||
},
|
||||
}, option.children), [
|
||||
[resolveDirective('click-anime')],
|
||||
]))), [
|
||||
[resolveDirective('size'), { max: [500] }],
|
||||
]);
|
||||
},
|
||||
});
|
||||
const props = defineProps<{
|
||||
modelValue: string;
|
||||
options: {
|
||||
value: string;
|
||||
label: string;
|
||||
};
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
<template>
|
||||
<MkSpacer :content-max="800">
|
||||
<MkTab v-model="tab" style="margin-bottom: var(--margin);">
|
||||
<option value="notes">{{ i18n.ts.notes }}</option>
|
||||
<option value="polls">{{ i18n.ts.poll }}</option>
|
||||
</MkTab>
|
||||
<MkTab v-model="tab" :options="tabs" style="margin-bottom: var(--margin);"/>
|
||||
<XNotes v-if="tab === 'notes'" :pagination="paginationForNotes"/>
|
||||
<XNotes v-else-if="tab === 'polls'" :pagination="paginationForPolls"/>
|
||||
</MkSpacer>
|
||||
|
@ -14,6 +11,14 @@ import XNotes from '@/components/notes.vue';
|
|||
import MkTab from '@/components/tab.vue';
|
||||
import { i18n } from '@/i18n';
|
||||
|
||||
const tabs = [{
|
||||
value: 'notes',
|
||||
label: i18n.ts.notes,
|
||||
}, {
|
||||
value: 'polls',
|
||||
label: i18n.ts.poll,
|
||||
}];
|
||||
|
||||
const paginationForNotes = {
|
||||
endpoint: 'notes/featured' as const,
|
||||
limit: 10,
|
||||
|
|
|
@ -47,7 +47,6 @@ import XUserList from '@/components/user-list.vue';
|
|||
import MkFolder from '@/components/ui/folder.vue';
|
||||
import MkInput from '@/components/form/input.vue';
|
||||
import MkButton from '@/components/ui/button.vue';
|
||||
import MkTab from '@/components/tab.vue';
|
||||
import MkPagination from '@/components/ui/pagination.vue';
|
||||
import MkGalleryPostPreview from '@/components/gallery-post-preview.vue';
|
||||
import number from '@/filters/number';
|
||||
|
|
|
@ -45,7 +45,6 @@ import MkPagination from '@/components/ui/pagination.vue';
|
|||
import MkButton from '@/components/ui/button.vue';
|
||||
import MkContainer from '@/components/ui/container.vue';
|
||||
import MkAvatars from '@/components/avatars.vue';
|
||||
import MkTab from '@/components/tab.vue';
|
||||
import * as os from '@/os';
|
||||
import { definePageMetadata } from '@/scripts/page-metadata';
|
||||
import { i18n } from '@/i18n';
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
<template>
|
||||
<div class="_formRoot">
|
||||
<MkTab v-model="tab" style="margin-bottom: var(--margin);">
|
||||
<option value="mute">{{ i18n.ts.mutedUsers }}</option>
|
||||
<option value="block">{{ i18n.ts.blockedUsers }}</option>
|
||||
</MkTab>
|
||||
<MkTab v-model="tab" :options="tabs" style="margin-bottom: var(--margin);"/>
|
||||
<div v-if="tab === 'mute'">
|
||||
<MkPagination :pagination="mutingPagination" class="muting">
|
||||
<template #empty><FormInfo>{{ i18n.ts.noUsers }}</FormInfo></template>
|
||||
|
@ -39,6 +36,14 @@ import { definePageMetadata } from '@/scripts/page-metadata';
|
|||
|
||||
let tab = $ref('mute');
|
||||
|
||||
const tabs = [{
|
||||
value: 'mute',
|
||||
label: i18n.ts.mutedUsers,
|
||||
}, {
|
||||
value: 'block',
|
||||
label: i18n.ts.blockedUsers,
|
||||
}];
|
||||
|
||||
const mutingPagination = {
|
||||
endpoint: 'mute/list' as const,
|
||||
limit: 10,
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
<template>
|
||||
<div class="_formRoot">
|
||||
<MkTab v-model="tab" class="_formBlock">
|
||||
<option value="soft">{{ i18n.ts._wordMute.soft }}</option>
|
||||
<option value="hard">{{ i18n.ts._wordMute.hard }}</option>
|
||||
</MkTab>
|
||||
<MkTab v-model="tab" :options="tabs" class="_formBlock"/>
|
||||
<div class="_formBlock">
|
||||
<div v-show="tab === 'soft'">
|
||||
<MkInfo class="_formBlock">{{ i18n.ts._wordMute.softDescription }}</MkInfo>
|
||||
|
@ -50,6 +47,14 @@ const render = (mutedWords) => mutedWords.map(x => {
|
|||
}
|
||||
}).join('\n');
|
||||
|
||||
const tabs = [{
|
||||
value: 'soft',
|
||||
label: i18n.ts._wordMute.soft,
|
||||
}, {
|
||||
value: 'hard',
|
||||
label: i18n.ts._wordMute.hard,
|
||||
}];
|
||||
|
||||
const tab = ref('soft');
|
||||
const softMutedWords = ref(render(defaultStore.state.mutedWords));
|
||||
const hardMutedWords = ref(render($i!.mutedWords));
|
||||
|
|
|
@ -1,16 +1,12 @@
|
|||
<template>
|
||||
<div v-sticky-container class="yrzkoczt">
|
||||
<MkTab v-model="include" class="tab">
|
||||
<option :value="null">{{ i18n.ts.notes }}</option>
|
||||
<option value="replies">{{ i18n.ts.notesAndReplies }}</option>
|
||||
<option value="files">{{ i18n.ts.withFiles }}</option>
|
||||
</MkTab>
|
||||
<MkTab v-model="include" :options="tabs" class="tab"/>
|
||||
<XNotes :no-gap="true" :pagination="pagination"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed } from 'vue';
|
||||
import { computed } from 'vue';
|
||||
import * as foundkey from 'foundkey-js';
|
||||
import XNotes from '@/components/notes.vue';
|
||||
import MkTab from '@/components/tab.vue';
|
||||
|
@ -21,15 +17,26 @@ const props = defineProps<{
|
|||
user: foundkey.entities.UserDetailed;
|
||||
}>();
|
||||
|
||||
const include = ref<string | null>(null);
|
||||
const tabs = [{
|
||||
value: 'notes',
|
||||
label: i18n.ts.notes,
|
||||
}, {
|
||||
value: 'replies',
|
||||
label: i18n.ts.notesAndReplies,
|
||||
}, {
|
||||
value: 'files',
|
||||
label: i18n.ts.withFiles,
|
||||
}];
|
||||
|
||||
let include: string = $ref('notes');
|
||||
|
||||
const pagination = {
|
||||
endpoint: 'users/notes' as const,
|
||||
limit: 10,
|
||||
params: computed(() => ({
|
||||
userId: props.user.id,
|
||||
includeReplies: include.value === 'replies',
|
||||
withFiles: include.value === 'files',
|
||||
includeReplies: include === 'replies',
|
||||
withFiles: include === 'files',
|
||||
})),
|
||||
};
|
||||
</script>
|
||||
|
|
Loading…
Reference in a new issue