refactor: Button components (#6929)

* feat: refactor button components

* fix: qa

* fix: storybook

* a11y: pass

* fix: build

* fix: rename default ->md

* fix: lint

* docs: buttons.md

* refactor part 1

* refactor part 2

* fix: undo refactor for fresh restart

* refactor

* Revert "refactor"

This reverts commit 96d65902d7.

* refactor: part 1

* fix: qa

* fix: qa

* fix: qa

* fix: qa

* fix: qa

* fix: qa

* fix: qa

* fix: qa

* fix: remove text-contrast

* fix: qa

* fix: v-tooltip

* fix: lint

* fix: split broken

* fix: passkey qa

* fix: qa

* fix: qa

* fix: prepr

* fix: splitbutton

* improve button group seam

---------

Signed-off-by: Calum H. <calum@modrinth.com>
Co-authored-by: Prospector <6166773+Prospector@users.noreply.github.com>
This commit is contained in:
Calum H.
2026-08-04 13:54:04 -07:00
committed by GitHub
co-authored by Prospector
parent 6cfe999cb3
commit bb2193b6f5
398 changed files with 13688 additions and 13133 deletions
+82 -4
View File
@@ -1,5 +1,5 @@
<template>
<div class="w-full px-2 pt-2">
<div class="w-full p-2">
<UserProfilePageLayout
:user-id="userId"
:project-type="projectType"
@@ -8,16 +8,47 @@
project-link-mode="app"
:edit-profile-link="openProfileSettings"
external-navigation
/>
>
<template #project-actions="{ project }">
<Button
type="outlined"
class="!text-brand [&>svg]:!text-brand !shadow-[inset_0_0_0_1px_var(--color-brand)]"
:disabled="isProjectInstalling(project.id)"
@click.stop="installProject(project)"
>
<SpinnerIcon v-if="isProjectInstalling(project.id)" class="animate-spin" />
<DownloadIcon v-else-if="project.project_type === 'modpack'" />
<PlusIcon v-else />
{{
formatMessage(
isProjectInstalling(project.id)
? commonMessages.installingLabel
: project.project_type === 'modpack'
? commonMessages.installButton
: messages.installToInstance,
)
}}
</Button>
</template>
</UserProfilePageLayout>
</div>
</template>
<script setup lang="ts">
import type { Labrinth } from '@modrinth/api-client'
import { provideUserProfile, UserProfilePageLayout } from '@modrinth/ui'
import { DownloadIcon, PlusIcon, SpinnerIcon } from '@modrinth/assets'
import {
Button,
commonMessages,
defineMessages,
injectNotificationManager,
provideUserProfile,
UserProfilePageLayout,
useVIntl,
} from '@modrinth/ui'
import { useQuery, useQueryClient } from '@tanstack/vue-query'
import { computed, inject, ref, watch } from 'vue'
import { onBeforeRouteUpdate, useRoute } from 'vue-router'
import { onBeforeRouteUpdate, useRoute, useRouter } from 'vue-router'
import {
block_user,
@@ -31,10 +62,57 @@ import {
} from '@/helpers/users'
import { appSettingsModalOpenProfileKey } from '@/providers/app-settings-modal'
import { useBreadcrumb } from '@/providers/breadcrumbs'
import { injectContentInstall } from '@/providers/content-install'
const route = useRoute()
const router = useRouter()
const openProfileSettings = inject(appSettingsModalOpenProfileKey, () => {})
const queryClient = useQueryClient()
const { formatMessage } = useVIntl()
const { handleError } = injectNotificationManager()
const { install: installVersion } = injectContentInstall()
const installingProjectIds = ref(new Set<string>())
const messages = defineMessages({
installToInstance: {
id: 'app.user.project.install-to-instance',
defaultMessage: 'Install to instance',
},
})
function isProjectInstalling(projectId: string): boolean {
return installingProjectIds.value.has(projectId)
}
function setProjectInstalling(projectId: string, installing: boolean): void {
const next = new Set(installingProjectIds.value)
if (installing) {
next.add(projectId)
} else {
next.delete(projectId)
}
installingProjectIds.value = next
}
async function installProject(project: Labrinth.Projects.v2.Project): Promise<void> {
if (isProjectInstalling(project.id)) return
setProjectInstalling(project.id, true)
try {
await installVersion(
project.id,
null,
null,
'UserPage',
() => setProjectInstalling(project.id, false),
(instanceId) => router.push(`/instance/${encodeURIComponent(instanceId)}`),
)
} catch (error) {
setProjectInstalling(project.id, false)
handleError(error)
}
}
const userProfile = provideUserProfile({
getUser: get_user_profile,
getProjects: get_user_projects,