feat(frontend): add danger prop to XButton component (#2078)

The is-danger class no longer worked on XButton because the component uses scoped CSS. This adds a proper danger boolean prop that applies danger styling (red background) as a color modifier that works alongside any variant (primary, secondary, tertiary).
This commit is contained in:
kolaente 2026-01-10 18:22:19 +01:00 committed by GitHub
parent 534483f237
commit 9a3e79af8e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 70 additions and 9 deletions

View File

@ -6,6 +6,7 @@
{
'is-loading': loading,
'has-no-shadow': !shadow || variant === 'tertiary',
'is-danger': danger,
}
]"
:disabled="disabled || loading"
@ -58,6 +59,7 @@ export interface ButtonProps {
disabled?: boolean
shadow?: boolean
wrap?: boolean
danger?: boolean
}
defineOptions({name: 'XButton'})
@ -168,6 +170,65 @@ const variantClass = computed<string>(() => VARIANT_CLASS_MAP[variant.value])
color: inherit;
}
// Danger modifier - solid filled button (default and primary variant)
&.is-danger {
background-color: var(--danger);
border-color: transparent;
color: var(--white);
&:hover {
background-color: var(--danger-dark);
border-color: transparent;
}
&:focus,
&:focus-visible {
outline-color: var(--danger);
&:not(:active) {
box-shadow: 0 0 0 0.125em hsla(var(--danger-h), var(--danger-s), var(--danger-l), 0.25);
}
}
&:active {
background-color: var(--danger-dark);
border-color: transparent;
}
}
// Danger + outlined/secondary variant
&.is-danger.is-outlined {
background-color: transparent;
border: 1px solid var(--danger);
color: var(--danger);
&:hover,
&:focus {
background-color: var(--danger);
border-color: var(--danger);
color: var(--white);
}
}
// Danger + text/tertiary variant
&.is-danger.is-text {
background-color: transparent;
color: var(--danger);
&:hover {
background-color: hsla(var(--danger-h), var(--danger-s), var(--danger-l), 0.1);
}
}
// Danger loading spinner - white on solid, danger-colored on outlined/text
&.is-danger.is-loading::after {
border-color: transparent transparent var(--white) var(--white);
}
&.is-danger.is-outlined.is-loading::after,
&.is-danger.is-text.is-loading::after {
border-color: transparent transparent var(--danger) var(--danger);
}
// Loading state
&.is-loading {
color: transparent !important;

View File

@ -186,7 +186,7 @@
</td>
<td class="actions">
<XButton
class="is-danger"
danger
icon="trash-alt"
@click="
() => {

View File

@ -121,7 +121,7 @@
</select>
</div>
<XButton
class="is-danger"
danger
icon="trash-alt"
@click="
() => {

View File

@ -99,7 +99,7 @@
<div class="control">
<XButton
icon="trash-alt"
class="is-danger"
danger
@click="showDeleteDialoge(labelEditLabel)"
/>
</div>

View File

@ -90,7 +90,7 @@
v-if="hasBackground"
:shadow="false"
variant="tertiary"
class="is-danger"
danger
@click.prevent.stop="removeBackground"
>
{{ $t('project.background.remove') }}

View File

@ -245,7 +245,7 @@ function validateSelectedEvents() {
<td class="actions">
<XButton
class="is-danger"
danger
icon="trash-alt"
@click="() => {showDeleteModal = true;webhookIdToDelete = w.id}"
/>

View File

@ -84,7 +84,7 @@
<div class="control">
<XButton
:loading="teamService.loading"
class="is-danger"
danger
icon="trash-alt"
@click="showDeleteModal = true"
/>
@ -184,7 +184,7 @@
<XButton
v-if="m.id !== userInfo.id"
:loading="teamMemberService.loading"
class="is-danger"
danger
icon="trash-alt"
@click="() => {memberToDelete = m; showUserDeleteModal = true}"
/>

View File

@ -51,7 +51,7 @@
</p>
<p v-if="!totpDisableForm">
<XButton
class="is-danger"
danger
@click="totpDisableForm = true"
>
{{ $t('misc.disable') }}
@ -76,7 +76,7 @@
</div>
</div>
<XButton
class="is-danger"
danger
@click="totpDisable"
>
{{ $t('user.settings.totp.disable') }}