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.
This commit is contained in:
Johann150 2022-10-04 16:02:51 +02:00
parent 1592420406
commit 93f54e3258
Signed by untrusted user: Johann150
GPG key ID: 9EE6577A2A06F8F1
7 changed files with 67 additions and 49 deletions

View file

@ -1,31 +1,29 @@
<script lang="ts"> <template>
import { defineComponent, h, resolveDirective, withDirectives } from 'vue'; <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({ <script lang="ts" setup>
props: { const emit = defineEmits<{
modelValue: { (ev: 'update:modelValue', value: string): void;
required: true, }>();
},
},
render() {
const options = this.$slots.default();
return withDirectives(h('div', { const props = defineProps<{
class: 'pxhvhrfw', modelValue: string;
}, options.map(option => withDirectives(h('button', { options: {
class: ['_button', { active: this.modelValue === option.props.value }], value: string;
key: option.key, label: string;
disabled: this.modelValue === option.props.value, };
onClick: () => { }>();
this.$emit('update:modelValue', option.props.value);
},
}, option.children), [
[resolveDirective('click-anime')],
]))), [
[resolveDirective('size'), { max: [500] }],
]);
},
});
</script> </script>
<style lang="scss"> <style lang="scss">

View file

@ -1,9 +1,6 @@
<template> <template>
<MkSpacer :content-max="800"> <MkSpacer :content-max="800">
<MkTab v-model="tab" style="margin-bottom: var(--margin);"> <MkTab v-model="tab" :options="tabs" style="margin-bottom: var(--margin);"/>
<option value="notes">{{ i18n.ts.notes }}</option>
<option value="polls">{{ i18n.ts.poll }}</option>
</MkTab>
<XNotes v-if="tab === 'notes'" :pagination="paginationForNotes"/> <XNotes v-if="tab === 'notes'" :pagination="paginationForNotes"/>
<XNotes v-else-if="tab === 'polls'" :pagination="paginationForPolls"/> <XNotes v-else-if="tab === 'polls'" :pagination="paginationForPolls"/>
</MkSpacer> </MkSpacer>
@ -14,6 +11,14 @@ import XNotes from '@/components/notes.vue';
import MkTab from '@/components/tab.vue'; import MkTab from '@/components/tab.vue';
import { i18n } from '@/i18n'; import { i18n } from '@/i18n';
const tabs = [{
value: 'notes',
label: i18n.ts.notes,
}, {
value: 'polls',
label: i18n.ts.poll,
}];
const paginationForNotes = { const paginationForNotes = {
endpoint: 'notes/featured' as const, endpoint: 'notes/featured' as const,
limit: 10, limit: 10,

View file

@ -47,7 +47,6 @@ import XUserList from '@/components/user-list.vue';
import MkFolder from '@/components/ui/folder.vue'; import MkFolder from '@/components/ui/folder.vue';
import MkInput from '@/components/form/input.vue'; import MkInput from '@/components/form/input.vue';
import MkButton from '@/components/ui/button.vue'; import MkButton from '@/components/ui/button.vue';
import MkTab from '@/components/tab.vue';
import MkPagination from '@/components/ui/pagination.vue'; import MkPagination from '@/components/ui/pagination.vue';
import MkGalleryPostPreview from '@/components/gallery-post-preview.vue'; import MkGalleryPostPreview from '@/components/gallery-post-preview.vue';
import number from '@/filters/number'; import number from '@/filters/number';

View file

@ -45,7 +45,6 @@ import MkPagination from '@/components/ui/pagination.vue';
import MkButton from '@/components/ui/button.vue'; import MkButton from '@/components/ui/button.vue';
import MkContainer from '@/components/ui/container.vue'; import MkContainer from '@/components/ui/container.vue';
import MkAvatars from '@/components/avatars.vue'; import MkAvatars from '@/components/avatars.vue';
import MkTab from '@/components/tab.vue';
import * as os from '@/os'; import * as os from '@/os';
import { definePageMetadata } from '@/scripts/page-metadata'; import { definePageMetadata } from '@/scripts/page-metadata';
import { i18n } from '@/i18n'; import { i18n } from '@/i18n';

View file

@ -1,9 +1,6 @@
<template> <template>
<div class="_formRoot"> <div class="_formRoot">
<MkTab v-model="tab" style="margin-bottom: var(--margin);"> <MkTab v-model="tab" :options="tabs" style="margin-bottom: var(--margin);"/>
<option value="mute">{{ i18n.ts.mutedUsers }}</option>
<option value="block">{{ i18n.ts.blockedUsers }}</option>
</MkTab>
<div v-if="tab === 'mute'"> <div v-if="tab === 'mute'">
<MkPagination :pagination="mutingPagination" class="muting"> <MkPagination :pagination="mutingPagination" class="muting">
<template #empty><FormInfo>{{ i18n.ts.noUsers }}</FormInfo></template> <template #empty><FormInfo>{{ i18n.ts.noUsers }}</FormInfo></template>
@ -39,6 +36,14 @@ import { definePageMetadata } from '@/scripts/page-metadata';
let tab = $ref('mute'); let tab = $ref('mute');
const tabs = [{
value: 'mute',
label: i18n.ts.mutedUsers,
}, {
value: 'block',
label: i18n.ts.blockedUsers,
}];
const mutingPagination = { const mutingPagination = {
endpoint: 'mute/list' as const, endpoint: 'mute/list' as const,
limit: 10, limit: 10,

View file

@ -1,9 +1,6 @@
<template> <template>
<div class="_formRoot"> <div class="_formRoot">
<MkTab v-model="tab" class="_formBlock"> <MkTab v-model="tab" :options="tabs" class="_formBlock"/>
<option value="soft">{{ i18n.ts._wordMute.soft }}</option>
<option value="hard">{{ i18n.ts._wordMute.hard }}</option>
</MkTab>
<div class="_formBlock"> <div class="_formBlock">
<div v-show="tab === 'soft'"> <div v-show="tab === 'soft'">
<MkInfo class="_formBlock">{{ i18n.ts._wordMute.softDescription }}</MkInfo> <MkInfo class="_formBlock">{{ i18n.ts._wordMute.softDescription }}</MkInfo>
@ -50,6 +47,14 @@ const render = (mutedWords) => mutedWords.map(x => {
} }
}).join('\n'); }).join('\n');
const tabs = [{
value: 'soft',
label: i18n.ts._wordMute.soft,
}, {
value: 'hard',
label: i18n.ts._wordMute.hard,
}];
const tab = ref('soft'); const tab = ref('soft');
const softMutedWords = ref(render(defaultStore.state.mutedWords)); const softMutedWords = ref(render(defaultStore.state.mutedWords));
const hardMutedWords = ref(render($i!.mutedWords)); const hardMutedWords = ref(render($i!.mutedWords));

View file

@ -1,16 +1,12 @@
<template> <template>
<div v-sticky-container class="yrzkoczt"> <div v-sticky-container class="yrzkoczt">
<MkTab v-model="include" class="tab"> <MkTab v-model="include" :options="tabs" class="tab"/>
<option :value="null">{{ i18n.ts.notes }}</option>
<option value="replies">{{ i18n.ts.notesAndReplies }}</option>
<option value="files">{{ i18n.ts.withFiles }}</option>
</MkTab>
<XNotes :no-gap="true" :pagination="pagination"/> <XNotes :no-gap="true" :pagination="pagination"/>
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref, computed } from 'vue'; import { computed } from 'vue';
import * as foundkey from 'foundkey-js'; import * as foundkey from 'foundkey-js';
import XNotes from '@/components/notes.vue'; import XNotes from '@/components/notes.vue';
import MkTab from '@/components/tab.vue'; import MkTab from '@/components/tab.vue';
@ -21,15 +17,26 @@ const props = defineProps<{
user: foundkey.entities.UserDetailed; 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 = { const pagination = {
endpoint: 'users/notes' as const, endpoint: 'users/notes' as const,
limit: 10, limit: 10,
params: computed(() => ({ params: computed(() => ({
userId: props.user.id, userId: props.user.id,
includeReplies: include.value === 'replies', includeReplies: include === 'replies',
withFiles: include.value === 'files', withFiles: include === 'files',
})), })),
}; };
</script> </script>