summaryrefslogtreecommitdiff
path: root/packages/frontend
diff options
context:
space:
mode:
authorかっこかり <67428053+kakkokari-gtyih@users.noreply.github.com>2025-10-05 15:48:11 +0900
committerGitHub <noreply@github.com>2025-10-05 15:48:11 +0900
commit720c6519cdca2b2c969cb5d8ce2de0145005b432 (patch)
tree6a72acfb95453c5bc1e038aaac7da3ca53ce6878 /packages/frontend
parentUpdate CHANGELOG with new features and enhancements (diff)
downloadmisskey-720c6519cdca2b2c969cb5d8ce2de0145005b432.tar.gz
misskey-720c6519cdca2b2c969cb5d8ce2de0145005b432.tar.bz2
misskey-720c6519cdca2b2c969cb5d8ce2de0145005b432.zip
refactor(frontend): MkTabの指定をpropsから行うように (#16596)
* refactor(frontend): MkTabの指定をpropsから行うように * Update explore.featured.vue
Diffstat (limited to 'packages/frontend')
-rw-r--r--packages/frontend/src/components/MkTab.vue111
-rw-r--r--packages/frontend/src/pages/explore.featured.vue13
-rw-r--r--packages/frontend/src/pages/explore.users.vue14
-rw-r--r--packages/frontend/src/pages/qr.read.vue13
-rw-r--r--packages/frontend/src/pages/user/index.timeline.vue17
-rw-r--r--packages/frontend/src/pages/user/notes.vue17
6 files changed, 110 insertions, 75 deletions
diff --git a/packages/frontend/src/components/MkTab.vue b/packages/frontend/src/components/MkTab.vue
index f557ffa5dc..d8ae52482e 100644
--- a/packages/frontend/src/components/MkTab.vue
+++ b/packages/frontend/src/components/MkTab.vue
@@ -3,76 +3,85 @@ SPDX-FileCopyrightText: syuilo and misskey-project
SPDX-License-Identifier: AGPL-3.0-only
-->
+<template>
+ <div :class="$style.tabsRoot">
+ <button
+ v-for="option in tabs"
+ :key="option.key"
+ :class="['_button', $style.tabButton, { [$style.active]: modelValue === option.key }]"
+ :disabled="modelValue === option.key"
+ @click="update(option.key)"
+ >
+ <i v-if="option.icon" :class="[option.icon, $style.icon]"></i>
+ {{ option.label }}
+ </button>
+ </div>
+</template>
+
<script lang="ts">
-import { defineComponent, h, resolveDirective, withDirectives } from 'vue';
+export type Tab<T = string> = {
+ key: T;
+ icon?: string;
+ label?: string;
+};
+</script>
+
+<script setup lang="ts" generic="const T extends Tab">
+import { defineProps, defineEmits } from 'vue';
-export default defineComponent({
- props: {
- modelValue: {
- required: true,
- },
- },
- setup(props, { emit, slots }) {
- const options = slots.default?.() ?? [];
+defineProps<{
+ tabs: T[];
+}>();
- return () => h('div', {
- class: 'pxhvhrfw',
- }, options.map(option => withDirectives(h('button', {
- class: ['_button', { active: props.modelValue === option.props?.value }],
- key: option.key as string,
- disabled: props.modelValue === option.props?.value,
- onClick: () => {
- emit('update:modelValue', option.props?.value);
- },
- }, option.children ?? []), [
- [resolveDirective('click-anime')],
- ])));
- },
-});
+const model = defineModel<T['key']>();
+
+function update(key: T['key']) {
+ model.value = key;
+}
</script>
-<style lang="scss">
-.pxhvhrfw {
+<style module lang="scss">
+.tabsRoot {
display: flex;
font-size: 90%;
+}
- > button {
- flex: 1;
- padding: 10px 8px;
- border-radius: 999px;
+.tabButton {
+ flex: 1;
+ padding: 10px 8px;
+ border-radius: 999px;
- &:disabled {
- opacity: 1 !important;
- cursor: default;
- }
+ &:disabled {
+ opacity: 1 !important;
+ cursor: default;
+ }
- &.active {
- color: var(--MI_THEME-accent);
- background: var(--MI_THEME-accentedBg);
- }
+ &.active {
+ color: var(--MI_THEME-accent);
+ background: var(--MI_THEME-accentedBg);
+ }
- &:not(.active):hover {
- color: var(--MI_THEME-fgHighlighted);
- background: var(--MI_THEME-panelHighlight);
- }
+ &:not(.active):hover {
+ color: var(--MI_THEME-fgHighlighted);
+ background: var(--MI_THEME-panelHighlight);
+ }
- &:not(:first-child) {
- margin-left: 8px;
- }
+ &:not(:first-child) {
+ margin-left: 8px;
+ }
- > .icon {
- margin-right: 6px;
- }
+ > .icon {
+ margin-right: 6px;
}
}
@container (max-width: 500px) {
- .pxhvhrfw {
+ .tabsRoot {
font-size: 80%;
+ }
- > button {
- padding: 11px 8px;
- }
+ .tabButton {
+ padding: 11px 8px;
}
}
</style>
diff --git a/packages/frontend/src/pages/explore.featured.vue b/packages/frontend/src/pages/explore.featured.vue
index abb816a956..3158b384d2 100644
--- a/packages/frontend/src/pages/explore.featured.vue
+++ b/packages/frontend/src/pages/explore.featured.vue
@@ -5,9 +5,14 @@ SPDX-License-Identifier: AGPL-3.0-only
<template>
<div class="_spacer" style="--MI_SPACER-w: 800px;">
- <MkTab v-model="tab" style="margin-bottom: var(--MI-margin);">
- <option value="notes">{{ i18n.ts.notes }}</option>
- <option value="polls">{{ i18n.ts.poll }}</option>
+ <MkTab
+ v-model="tab"
+ :tabs="[
+ { key: 'notes', label: i18n.ts.notes },
+ { key: 'polls', label: i18n.ts.poll },
+ ]"
+ style="margin-bottom: var(--MI-margin);"
+ >
</MkTab>
<MkNotesTimeline v-if="tab === 'notes'" :paginator="paginatorForNotes"/>
<MkNotesTimeline v-else-if="tab === 'polls'" :paginator="paginatorForPolls"/>
@@ -33,5 +38,5 @@ const paginatorForPolls = markRaw(new Paginator('notes/polls/recommendation', {
},
}));
-const tab = ref('notes');
+const tab = ref<'notes' | 'polls'>('notes');
</script>
diff --git a/packages/frontend/src/pages/explore.users.vue b/packages/frontend/src/pages/explore.users.vue
index 08f9f5e582..4e3fb16b5a 100644
--- a/packages/frontend/src/pages/explore.users.vue
+++ b/packages/frontend/src/pages/explore.users.vue
@@ -5,9 +5,15 @@ SPDX-License-Identifier: AGPL-3.0-only
<template>
<div class="_spacer" style="--MI_SPACER-w: 1200px;">
- <MkTab v-if="instance.federation !== 'none'" v-model="origin" style="margin-bottom: var(--MI-margin);">
- <option value="local">{{ i18n.ts.local }}</option>
- <option value="remote">{{ i18n.ts.remote }}</option>
+ <MkTab
+ v-if="instance.federation !== 'none'"
+ v-model="origin"
+ :tabs="[
+ { key: 'local', label: i18n.ts.local },
+ { key: 'remote', label: i18n.ts.remote },
+ ]"
+ style="margin-bottom: var(--MI-margin);"
+ >
</MkTab>
<div v-if="origin === 'local'">
<template v-if="tag == null">
@@ -77,7 +83,7 @@ const props = defineProps<{
tag?: string;
}>();
-const origin = ref('local');
+const origin = ref<'local' | 'remote'>('local');
const tagsLocal = ref<Misskey.entities.Hashtag[]>([]);
const tagsRemote = ref<Misskey.entities.Hashtag[]>([]);
diff --git a/packages/frontend/src/pages/qr.read.vue b/packages/frontend/src/pages/qr.read.vue
index e4c475196a..251dccd0f0 100644
--- a/packages/frontend/src/pages/qr.read.vue
+++ b/packages/frontend/src/pages/qr.read.vue
@@ -39,10 +39,15 @@ SPDX-License-Identifier: AGPL-3.0-only
>
<MkStickyContainer>
<template #header>
- <MkTab v-model="tab" :class="$style.tab">
- <option value="users">{{ i18n.ts.users }}</option>
- <option value="notes">{{ i18n.ts.notes }}</option>
- <option value="all">{{ i18n.ts.all }}</option>
+ <MkTab
+ v-model="tab"
+ :tabs="[
+ { key: 'users', label: i18n.ts.users },
+ { key: 'notes', label: i18n.ts.notes },
+ { key: 'all', label: i18n.ts.all },
+ ]"
+ :class="$style.tab"
+ >
</MkTab>
</template>
<div v-if="tab === 'users'" :class="[$style.users, '_margin']" style="padding-bottom: var(--MI-margin);">
diff --git a/packages/frontend/src/pages/user/index.timeline.vue b/packages/frontend/src/pages/user/index.timeline.vue
index 5e9e671252..6d74de14a0 100644
--- a/packages/frontend/src/pages/user/index.timeline.vue
+++ b/packages/frontend/src/pages/user/index.timeline.vue
@@ -6,11 +6,16 @@ SPDX-License-Identifier: AGPL-3.0-only
<template>
<MkStickyContainer>
<template #header>
- <MkTab v-model="tab" :class="$style.tab">
- <option value="featured">{{ i18n.ts.featured }}</option>
- <option value="notes">{{ i18n.ts.notes }}</option>
- <option value="all">{{ i18n.ts.all }}</option>
- <option value="files">{{ i18n.ts.withFiles }}</option>
+ <MkTab
+ v-model="tab"
+ :tabs="[
+ { key: 'featured', label: i18n.ts.featured },
+ { key: 'notes', label: i18n.ts.notes },
+ { key: 'all', label: i18n.ts.all },
+ { key: 'files', label: i18n.ts.withFiles },
+ ]"
+ :class="$style.tab"
+ >
</MkTab>
</template>
<MkNotesTimeline v-if="tab === 'featured'" :noGap="true" :paginator="featuredPaginator" :pullToRefresh="false" :class="$style.tl"/>
@@ -30,7 +35,7 @@ const props = defineProps<{
user: Misskey.entities.UserDetailed;
}>();
-const tab = ref<string>('all');
+const tab = ref<'featured' | 'notes' | 'all' | 'files'>('all');
const featuredPaginator = markRaw(new Paginator('users/featured-notes', {
limit: 10,
diff --git a/packages/frontend/src/pages/user/notes.vue b/packages/frontend/src/pages/user/notes.vue
index b5e600da92..1e6dba73bd 100644
--- a/packages/frontend/src/pages/user/notes.vue
+++ b/packages/frontend/src/pages/user/notes.vue
@@ -8,11 +8,16 @@ SPDX-License-Identifier: AGPL-3.0-only
<div :class="$style.root">
<MkStickyContainer>
<template #header>
- <MkTab v-model="tab" :class="$style.tab">
- <option value="featured">{{ i18n.ts.featured }}</option>
- <option value="notes">{{ i18n.ts.notes }}</option>
- <option value="all">{{ i18n.ts.all }}</option>
- <option value="files">{{ i18n.ts.withFiles }}</option>
+ <MkTab
+ v-model="tab"
+ :tabs="[
+ { key: 'featured', label: i18n.ts.featured },
+ { key: 'notes', label: i18n.ts.notes },
+ { key: 'all', label: i18n.ts.all },
+ { key: 'files', label: i18n.ts.withFiles },
+ ]"
+ :class="$style.tab"
+ >
</MkTab>
</template>
<MkNotesTimeline v-if="tab === 'featured'" :noGap="true" :paginator="featuredPaginator" :class="$style.tl"/>
@@ -34,7 +39,7 @@ const props = defineProps<{
user: Misskey.entities.UserDetailed;
}>();
-const tab = ref<string>('all');
+const tab = ref<'featured' | 'notes' | 'all' | 'files'>('all');
const featuredPaginator = markRaw(new Paginator('users/featured-notes', {
limit: 10,