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
@@ -15,10 +15,9 @@ import type { RouteLocationRaw } from 'vue-router'
import AutoLink from '#ui/components/base/AutoLink.vue'
import Avatar from '#ui/components/base/Avatar.vue'
import BulletDivider from '#ui/components/base/BulletDivider.vue'
import ButtonStyled from '#ui/components/base/ButtonStyled.vue'
import type { OverflowMenuOption } from '#ui/components/base/buttons'
import { IconButton, TeleportOverflowMenu } from '#ui/components/base/buttons'
import Checkbox from '#ui/components/base/Checkbox.vue'
import type { Option as OverflowMenuOption } from '#ui/components/base/OverflowMenu.vue'
import TeleportOverflowMenu from '#ui/components/base/TeleportOverflowMenu.vue'
import Toggle from '#ui/components/base/Toggle.vue'
import { defineMessages, useVIntl } from '#ui/composables/i18n'
import { commonMessages } from '#ui/utils/common-messages'
@@ -313,43 +312,44 @@ const deleteHovered = ref(false)
v-if="hasUpdateListener || hasSwitchVersionListener"
class="flex w-8 items-center justify-center"
>
<ButtonStyled
<IconButton
v-if="hasUpdate"
circular
type="transparent"
v-tooltip="
isDisabled && disabledTooltip
? disabledTooltip
: formatMessage(commonMessages.updateAvailableLabel)
"
type="quiet"
color="green"
color-fill="text"
hover-color-fill="background"
:label="
isDisabled && disabledTooltip
? disabledTooltip
: formatMessage(commonMessages.updateAvailableLabel)
"
:disabled="isDisabled"
class="hover:!bg-green focus-visible:!bg-green hover:!text-[var(--color-accent-contrast)] focus-visible:!text-[var(--color-accent-contrast)]"
@click="emit('update')"
>
<button
v-tooltip="
isDisabled && disabledTooltip
? disabledTooltip
: formatMessage(commonMessages.updateAvailableLabel)
"
:disabled="isDisabled"
@click="emit('update')"
>
<DownloadIcon class="size-5" />
</button>
</ButtonStyled>
<ButtonStyled
<DownloadIcon class="size-5" />
</IconButton>
<IconButton
v-else-if="hasSwitchVersionListener && version && !hideSwitchVersion"
circular
type="transparent"
v-tooltip="
isDisabled && disabledTooltip
? disabledTooltip
: formatMessage(commonMessages.switchVersionButton)
"
type="quiet"
:label="
isDisabled && disabledTooltip
? disabledTooltip
: formatMessage(commonMessages.switchVersionButton)
"
:disabled="isDisabled"
@click="emit('switchVersion')"
>
<button
v-tooltip="
isDisabled && disabledTooltip
? disabledTooltip
: formatMessage(commonMessages.switchVersionButton)
"
:disabled="isDisabled"
@click="emit('switchVersion')"
>
<ArrowLeftRightIcon class="size-5" />
</button>
</ButtonStyled>
<ArrowLeftRightIcon class="size-5" />
</IconButton>
</div>
<Toggle
@@ -366,46 +366,55 @@ const deleteHovered = ref(false)
@update:model-value="(val) => emit('update:enabled', val as boolean)"
/>
<ButtonStyled v-if="hasDeleteListener && !props.hideDelete" circular type="transparent">
<button
v-tooltip="
isDisabled && disabledTooltip
? disabledTooltip
: formatMessage(
shiftHeld && deleteHovered
? commonMessages.deleteImmediatelyLabel
: commonMessages.deleteLabel,
)
"
:disabled="isDisabled"
@click="emit('delete', $event)"
@mouseenter="deleteHovered = true"
@mouseleave="deleteHovered = false"
>
<span class="relative size-5">
<TrashIcon
class="absolute inset-0 size-5 text-secondary transition-opacity duration-200"
:class="shiftHeld && deleteHovered ? 'opacity-0' : 'opacity-100'"
/>
<TrashExclamationIcon
class="absolute inset-0 size-5 text-red transition-opacity duration-200"
:class="shiftHeld && deleteHovered ? 'opacity-100' : 'opacity-0'"
/>
</span>
</button>
</ButtonStyled>
<IconButton
v-if="hasDeleteListener && !props.hideDelete"
v-tooltip="
isDisabled && disabledTooltip
? disabledTooltip
: formatMessage(
shiftHeld && deleteHovered
? commonMessages.deleteImmediatelyLabel
: commonMessages.deleteLabel,
)
"
type="quiet"
:label="
isDisabled && disabledTooltip
? disabledTooltip
: formatMessage(
shiftHeld && deleteHovered
? commonMessages.deleteImmediatelyLabel
: commonMessages.deleteLabel,
)
"
:disabled="isDisabled"
@click="emit('delete', $event)"
@mouseenter="deleteHovered = true"
@mouseleave="deleteHovered = false"
>
<span class="relative size-5">
<TrashIcon
class="absolute inset-0 size-5 text-secondary transition-opacity duration-200"
:class="shiftHeld && deleteHovered ? 'opacity-0' : 'opacity-100'"
/>
<TrashExclamationIcon
class="absolute inset-0 size-5 text-red transition-opacity duration-200"
:class="shiftHeld && deleteHovered ? 'opacity-100' : 'opacity-0'"
/>
</span>
</IconButton>
<slot name="additionalButtonsRight" />
<ButtonStyled circular type="transparent">
<TeleportOverflowMenu
v-if="overflowOptions?.length"
:options="overflowOptions"
:disabled="isDisabled"
>
<MoreVerticalIcon class="size-5" />
</TeleportOverflowMenu>
</ButtonStyled>
<TeleportOverflowMenu
v-if="overflowOptions?.length"
type="quiet"
label="More options"
:options="overflowOptions"
:disabled="isDisabled"
>
<MoreVerticalIcon class="size-5" />
</TeleportOverflowMenu>
</div>
</div>
</template>