refactor: improve button component styles (#7517)

#### What type of PR is this?

/area ui
/kind improvement
/milestone 2.21.x

#### What this PR does / why we need it:

1. Add ghost variant
2. Improve icon style
3. Refactoring css using scss functions

#### Does this PR introduce a user-facing change?

```release-note
None
```
pull/7521/head^2
Ryan Wang 2025-06-09 23:38:34 +08:00 committed by GitHub
parent 63d40d4d40
commit 204113bd87
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
33 changed files with 228 additions and 154 deletions

View File

@ -260,7 +260,7 @@ watch(
@click="policyVisible = true" @click="policyVisible = true"
> >
<template #icon> <template #icon>
<IconDatabase2Line class="h-full w-full" /> <IconDatabase2Line />
</template> </template>
{{ $t("core.attachment.actions.storage_policies") }} {{ $t("core.attachment.actions.storage_policies") }}
</VButton> </VButton>
@ -270,7 +270,7 @@ watch(
@click="uploadVisible = true" @click="uploadVisible = true"
> >
<template #icon> <template #icon>
<IconUpload class="h-full w-full" /> <IconUpload />
</template> </template>
{{ $t("core.common.buttons.upload") }} {{ $t("core.common.buttons.upload") }}
</VButton> </VButton>
@ -475,7 +475,7 @@ watch(
@click="uploadVisible = true" @click="uploadVisible = true"
> >
<template #icon> <template #icon>
<IconUpload class="h-full w-full" /> <IconUpload />
</template> </template>
{{ $t("core.attachment.empty.actions.upload") }} {{ $t("core.attachment.empty.actions.upload") }}
</VButton> </VButton>

View File

@ -141,7 +141,7 @@ function getPolicyTemplateDisplayName(templateName: string) {
<VDropdown> <VDropdown>
<VButton type="secondary"> <VButton type="secondary">
<template #icon> <template #icon>
<IconAddCircle class="h-full w-full" /> <IconAddCircle />
</template> </template>
{{ $t("core.common.buttons.new") }} {{ $t("core.common.buttons.new") }}
</VButton> </VButton>

View File

@ -265,7 +265,7 @@ const viewType = useLocalStorage("attachment-selector-view-type", "grid");
<div class="mb-5"> <div class="mb-5">
<VButton @click="uploadVisible = true"> <VButton @click="uploadVisible = true">
<template #icon> <template #icon>
<IconUpload class="h-full w-full" /> <IconUpload />
</template> </template>
{{ $t("core.common.buttons.upload") }} {{ $t("core.common.buttons.upload") }}
</VButton> </VButton>
@ -286,7 +286,7 @@ const viewType = useLocalStorage("attachment-selector-view-type", "grid");
</VButton> </VButton>
<VButton type="secondary" @click="uploadVisible = true"> <VButton type="secondary" @click="uploadVisible = true">
<template #icon> <template #icon>
<IconUpload class="h-full w-full" /> <IconUpload />
</template> </template>
{{ $t("core.attachment.empty.actions.upload") }} {{ $t("core.attachment.empty.actions.upload") }}
</VButton> </VButton>

View File

@ -382,7 +382,7 @@ const { operationItems } = useOperationItemExtensionPoint<ListedComment>(
</VButton> </VButton>
<VButton type="secondary" @click="replyModal = true"> <VButton type="secondary" @click="replyModal = true">
<template #icon> <template #icon>
<IconAddCircle class="h-full w-full" /> <IconAddCircle />
</template> </template>
{{ $t("core.comment.reply_empty.new") }} {{ $t("core.comment.reply_empty.new") }}
</VButton> </VButton>

View File

@ -217,7 +217,7 @@ watch(
type="secondary" type="secondary"
> >
<template #icon> <template #icon>
<IconAddCircle class="h-full w-full" /> <IconAddCircle />
</template> </template>
{{ $t("core.common.buttons.new") }} {{ $t("core.common.buttons.new") }}
</VButton> </VButton>

View File

@ -486,7 +486,7 @@ async function handleUploadImage(file: File, options?: AxiosRequestConfig) {
" "
> >
<template #icon> <template #icon>
<IconHistoryLine class="h-full w-full" /> <IconHistoryLine />
</template> </template>
{{ $t("core.page_editor.actions.snapshots") }} {{ $t("core.page_editor.actions.snapshots") }}
</VButton> </VButton>
@ -497,13 +497,13 @@ async function handleUploadImage(file: File, options?: AxiosRequestConfig) {
@click="handlePreview" @click="handlePreview"
> >
<template #icon> <template #icon>
<IconEye class="h-full w-full" /> <IconEye />
</template> </template>
{{ $t("core.common.buttons.preview") }} {{ $t("core.common.buttons.preview") }}
</VButton> </VButton>
<VButton :loading="saving" size="sm" type="default" @click="handleSave"> <VButton :loading="saving" size="sm" type="default" @click="handleSave">
<template #icon> <template #icon>
<IconSave class="h-full w-full" /> <IconSave />
</template> </template>
{{ $t("core.common.buttons.save") }} {{ $t("core.common.buttons.save") }}
</VButton> </VButton>
@ -514,7 +514,7 @@ async function handleUploadImage(file: File, options?: AxiosRequestConfig) {
@click="handleOpenSettingModal" @click="handleOpenSettingModal"
> >
<template #icon> <template #icon>
<IconSettings class="h-full w-full" /> <IconSettings />
</template> </template>
{{ $t("core.common.buttons.setting") }} {{ $t("core.common.buttons.setting") }}
</VButton> </VButton>
@ -524,7 +524,7 @@ async function handleUploadImage(file: File, options?: AxiosRequestConfig) {
@click="handlePublishClick" @click="handlePublishClick"
> >
<template #icon> <template #icon>
<IconSendPlaneFill class="h-full w-full" /> <IconSendPlaneFill />
</template> </template>
{{ $t("core.common.buttons.publish") }} {{ $t("core.common.buttons.publish") }}
</VButton> </VButton>

View File

@ -298,7 +298,7 @@ watch(selectedPageNames, (newValue) => {
type="secondary" type="secondary"
> >
<template #icon> <template #icon>
<IconAddCircle class="h-full w-full" /> <IconAddCircle />
</template> </template>
{{ $t("core.common.buttons.new") }} {{ $t("core.common.buttons.new") }}
</VButton> </VButton>
@ -436,7 +436,7 @@ watch(selectedPageNames, (newValue) => {
type="secondary" type="secondary"
> >
<template #icon> <template #icon>
<IconAddCircle class="h-full w-full" /> <IconAddCircle />
</template> </template>
{{ $t("core.common.buttons.new") }} {{ $t("core.common.buttons.new") }}
</VButton> </VButton>

View File

@ -468,6 +468,7 @@ const { handleGenerateSlug } = useSlugify(
" "
:loading="publishCanceling" :loading="publishCanceling"
type="danger" type="danger"
ghost
@click="handleUnpublish()" @click="handleUnpublish()"
> >
{{ $t("core.common.buttons.cancel_publish") }} {{ $t("core.common.buttons.cancel_publish") }}

View File

@ -227,7 +227,7 @@ watch(
type="secondary" type="secondary"
> >
<template #icon> <template #icon>
<IconAddCircle class="h-full w-full" /> <IconAddCircle />
</template> </template>
{{ $t("core.common.buttons.new") }} {{ $t("core.common.buttons.new") }}
</VButton> </VButton>

View File

@ -522,7 +522,7 @@ useSlugify(
" "
> >
<template #icon> <template #icon>
<IconHistoryLine class="h-full w-full" /> <IconHistoryLine />
</template> </template>
{{ $t("core.post_editor.actions.snapshots") }} {{ $t("core.post_editor.actions.snapshots") }}
</VButton> </VButton>
@ -533,13 +533,13 @@ useSlugify(
@click="handlePreview" @click="handlePreview"
> >
<template #icon> <template #icon>
<IconEye class="h-full w-full" /> <IconEye />
</template> </template>
{{ $t("core.common.buttons.preview") }} {{ $t("core.common.buttons.preview") }}
</VButton> </VButton>
<VButton :loading="saving" size="sm" type="default" @click="handleSave"> <VButton :loading="saving" size="sm" type="default" @click="handleSave">
<template #icon> <template #icon>
<IconSave class="h-full w-full" /> <IconSave />
</template> </template>
{{ $t("core.common.buttons.save") }} {{ $t("core.common.buttons.save") }}
</VButton> </VButton>
@ -550,7 +550,7 @@ useSlugify(
@click="handleOpenSettingModal" @click="handleOpenSettingModal"
> >
<template #icon> <template #icon>
<IconSettings class="h-full w-full" /> <IconSettings />
</template> </template>
{{ $t("core.common.buttons.setting") }} {{ $t("core.common.buttons.setting") }}
</VButton> </VButton>
@ -560,7 +560,7 @@ useSlugify(
@click="handlePublishClick" @click="handlePublishClick"
> >
<template #icon> <template #icon>
<IconSendPlaneFill class="h-full w-full" /> <IconSendPlaneFill />
</template> </template>
{{ $t("core.common.buttons.publish") }} {{ $t("core.common.buttons.publish") }}
</VButton> </VButton>

View File

@ -404,7 +404,7 @@ watch(
type="secondary" type="secondary"
> >
<template #icon> <template #icon>
<IconAddCircle class="h-full w-full" /> <IconAddCircle />
</template> </template>
{{ $t("core.common.buttons.new") }} {{ $t("core.common.buttons.new") }}
</VButton> </VButton>
@ -583,7 +583,7 @@ watch(
type="secondary" type="secondary"
> >
<template #icon> <template #icon>
<IconAddCircle class="h-full w-full" /> <IconAddCircle />
</template> </template>
{{ $t("core.common.buttons.new") }} {{ $t("core.common.buttons.new") }}
</VButton> </VButton>

View File

@ -74,7 +74,7 @@ async function handleUpdateInBatch() {
@click="creationModal = true" @click="creationModal = true"
> >
<template #icon> <template #icon>
<IconAddCircle class="h-full w-full" /> <IconAddCircle />
</template> </template>
{{ $t("core.common.buttons.new") }} {{ $t("core.common.buttons.new") }}
</VButton> </VButton>
@ -116,7 +116,7 @@ async function handleUpdateInBatch() {
@click="creationModal = true" @click="creationModal = true"
> >
<template #icon> <template #icon>
<IconAddCircle class="h-full w-full" /> <IconAddCircle />
</template> </template>
{{ $t("core.common.buttons.new") }} {{ $t("core.common.buttons.new") }}
</VButton> </VButton>

View File

@ -498,6 +498,7 @@ const showCancelPublishButton = computed(() => {
v-if="showCancelPublishButton" v-if="showCancelPublishButton"
:loading="publishCanceling" :loading="publishCanceling"
type="danger" type="danger"
ghost
@click="handleUnpublish()" @click="handleUnpublish()"
> >
{{ $t("core.common.buttons.cancel_publish") }} {{ $t("core.common.buttons.cancel_publish") }}

View File

@ -173,7 +173,7 @@ watch(selectedTagNames, (newVal) => {
@click="editingModal = true" @click="editingModal = true"
> >
<template #icon> <template #icon>
<IconAddCircle class="h-full w-full" /> <IconAddCircle />
</template> </template>
{{ $t("core.common.buttons.new") }} {{ $t("core.common.buttons.new") }}
</VButton> </VButton>
@ -274,7 +274,7 @@ watch(selectedTagNames, (newVal) => {
</VButton> </VButton>
<VButton type="secondary" @click="editingModal = true"> <VButton type="secondary" @click="editingModal = true">
<template #icon> <template #icon>
<IconAddCircle class="h-full w-full" /> <IconAddCircle />
</template> </template>
{{ $t("core.common.buttons.new") }} {{ $t("core.common.buttons.new") }}
</VButton> </VButton>

View File

@ -43,7 +43,7 @@ provide<ComputedRef<DashboardWidgetDefinition[]>>(
@click="$router.push({ name: 'DashboardDesigner' })" @click="$router.push({ name: 'DashboardDesigner' })"
> >
<template #icon> <template #icon>
<IconSettings class="h-full w-full" /> <IconSettings />
</template> </template>
{{ $t("core.dashboard.actions.setting") }} {{ $t("core.dashboard.actions.setting") }}
</VButton> </VButton>

View File

@ -37,7 +37,6 @@ import {
import type { GridLayout } from "vue-grid-layout"; import type { GridLayout } from "vue-grid-layout";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { onBeforeRouteLeave, useRouter } from "vue-router"; import { onBeforeRouteLeave, useRouter } from "vue-router";
import RiArrowGoBackLine from "~icons/ri/arrow-go-back-line";
import RiBox3Line from "~icons/ri/box-3-line"; import RiBox3Line from "~icons/ri/box-3-line";
import RiFileCopyLine from "~icons/ri/file-copy-line"; import RiFileCopyLine from "~icons/ri/file-copy-line";
import WidgetEditableItem from "./components/WidgetEditableItem.vue"; import WidgetEditableItem from "./components/WidgetEditableItem.vue";
@ -339,16 +338,13 @@ function handleCopyFromLayout(breakpoint: string) {
></VTabbar> ></VTabbar>
</div> </div>
<VSpace> <VSpace>
<VButton @click="handleBack"> <VButton ghost @click="handleBack">
<template #icon>
<RiArrowGoBackLine class="h-full w-full" />
</template>
{{ $t("core.common.buttons.back") }} {{ $t("core.common.buttons.back") }}
</VButton> </VButton>
<VDropdown> <VDropdown>
<VButton> <VButton>
<template #icon> <template #icon>
<IconAddCircle class="h-full w-full" /> <IconAddCircle />
</template> </template>
{{ $t("core.dashboard_designer.actions.add_widget") }} {{ $t("core.dashboard_designer.actions.add_widget") }}
</VButton> </VButton>
@ -396,7 +392,7 @@ function handleCopyFromLayout(breakpoint: string) {
@click="handleSave" @click="handleSave"
> >
<template #icon> <template #icon>
<IconSave class="h-full w-full" /> <IconSave />
</template> </template>
{{ $t("core.common.buttons.save") }} {{ $t("core.common.buttons.save") }}
</VButton> </VButton>

View File

@ -298,7 +298,7 @@ function getMenuItemRefDisplayName(menuItem: MenuTreeItem) {
@click="menuItemEditingModal = true" @click="menuItemEditingModal = true"
> >
<template #icon> <template #icon>
<IconAddCircle class="h-full w-full" /> <IconAddCircle />
</template> </template>
{{ $t("core.common.buttons.new") }} {{ $t("core.common.buttons.new") }}
</VButton> </VButton>

View File

@ -85,7 +85,7 @@ const handleOpenPreview = (theme: Theme) => {
@click="activeTabId = 'local-upload'" @click="activeTabId = 'local-upload'"
> >
<template #icon> <template #icon>
<IconAddCircle class="h-full w-full" /> <IconAddCircle />
</template> </template>
{{ $t("core.theme.common.buttons.install") }} {{ $t("core.theme.common.buttons.install") }}
</VButton> </VButton>

View File

@ -210,13 +210,13 @@ onMounted(() => {
</VButton> </VButton>
<VButton type="default" size="sm" @click="previewModal = true"> <VButton type="default" size="sm" @click="previewModal = true">
<template #icon> <template #icon>
<IconEye class="h-full w-full" /> <IconEye />
</template> </template>
{{ $t("core.common.buttons.preview") }} {{ $t("core.common.buttons.preview") }}
</VButton> </VButton>
<VButton type="secondary" @click="themesModal = true"> <VButton type="secondary" @click="themesModal = true">
<template #icon> <template #icon>
<IconListSettings class="h-full w-full" /> <IconListSettings />
</template> </template>
{{ $t("core.theme.actions.management") }} {{ $t("core.theme.actions.management") }}
</VButton> </VButton>
@ -237,7 +237,7 @@ onMounted(() => {
</VButton> </VButton>
<VButton type="secondary" @click="themesModal = true"> <VButton type="secondary" @click="themesModal = true">
<template #icon> <template #icon>
<IconExchange class="h-full w-full" /> <IconExchange />
</template> </template>
{{ $t("core.theme.empty.actions.switch") }} {{ $t("core.theme.empty.actions.switch") }}
</VButton> </VButton>

View File

@ -68,7 +68,7 @@ onMounted(async () => {
<template #actions> <template #actions>
<VButton type="secondary" @click="handleCreate"> <VButton type="secondary" @click="handleCreate">
<template #icon> <template #icon>
<IconAddCircle class="h-full w-full" /> <IconAddCircle />
</template> </template>
{{ $t("core.backup.operations.create.button") }} {{ $t("core.backup.operations.create.button") }}
</VButton> </VButton>

View File

@ -200,7 +200,7 @@ const handleDownloadLogfile = () => {
<template #actions> <template #actions>
<VButton size="sm" @click="handleCopy"> <VButton size="sm" @click="handleCopy">
<template #icon> <template #icon>
<IconClipboardLine class="h-full w-full" /> <IconClipboardLine />
</template> </template>
{{ $t("core.common.buttons.copy") }} {{ $t("core.common.buttons.copy") }}
</VButton> </VButton>

View File

@ -169,7 +169,7 @@ onMounted(() => {
@click="$router.push({ name: 'PluginExtensionPointSettings' })" @click="$router.push({ name: 'PluginExtensionPointSettings' })"
> >
<template #icon> <template #icon>
<IconSettings class="h-full w-full" /> <IconSettings />
</template> </template>
{{ $t("core.plugin.actions.extension-point-settings") }} {{ $t("core.plugin.actions.extension-point-settings") }}
</VButton> </VButton>
@ -181,7 +181,7 @@ onMounted(() => {
@click="pluginInstallationModalVisible = true" @click="pluginInstallationModalVisible = true"
> >
<template #icon> <template #icon>
<IconAddCircle class="h-full w-full" /> <IconAddCircle />
</template> </template>
{{ $t("core.common.buttons.install") }} {{ $t("core.common.buttons.install") }}
</VButton> </VButton>
@ -314,7 +314,7 @@ onMounted(() => {
@click="pluginInstallationModalVisible = true" @click="pluginInstallationModalVisible = true"
> >
<template #icon> <template #icon>
<IconAddCircle class="h-full w-full" /> <IconAddCircle />
</template> </template>
{{ $t("core.plugin.empty.actions.install") }} {{ $t("core.plugin.empty.actions.install") }}
</VButton> </VButton>

View File

@ -38,7 +38,7 @@ function handleReloadWindow() {
<template> <template>
<VButton v-if="needsReloadWindow" size="xs" @click="handleReloadWindow"> <VButton v-if="needsReloadWindow" size="xs" @click="handleReloadWindow">
<template #icon> <template #icon>
<IconInformation class="h-full w-full" /> <IconInformation />
</template> </template>
{{ $t("core.plugin.operations.reload_window.button") }} {{ $t("core.plugin.operations.reload_window.button") }}
</VButton> </VButton>

View File

@ -216,7 +216,7 @@ const handleDelete = async (role: Role) => {
@click="editingModal = true" @click="editingModal = true"
> >
<template #icon> <template #icon>
<IconAddCircle class="h-full w-full" /> <IconAddCircle />
</template> </template>
{{ $t("core.common.buttons.new") }} {{ $t("core.common.buttons.new") }}
</VButton> </VButton>

View File

@ -198,14 +198,14 @@ function onCreationModalClose() {
type="default" type="default"
> >
<template #icon> <template #icon>
<IconShieldUser class="h-full w-full" /> <IconShieldUser />
</template> </template>
{{ $t("core.user.actions.roles") }} {{ $t("core.user.actions.roles") }}
</VButton> </VButton>
<HasPermission :permissions="['*']"> <HasPermission :permissions="['*']">
<VButton :route="{ name: 'AuthProviders' }" size="sm" type="default"> <VButton :route="{ name: 'AuthProviders' }" size="sm" type="default">
<template #icon> <template #icon>
<IconLockPasswordLine class="h-full w-full" /> <IconLockPasswordLine />
</template> </template>
{{ $t("core.user.actions.identity_authentication") }} {{ $t("core.user.actions.identity_authentication") }}
</VButton> </VButton>
@ -216,7 +216,7 @@ function onCreationModalClose() {
@click="creationModal = true" @click="creationModal = true"
> >
<template #icon> <template #icon>
<IconAddCircle class="h-full w-full" /> <IconAddCircle />
</template> </template>
{{ $t("core.common.buttons.new") }} {{ $t("core.common.buttons.new") }}
</VButton> </VButton>
@ -326,7 +326,7 @@ function onCreationModalClose() {
@click="creationModal = true" @click="creationModal = true"
> >
<template #icon> <template #icon>
<IconAddCircle class="h-full w-full" /> <IconAddCircle />
</template> </template>
{{ $t("core.common.buttons.new") }} {{ $t("core.common.buttons.new") }}
</VButton> </VButton>

View File

@ -35,6 +35,7 @@
</span> </span>
</button> </button>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { computed } from "vue"; import { computed } from "vue";
import type { RouteLocationRaw } from "vue-router"; import type { RouteLocationRaw } from "vue-router";
@ -50,6 +51,7 @@ const props = withDefaults(
disabled?: boolean; disabled?: boolean;
loading?: boolean; loading?: boolean;
route?: RouteLocationRaw | undefined; route?: RouteLocationRaw | undefined;
ghost?: boolean;
}>(), }>(),
{ {
type: "default", type: "default",
@ -59,6 +61,7 @@ const props = withDefaults(
disabled: false, disabled: false,
loading: false, loading: false,
route: undefined, route: undefined,
ghost: false,
} }
); );
@ -74,6 +77,7 @@ const classes = computed(() => {
{ "btn-circle": props.circle }, { "btn-circle": props.circle },
{ "btn-block": props.block }, { "btn-block": props.block },
{ "btn-loading": props.loading }, { "btn-loading": props.loading },
{ "btn-ghost": props.ghost },
]; ];
}); });
@ -85,128 +89,199 @@ function handleClick() {
emit("click"); emit("click");
} }
</script> </script>
<style lang="scss"> <style lang="scss">
@use "sass:map";
$btn-sizes: (
xs: (
height: theme("spacing.6"),
padding-x: theme("spacing.2"),
font-size: theme("fontSize.xs"),
icon-size: theme("spacing.3"),
icon-margin: theme("spacing.2"),
),
sm: (
height: theme("spacing.7"),
padding-x: theme("spacing.3"),
font-size: theme("fontSize.xs"),
icon-size: theme("spacing.3"),
icon-margin: theme("spacing.2"),
),
md: (
height: theme("spacing.9"),
padding-x: theme("spacing.4"),
font-size: theme("fontSize.sm"),
icon-size: theme("spacing.5"),
icon-margin: theme("spacing.3"),
),
lg: (
height: theme("spacing.11"),
padding-x: theme("spacing.5"),
font-size: theme("fontSize.lg"),
icon-size: theme("spacing.5"),
icon-margin: theme("spacing.3"),
),
);
$btn-themes: (
default: (
bg: transparent,
color: inherit,
border: 1px solid #d9d9d9,
hover-bg: theme("colors.gray.100"),
icon-color: theme("colors.secondary"),
ghost-color: inherit,
ghost-hover-bg: theme("colors.gray.100"),
ghost-icon-color: theme("colors.secondary"),
),
primary: (
bg: theme("colors.primary"),
color: #fff,
border: none,
hover-bg: theme("colors.primary"),
icon-color: #fff,
ghost-color: theme("colors.primary"),
ghost-hover-bg: theme("colors.primary / 10%"),
ghost-icon-color: theme("colors.primary"),
),
secondary: (
bg: theme("colors.secondary"),
color: #fff,
border: none,
hover-bg: theme("colors.secondary"),
icon-color: #fff,
ghost-color: theme("colors.secondary"),
ghost-hover-bg: theme("colors.secondary / 10%"),
ghost-icon-color: theme("colors.secondary"),
),
danger: (
bg: theme("colors.danger"),
color: #fff,
border: none,
hover-bg: theme("colors.danger"),
icon-color: #fff,
ghost-color: theme("colors.danger"),
ghost-hover-bg: theme("colors.danger / 10%"),
ghost-icon-color: theme("colors.danger"),
),
);
.btn { .btn {
@apply rounded-base display: inline-flex;
inline-flex align-items: center;
flex-shrink-0 justify-content: center;
cursor-pointer flex-shrink: 0;
select-none flex-wrap: wrap;
flex-wrap cursor: pointer;
items-center user-select: none;
justify-center appearance: none;
transition-all border-radius: theme("borderRadius.base");
text-center transition: all 150ms cubic-bezier(0.4, 0, 0.2, 1);
text-sm text-align: center;
no-underline text-decoration: none;
h-9 vertical-align: middle;
px-4 outline-width: 0;
outline-0 border-style: none;
border-none $md-config: map.get($btn-sizes, md);
appearance-none height: map.get($md-config, height);
align-middle; padding-left: map.get($md-config, padding-x);
padding-right: map.get($md-config, padding-x);
font-size: map.get($md-config, font-size);
&:hover { &:hover {
@apply opacity-90; opacity: 0.9;
} }
&:active { &:active {
@apply opacity-100; opacity: 1;
} }
&:disabled { &:disabled {
@apply opacity-50 opacity: 0.5;
cursor-not-allowed; cursor: not-allowed;
}
} }
.btn-default { &.btn-loading {
border: 1px solid #d9d9d9; cursor: not-allowed;
&:hover { &:hover {
@apply bg-gray-100; opacity: 1;
}
}
&.btn-block {
width: 100%;
} }
.btn-icon { .btn-icon {
@apply text-secondary; height: map.get($md-config, icon-size);
width: map.get($md-config, icon-size);
margin-right: map.get($md-config, icon-margin);
color: #fff;
display: inline-flex;
align-items: center;
justify-content: center;
> * {
height: 100%;
width: 100%;
}
} }
} }
.btn-primary { @each $size, $config in $btn-sizes {
@apply text-white bg-primary #{!important}; .btn-#{$size} {
} height: map.get($config, height);
padding-left: map.get($config, padding-x);
.btn-secondary { padding-right: map.get($config, padding-x);
@apply text-white bg-secondary #{!important}; font-size: map.get($config, font-size);
}
.btn-danger {
background-color: #d71d1d !important;
@apply text-white;
}
.btn-block {
@apply w-full;
}
.btn-icon { .btn-icon {
@apply h-5 w-5 height: map.get($config, icon-size);
text-white width: map.get($config, icon-size);
mr-3; margin-right: map.get($config, icon-margin);
} }
.btn-loading { &.btn-circle {
@apply cursor-not-allowed; width: map.get($config, height);
padding: 0;
border-radius: 9999px;
}
}
}
@each $theme, $config in $btn-themes {
.btn-#{$theme} {
background-color: map.get($config, bg) !important;
color: map.get($config, color);
border: map.get($config, border);
&:hover { &:hover {
@apply opacity-100; background-color: map.get($config, hover-bg) !important;
} }
}
.btn-lg {
@apply h-11
px-5
text-lg;
}
.btn-sm {
@apply h-7
px-3
text-xs;
.btn-icon { .btn-icon {
@apply h-3 color: map.get($config, icon-color);
w-3 }
mr-2;
} }
} }
.btn-xs { .btn-ghost {
@apply h-6 background-color: transparent !important;
px-2
text-xs; @each $theme, $config in $btn-themes {
&.btn-#{$theme} {
color: map.get($config, ghost-color);
border: none;
&:hover {
background-color: map.get($config, ghost-hover-bg) !important;
}
.btn-icon { .btn-icon {
@apply h-3 color: map.get($config, ghost-icon-color);
w-3
mr-2;
} }
} }
.btn-circle {
@apply w-9
p-0
rounded-full;
} }
.btn-lg.btn-circle {
@apply w-11;
}
.btn-sm.btn-circle {
@apply w-7;
}
.btn-xs.btn-circle {
@apply w-6;
} }
</style> </style>

View File

@ -29,7 +29,7 @@ const handleAppendClick = () => {
<div :class="context.classes.add" @click="handleAppendClick"> <div :class="context.classes.add" @click="handleAppendClick">
<VButton :disabled="disabled" type="secondary"> <VButton :disabled="disabled" type="secondary">
<template #icon> <template #icon>
<IconAddCircle class="h-full w-full" /> <IconAddCircle />
</template> </template>
{{ context.addLabel || $t("core.common.buttons.add") }} {{ context.addLabel || $t("core.common.buttons.add") }}
</VButton> </VButton>

View File

@ -29,7 +29,7 @@ const handleAppendClick = () => {
<div :class="context.classes.add" @click="handleAppendClick"> <div :class="context.classes.add" @click="handleAppendClick">
<VButton :disabled="disabled" type="secondary"> <VButton :disabled="disabled" type="secondary">
<template #icon> <template #icon>
<IconAddCircle class="h-full w-full" /> <IconAddCircle />
</template> </template>
{{ context.addLabel || $t("core.common.buttons.add") }} {{ context.addLabel || $t("core.common.buttons.add") }}
</VButton> </VButton>

View File

@ -31,6 +31,7 @@ module.exports = {
colors: { colors: {
primary: "#4CCBA0", primary: "#4CCBA0",
secondary: "#0E1731", secondary: "#0E1731",
danger: "#D71D1D",
}, },
borderRadius: { borderRadius: {
base: "4px", base: "4px",

View File

@ -307,7 +307,7 @@ const handleSelectNext = async () => {
<div v-if="data?.total" class="mb-5"> <div v-if="data?.total" class="mb-5">
<VButton @click="uploadVisible = true"> <VButton @click="uploadVisible = true">
<template #icon> <template #icon>
<IconUpload class="h-full w-full" /> <IconUpload />
</template> </template>
{{ $t("core.common.buttons.upload") }} {{ $t("core.common.buttons.upload") }}
</VButton> </VButton>
@ -327,7 +327,7 @@ const handleSelectNext = async () => {
</VButton> </VButton>
<VButton type="secondary" @click="uploadVisible = true"> <VButton type="secondary" @click="uploadVisible = true">
<template #icon> <template #icon>
<IconUpload class="h-full w-full" /> <IconUpload />
</template> </template>
{{ $t("core.uc_attachment.empty.actions.upload") }} {{ $t("core.uc_attachment.empty.actions.upload") }}
</VButton> </VButton>

View File

@ -484,7 +484,7 @@ useSlugify(
@click="handleSaveClick" @click="handleSaveClick"
> >
<template #icon> <template #icon>
<IconSave class="h-full w-full" /> <IconSave />
</template> </template>
{{ $t("core.common.buttons.save") }} {{ $t("core.common.buttons.save") }}
</VButton> </VButton>
@ -495,7 +495,7 @@ useSlugify(
@click="handleOpenPostSettingEditModal" @click="handleOpenPostSettingEditModal"
> >
<template #icon> <template #icon>
<IconSettings class="h-full w-full" /> <IconSettings />
</template> </template>
{{ $t("core.common.buttons.setting") }} {{ $t("core.common.buttons.setting") }}
</VButton> </VButton>
@ -506,7 +506,7 @@ useSlugify(
@click="handlePublishClick" @click="handlePublishClick"
> >
<template #icon> <template #icon>
<IconSendPlaneFill class="h-full w-full" /> <IconSendPlaneFill />
</template> </template>
{{ $t("core.common.buttons.publish") }} {{ $t("core.common.buttons.publish") }}
</VButton> </VButton>

View File

@ -109,7 +109,7 @@ const {
<template #actions> <template #actions>
<VButton :route="{ name: 'PostEditor' }" type="secondary"> <VButton :route="{ name: 'PostEditor' }" type="secondary">
<template #icon> <template #icon>
<IconAddCircle class="h-full w-full" /> <IconAddCircle />
</template> </template>
{{ $t("core.common.buttons.new") }} {{ $t("core.common.buttons.new") }}
</VButton> </VButton>
@ -179,7 +179,7 @@ const {
type="secondary" type="secondary"
> >
<template #icon> <template #icon>
<IconAddCircle class="h-full w-full" /> <IconAddCircle />
</template> </template>
{{ $t("core.common.buttons.new") }} {{ $t("core.common.buttons.new") }}
</VButton> </VButton>

View File

@ -39,7 +39,7 @@ const creationModal = ref(false);
<div v-if="pats?.length" class="my-5 flex justify-end"> <div v-if="pats?.length" class="my-5 flex justify-end">
<VButton type="secondary" @click="creationModal = true"> <VButton type="secondary" @click="creationModal = true">
<template #icon> <template #icon>
<IconAddCircle class="h-full w-full" /> <IconAddCircle />
</template> </template>
{{ $t("core.common.buttons.new") }} {{ $t("core.common.buttons.new") }}
</VButton> </VButton>
@ -59,7 +59,7 @@ const creationModal = ref(false);
</VButton> </VButton>
<VButton type="secondary" @click="creationModal = true"> <VButton type="secondary" @click="creationModal = true">
<template #icon> <template #icon>
<IconAddCircle class="h-full w-full" /> <IconAddCircle />
</template> </template>
{{ $t("core.common.buttons.new") }} {{ $t("core.common.buttons.new") }}
</VButton> </VButton>