1
0
mirror of https://github.com/misskey-dev/misskey.git synced 2026-05-28 06:35:22 +02:00

refactor(frontend): MkButtonのprops等整理 (#17282)

* refactor(frontend): MkButtonのprops等整理

* fix
This commit is contained in:
かっこかり
2026-04-06 22:28:44 +09:00
committed by GitHub
parent 367766d864
commit ae34578c6f
9 changed files with 63 additions and 40 deletions

View File

@@ -4,14 +4,12 @@ SPDX-License-Identifier: AGPL-3.0-only
--> -->
<template> <template>
<button <component
v-if="!link" :is="component"
ref="el" class="_button" ref="el"
class="_button"
:class="[$style.root, { [$style.inline]: inline, [$style.primary]: primary, [$style.gradate]: gradate, [$style.danger]: danger, [$style.rounded]: rounded, [$style.full]: full, [$style.small]: small, [$style.large]: large, [$style.transparent]: transparent, [$style.asLike]: asLike, [$style.iconOnly]: iconOnly, [$style.wait]: wait, [$style.active]: active }]" :class="[$style.root, { [$style.inline]: inline, [$style.primary]: primary, [$style.gradate]: gradate, [$style.danger]: danger, [$style.rounded]: rounded, [$style.full]: full, [$style.small]: small, [$style.large]: large, [$style.transparent]: transparent, [$style.asLike]: asLike, [$style.iconOnly]: iconOnly, [$style.wait]: wait, [$style.active]: active }]"
:type="type" v-bind="cProps"
:name="name"
:value="value"
:disabled="disabled || wait"
@click="emit('click', $event)" @click="emit('click', $event)"
@mousedown="onMousedown" @mousedown="onMousedown"
> >
@@ -19,34 +17,16 @@ SPDX-License-Identifier: AGPL-3.0-only
<div :class="$style.content"> <div :class="$style.content">
<slot></slot> <slot></slot>
</div> </div>
</button> </component>
<MkA
v-else class="_button"
:class="[$style.root, { [$style.inline]: inline, [$style.primary]: primary, [$style.gradate]: gradate, [$style.danger]: danger, [$style.rounded]: rounded, [$style.full]: full, [$style.small]: small, [$style.large]: large, [$style.transparent]: transparent, [$style.asLike]: asLike, [$style.iconOnly]: iconOnly, [$style.wait]: wait, [$style.active]: active }]"
:to="to ?? '#'"
:behavior="linkBehavior"
@mousedown="onMousedown"
>
<div ref="ripples" :class="$style.ripples" :data-children-class="$style.ripple"></div>
<div :class="$style.content">
<slot></slot>
</div>
</MkA>
</template> </template>
<script lang="ts" setup> <script lang="ts">
import { nextTick, onMounted, useTemplateRef } from 'vue'; interface MkButtonBase {
import type { MkABehavior } from '@/components/global/MkA.vue'; type?: string;
const props = defineProps<{
type?: 'button' | 'submit' | 'reset';
primary?: boolean; primary?: boolean;
gradate?: boolean; gradate?: boolean;
rounded?: boolean; rounded?: boolean;
inline?: boolean; inline?: boolean;
link?: boolean;
to?: string;
linkBehavior?: MkABehavior;
autofocus?: boolean; autofocus?: boolean;
wait?: boolean; wait?: boolean;
danger?: boolean; danger?: boolean;
@@ -55,12 +35,39 @@ const props = defineProps<{
large?: boolean; large?: boolean;
transparent?: boolean; transparent?: boolean;
asLike?: boolean; asLike?: boolean;
iconOnly?: boolean;
active?: boolean;
}
interface MkButtonAsButton extends MkButtonBase {
type?: 'button' | 'submit' | 'reset';
name?: string; name?: string;
value?: string; value?: string;
disabled?: boolean; disabled?: boolean;
iconOnly?: boolean; }
active?: boolean;
}>(); interface MkButtonAsLink extends MkButtonBase {
type: 'a';
href: string;
target?: string;
rel?: string;
}
interface MkButtonAsRouterLink extends MkButtonBase {
type: 'routerLink';
to: string;
linkBehavior?: MkABehavior;
}
export type MkButtonProps = MkButtonAsButton | MkButtonAsLink | MkButtonAsRouterLink;
</script>
<script lang="ts" setup>
import { nextTick, computed, onMounted, useTemplateRef } from 'vue';
import MkA from '@/components/global/MkA.vue';
import type { MkABehavior } from '@/components/global/MkA.vue';
const props = defineProps<MkButtonProps>();
const emit = defineEmits<{ const emit = defineEmits<{
(ev: 'click', payload: PointerEvent): void; (ev: 'click', payload: PointerEvent): void;
@@ -69,6 +76,22 @@ const emit = defineEmits<{
const el = useTemplateRef('el'); const el = useTemplateRef('el');
const ripples = useTemplateRef('ripples'); const ripples = useTemplateRef('ripples');
const component = computed(() => {
if (props.type === 'a') return 'a';
if (props.type === 'routerLink') return MkA;
return 'button';
});
const cProps = computed(() => {
if (props.type === 'a') return { href: props.href ?? '#', target: props.target, rel: props.rel };
if (props.type === 'routerLink') return { to: props.to!, behavior: props.linkBehavior };
return {
type: props.type ?? 'button',
name: props.name,
value: props.value,
disabled: props.disabled || props.wait,
};
});
onMounted(() => { onMounted(() => {
if (props.autofocus) { if (props.autofocus) {
nextTick(() => { nextTick(() => {

View File

@@ -25,7 +25,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</div> </div>
<div class="_gaps_s" :class="$style.mainActions"> <div class="_gaps_s" :class="$style.mainActions">
<MkButton :class="$style.mainAction" full rounded gradate data-cy-signup style="margin-right: 12px;" @click="signup()">{{ i18n.ts.joinThisServer }}</MkButton> <MkButton :class="$style.mainAction" full rounded gradate data-cy-signup style="margin-right: 12px;" @click="signup()">{{ i18n.ts.joinThisServer }}</MkButton>
<MkButton :class="$style.mainAction" full rounded link to="https://misskey-hub.net/servers/">{{ i18n.ts.exploreOtherServers }}</MkButton> <MkButton :class="$style.mainAction" full rounded type="a" target="_blank" rel="noopener" href="https://misskey-hub.net/servers/">{{ i18n.ts.exploreOtherServers }}</MkButton>
<MkButton :class="$style.mainAction" full rounded data-cy-signin @click="signin()">{{ i18n.ts.login }}</MkButton> <MkButton :class="$style.mainAction" full rounded data-cy-signin @click="signin()">{{ i18n.ts.login }}</MkButton>
</div> </div>
</div> </div>

View File

@@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<template> <template>
<div class="_gaps"> <div class="_gaps">
<MkButton v-if="$i && ($i.isModerator || $i.policies.canManageCustomEmojis)" primary link to="/custom-emojis-manager">{{ i18n.ts.manageCustomEmojis }}</MkButton> <MkButton v-if="$i && ($i.isModerator || $i.policies.canManageCustomEmojis)" primary type="routerLink" to="/custom-emojis-manager">{{ i18n.ts.manageCustomEmojis }}</MkButton>
<div class="query"> <div class="query">
<MkInput v-model="q" class="" :placeholder="i18n.ts.search" autocapitalize="off"> <MkInput v-model="q" class="" :placeholder="i18n.ts.search" autocapitalize="off">

View File

@@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<div class="_spacer" style="--MI_SPACER-w: 900px;"> <div class="_spacer" style="--MI_SPACER-w: 900px;">
<div :class="$style.root" class="_gaps"> <div :class="$style.root" class="_gaps">
<div :class="$style.subMenus" class="_gaps"> <div :class="$style.subMenus" class="_gaps">
<MkButton link to="/admin/abuse-report-notification-recipient" primary>{{ i18n.ts.notificationSetting }}</MkButton> <MkButton type="routerLink" to="/admin/abuse-report-notification-recipient" primary>{{ i18n.ts.notificationSetting }}</MkButton>
</div> </div>
<MkTip k="abuses"> <MkTip k="abuses">

View File

@@ -50,7 +50,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</MkPagination> </MkPagination>
</div> </div>
<div v-else-if="tab === 'owned'" class="_gaps"> <div v-else-if="tab === 'owned'" class="_gaps">
<MkButton link primary rounded to="/channels/new"><i class="ti ti-plus"></i> {{ i18n.ts.createNew }}</MkButton> <MkButton type="routerLink" primary rounded to="/channels/new"><i class="ti ti-plus"></i> {{ i18n.ts.createNew }}</MkButton>
<MkPagination v-slot="{items}" :paginator="ownedPaginator"> <MkPagination v-slot="{items}" :paginator="ownedPaginator">
<div :class="$style.root"> <div :class="$style.root">
<MkChannelPreview v-for="channel in items" :key="channel.id" :channel="channel"/> <MkChannelPreview v-for="channel in items" :key="channel.id" :channel="channel"/>

View File

@@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<PageWithHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"> <PageWithHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs">
<div class="_spacer" style="--MI_SPACER-w: 700px;"> <div class="_spacer" style="--MI_SPACER-w: 700px;">
<div class="jqqmcavi"> <div class="jqqmcavi">
<MkButton v-if="pageId && author != null" class="button" inline link :to="`/@${ author.username }/pages/${ currentName }`"><i class="ti ti-external-link"></i> {{ i18n.ts._pages.viewPage }}</MkButton> <MkButton v-if="pageId && author != null" class="button" inline type="routerLink" :to="`/@${ author.username }/pages/${ currentName }`"><i class="ti ti-external-link"></i> {{ i18n.ts._pages.viewPage }}</MkButton>
<MkButton v-if="!readonly" inline primary class="button" @click="save"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</MkButton> <MkButton v-if="!readonly" inline primary class="button" @click="save"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</MkButton>
<MkButton v-if="pageId" inline class="button" @click="duplicate"><i class="ti ti-copy"></i> {{ i18n.ts.duplicate }}</MkButton> <MkButton v-if="pageId" inline class="button" @click="duplicate"><i class="ti ti-copy"></i> {{ i18n.ts.duplicate }}</MkButton>
<MkButton v-if="pageId && !readonly" inline class="button" danger @click="del"><i class="ti ti-trash"></i> {{ i18n.ts.delete }}</MkButton> <MkButton v-if="pageId && !readonly" inline class="button" danger @click="del"><i class="ti ti-trash"></i> {{ i18n.ts.delete }}</MkButton>

View File

@@ -39,7 +39,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<div> <div>
<a :class="$style.qrRoot" :href="twoFactorData.url"><img :class="$style.qr" :src="twoFactorData.qr"></a> <a :class="$style.qrRoot" :href="twoFactorData.url"><img :class="$style.qr" :src="twoFactorData.qr"></a>
<!-- QRコード側にマージンが入っているので直下でOK --> <!-- QRコード側にマージンが入っているので直下でOK -->
<div><MkButton inline rounded link :to="twoFactorData.url" :linkBehavior="'browser'">{{ i18n.ts.launchApp }}</MkButton></div> <div><MkButton inline rounded type="routerLink" :to="twoFactorData.url" :linkBehavior="'browser'">{{ i18n.ts.launchApp }}</MkButton></div>
</div> </div>
<MkKeyValue :copy="twoFactorData.url"> <MkKeyValue :copy="twoFactorData.url">
<template #key>{{ i18n.ts._2fa.step2Uri }}</template> <template #key>{{ i18n.ts._2fa.step2Uri }}</template>

View File

@@ -20,7 +20,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<SearchMarker :keywords="['avatar', 'icon', 'change']"> <SearchMarker :keywords="['avatar', 'icon', 'change']">
<MkButton primary rounded @click="changeAvatar"><SearchLabel>{{ i18n.ts._profile.changeAvatar }}</SearchLabel></MkButton> <MkButton primary rounded @click="changeAvatar"><SearchLabel>{{ i18n.ts._profile.changeAvatar }}</SearchLabel></MkButton>
</SearchMarker> </SearchMarker>
<MkButton primary rounded link to="/settings/avatar-decoration">{{ i18n.ts.decorate }} <i class="ti ti-sparkles"></i></MkButton> <MkButton primary rounded type="routerLink" to="/settings/avatar-decoration">{{ i18n.ts.decorate }} <i class="ti ti-sparkles"></i></MkButton>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -28,7 +28,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<div v-else key="success" class="_gaps_m" style="padding: 32px;"> <div v-else key="success" class="_gaps_m" style="padding: 32px;">
<div :class="$style.mainText">{{ i18n.ts.emailVerified }}</div> <div :class="$style.mainText">{{ i18n.ts.emailVerified }}</div>
<div> <div>
<MkButton large rounded link to="/" linkBehavior="browser" style="margin: 0 auto;"> <MkButton large rounded type="routerLink" to="/" linkBehavior="browser" style="margin: 0 auto;">
{{ i18n.ts.goToMisskey }} {{ i18n.ts.goToMisskey }}
</MkButton> </MkButton>
</div> </div>