chore(frontend): introduce prettier + eslint and prune unused code
- Add Prettier 3 with prettier-plugin-organize-imports (sorts/removes unused imports) - Add ESLint 10 flat config with typescript-eslint + eslint-plugin-vue + eslint-config-prettier - Add root scripts: format, format:check, lint, lint:fix - Reformat 257 files across admin-web, ops-web, desktop-client, packages - Remove unused locals/exports flagged by --noUnusedLocals/--noUnusedParameters - Fix duplicate localTabLabel key, surrogate-pair regex u-flag, NBSP literal in regex - Skip server/ (Go) and apps/browser-extension/ (deprecated per ADR) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,30 +1,33 @@
|
||||
<script setup lang="ts">
|
||||
const props = withDefaults(defineProps<{
|
||||
tone?: "primary" | "secondary" | "ghost" | "danger" | "text";
|
||||
size?: "sm" | "md";
|
||||
loading?: boolean;
|
||||
disabled?: boolean;
|
||||
type?: "button" | "submit" | "reset";
|
||||
title?: string;
|
||||
}>(), {
|
||||
tone: "secondary",
|
||||
size: "md",
|
||||
loading: false,
|
||||
disabled: false,
|
||||
type: "button",
|
||||
title: undefined,
|
||||
});
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
tone?: 'primary' | 'secondary' | 'ghost' | 'danger' | 'text'
|
||||
size?: 'sm' | 'md'
|
||||
loading?: boolean
|
||||
disabled?: boolean
|
||||
type?: 'button' | 'submit' | 'reset'
|
||||
title?: string
|
||||
}>(),
|
||||
{
|
||||
tone: 'secondary',
|
||||
size: 'md',
|
||||
loading: false,
|
||||
disabled: false,
|
||||
type: 'button',
|
||||
title: undefined,
|
||||
},
|
||||
)
|
||||
|
||||
const emit = defineEmits<{
|
||||
(event: "click", payload: MouseEvent): void;
|
||||
}>();
|
||||
(event: 'click', payload: MouseEvent): void
|
||||
}>()
|
||||
|
||||
function handleClick(event: MouseEvent) {
|
||||
if (props.loading || props.disabled) {
|
||||
event.preventDefault();
|
||||
return;
|
||||
event.preventDefault()
|
||||
return
|
||||
}
|
||||
emit("click", event);
|
||||
emit('click', event)
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -57,7 +60,11 @@ function handleClick(event: MouseEvent) {
|
||||
background: #ffffff;
|
||||
color: #1f2937;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.2s ease, background-color 0.2s ease, color 0.2s ease, opacity 0.2s ease;
|
||||
transition:
|
||||
border-color 0.2s ease,
|
||||
background-color 0.2s ease,
|
||||
color 0.2s ease,
|
||||
opacity 0.2s ease;
|
||||
}
|
||||
|
||||
.button:disabled {
|
||||
|
||||
@@ -1,79 +1,79 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from "vue";
|
||||
import { RouterLink, RouterView, useRoute } from "vue-router";
|
||||
import {
|
||||
AppstoreOutlined,
|
||||
SendOutlined,
|
||||
LinkOutlined,
|
||||
RobotOutlined,
|
||||
LogoutOutlined,
|
||||
RobotOutlined,
|
||||
SendOutlined,
|
||||
SettingOutlined,
|
||||
} from "@ant-design/icons-vue";
|
||||
} from '@ant-design/icons-vue'
|
||||
import { computed } from 'vue'
|
||||
import { RouterLink, RouterView, useRoute } from 'vue-router'
|
||||
|
||||
import { useDesktopRuntime } from "../composables/useDesktopRuntime";
|
||||
import { useDesktopSession } from "../composables/useDesktopSession";
|
||||
import { desktopMonitoringMediaCatalog, desktopPublishMediaCatalog } from "../lib/media-catalog";
|
||||
import { useDesktopRuntime } from '../composables/useDesktopRuntime'
|
||||
import { useDesktopSession } from '../composables/useDesktopSession'
|
||||
import { desktopMonitoringMediaCatalog, desktopPublishMediaCatalog } from '../lib/media-catalog'
|
||||
|
||||
const route = useRoute();
|
||||
const { snapshot, error, refreshAccounts } = useDesktopRuntime();
|
||||
const { session, logout } = useDesktopSession();
|
||||
const route = useRoute()
|
||||
const { snapshot, error, refreshAccounts } = useDesktopRuntime()
|
||||
const { session, logout } = useDesktopSession()
|
||||
|
||||
const accountAwareRoutes = new Set(["/media-platforms", "/ai-platforms"]);
|
||||
const accountAwareRoutes = new Set(['/media-platforms', '/ai-platforms'])
|
||||
|
||||
function handleNavClick(target: string) {
|
||||
if (accountAwareRoutes.has(target)) {
|
||||
void refreshAccounts();
|
||||
void refreshAccounts()
|
||||
}
|
||||
}
|
||||
|
||||
const navItems = computed(() => {
|
||||
const data = snapshot.value;
|
||||
const accounts = data?.accounts ?? [];
|
||||
const publishIDs = new Set(desktopPublishMediaCatalog.map((item) => item.id));
|
||||
const monitoringIDs = new Set(desktopMonitoringMediaCatalog.map((item) => item.id));
|
||||
const data = snapshot.value
|
||||
const accounts = data?.accounts ?? []
|
||||
const publishIDs = new Set(desktopPublishMediaCatalog.map((item) => item.id))
|
||||
const monitoringIDs = new Set(desktopMonitoringMediaCatalog.map((item) => item.id))
|
||||
|
||||
return [
|
||||
{
|
||||
to: "/",
|
||||
title: "控制台",
|
||||
description: "运行总览、活动流和总体健康度",
|
||||
to: '/',
|
||||
title: '控制台',
|
||||
description: '运行总览、活动流和总体健康度',
|
||||
count: data?.summary.issuesOpen ?? 0,
|
||||
icon: AppstoreOutlined,
|
||||
},
|
||||
{
|
||||
to: "/publish-management",
|
||||
title: "发布管理",
|
||||
description: "查看待发布队列、历史发送结果,并对文章再次发送",
|
||||
to: '/publish-management',
|
||||
title: '发布管理',
|
||||
description: '查看待发布队列、历史发送结果,并对文章再次发送',
|
||||
count: data?.summary.queuedTasks ?? 0,
|
||||
icon: SendOutlined,
|
||||
},
|
||||
{
|
||||
to: "/media-platforms",
|
||||
title: "媒体账号",
|
||||
description: "发布媒体授权、多个账号绑定管理",
|
||||
to: '/media-platforms',
|
||||
title: '媒体账号',
|
||||
description: '发布媒体授权、多个账号绑定管理',
|
||||
count: accounts.filter((item) => publishIDs.has(item.platform)).length,
|
||||
icon: LinkOutlined,
|
||||
},
|
||||
{
|
||||
to: "/ai-platforms",
|
||||
title: "AI 平台",
|
||||
description: "AI 平台一平台一绑定,按卡片查看状态与归属",
|
||||
to: '/ai-platforms',
|
||||
title: 'AI 平台',
|
||||
description: 'AI 平台一平台一绑定,按卡片查看状态与归属',
|
||||
count: accounts.filter((item) => monitoringIDs.has(item.platform)).length,
|
||||
icon: RobotOutlined,
|
||||
},
|
||||
];
|
||||
});
|
||||
]
|
||||
})
|
||||
|
||||
|
||||
const operatorName = computed(() => session.value?.user?.name ?? "未命名操作员");
|
||||
const operatorEmail = computed(() => session.value?.user?.email ?? "");
|
||||
const liveClientLabel = computed(() => snapshot.value?.clients[0]?.deviceName ?? null);
|
||||
const operatorName = computed(() => session.value?.user?.name ?? '未命名操作员')
|
||||
const operatorEmail = computed(() => session.value?.user?.email ?? '')
|
||||
const liveClientLabel = computed(() => snapshot.value?.clients[0]?.deviceName ?? null)
|
||||
const clientLabel = computed(
|
||||
() => liveClientLabel.value ?? session.value?.desktopClient?.device_name ?? "当前设备尚未注册 client",
|
||||
);
|
||||
() =>
|
||||
liveClientLabel.value ?? session.value?.desktopClient?.device_name ?? '当前设备尚未注册 client',
|
||||
)
|
||||
|
||||
function openSettingsWindow() {
|
||||
void window.desktopBridge.app.openSettingsWindow();
|
||||
void window.desktopBridge.app.openSettingsWindow()
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -95,19 +95,19 @@ function openSettingsWindow() {
|
||||
<nav class="nav">
|
||||
<RouterLink
|
||||
v-for="item in navItems"
|
||||
:key="item.to"
|
||||
:to="item.to"
|
||||
class="nav-link"
|
||||
:class="{ active: route.path === item.to }"
|
||||
@click="handleNavClick(item.to)"
|
||||
>
|
||||
<div class="nav-copy">
|
||||
<component :is="item.icon" class="nav-icon" />
|
||||
<strong>{{ item.title }}</strong>
|
||||
</div>
|
||||
<span class="nav-count">{{ item.count }}</span>
|
||||
</RouterLink>
|
||||
</nav>
|
||||
:key="item.to"
|
||||
:to="item.to"
|
||||
class="nav-link"
|
||||
:class="{ active: route.path === item.to }"
|
||||
@click="handleNavClick(item.to)"
|
||||
>
|
||||
<div class="nav-copy">
|
||||
<component :is="item.icon" class="nav-icon" />
|
||||
<strong>{{ item.title }}</strong>
|
||||
</div>
|
||||
<span class="nav-count">{{ item.count }}</span>
|
||||
</RouterLink>
|
||||
</nav>
|
||||
|
||||
<footer class="sidebar-footer">
|
||||
<section class="user-profile-panel">
|
||||
@@ -132,7 +132,11 @@ function openSettingsWindow() {
|
||||
</button>
|
||||
</a-tooltip>
|
||||
<a-tooltip title="退出登录" placement="top">
|
||||
<button type="button" class="footer-icon-btn footer-icon-btn--danger" @click="logout">
|
||||
<button
|
||||
type="button"
|
||||
class="footer-icon-btn footer-icon-btn--danger"
|
||||
@click="logout"
|
||||
>
|
||||
<LogoutOutlined />
|
||||
</button>
|
||||
</a-tooltip>
|
||||
@@ -142,7 +146,7 @@ function openSettingsWindow() {
|
||||
|
||||
<div class="footer-bottom-row">
|
||||
<span class="version-label">Version</span>
|
||||
<strong class="version-value">{{ snapshot?.app.version ?? "0.1.0" }}</strong>
|
||||
<strong class="version-value">{{ snapshot?.app.version ?? '0.1.0' }}</strong>
|
||||
</div>
|
||||
<p v-if="error" class="error-text">{{ error }}</p>
|
||||
</footer>
|
||||
@@ -177,13 +181,13 @@ function openSettingsWindow() {
|
||||
-webkit-app-region: drag;
|
||||
}
|
||||
|
||||
:global(html[data-platform="darwin"]) .window-drag-bar {
|
||||
:global(html[data-platform='darwin']) .window-drag-bar {
|
||||
left: 80px;
|
||||
right: 0;
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
.app-shell :where(button, a, input, select, textarea, [role="button"], [role="link"]) {
|
||||
.app-shell :where(button, a, input, select, textarea, [role='button'], [role='link']) {
|
||||
-webkit-app-region: no-drag;
|
||||
}
|
||||
|
||||
@@ -344,13 +348,17 @@ h1 {
|
||||
border-radius: 16px;
|
||||
background: #ffffff;
|
||||
border: 1px solid #e2e8f0;
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.02), 0 2px 4px -2px rgba(0, 0, 0, 0.01);
|
||||
box-shadow:
|
||||
0 1px 3px rgba(0, 0, 0, 0.02),
|
||||
0 2px 4px -2px rgba(0, 0, 0, 0.01);
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.user-profile-panel:hover {
|
||||
border-color: #cbd5e1;
|
||||
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.03), 0 2px 4px -2px rgba(0, 0, 0, 0.02);
|
||||
box-shadow:
|
||||
0 4px 6px -1px rgba(0, 0, 0, 0.03),
|
||||
0 2px 4px -2px rgba(0, 0, 0, 0.02);
|
||||
}
|
||||
|
||||
.user-info-row {
|
||||
@@ -371,7 +379,7 @@ h1 {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
box-shadow: inset 0 2px 4px rgba(0,0,0,0.1);
|
||||
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.user-details {
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
<script setup lang="ts">
|
||||
withDefaults(defineProps<{
|
||||
title: string;
|
||||
open?: boolean;
|
||||
}>(), {
|
||||
open: false,
|
||||
});
|
||||
withDefaults(
|
||||
defineProps<{
|
||||
title: string
|
||||
open?: boolean
|
||||
}>(),
|
||||
{
|
||||
open: false,
|
||||
},
|
||||
)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -56,7 +59,7 @@ withDefaults(defineProps<{
|
||||
|
||||
.panel__indicator::before,
|
||||
.panel__indicator::after {
|
||||
content: "";
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
@@ -65,7 +68,9 @@ withDefaults(defineProps<{
|
||||
border-radius: 999px;
|
||||
background: #64748b;
|
||||
transform: translate(-50%, -50%);
|
||||
transition: transform 0.2s ease, opacity 0.2s ease;
|
||||
transition:
|
||||
transform 0.2s ease,
|
||||
opacity 0.2s ease;
|
||||
}
|
||||
|
||||
.panel__indicator::after {
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<script setup lang="ts">
|
||||
import type { Component } from 'vue';
|
||||
import type { Component } from 'vue'
|
||||
|
||||
defineProps<{
|
||||
eyebrow: string;
|
||||
value: string | number;
|
||||
label: string;
|
||||
tone?: "neutral" | "brand" | "success" | "warn" | "danger" | "info";
|
||||
icon?: Component;
|
||||
}>();
|
||||
eyebrow: string
|
||||
value: string | number
|
||||
label: string
|
||||
tone?: 'neutral' | 'brand' | 'success' | 'warn' | 'danger' | 'info'
|
||||
icon?: Component
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -33,7 +33,9 @@ defineProps<{
|
||||
border: 1px solid #f0f3fa;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
transition: box-shadow 0.2s, transform 0.2s;
|
||||
transition:
|
||||
box-shadow 0.2s,
|
||||
transform 0.2s;
|
||||
}
|
||||
|
||||
.metric-card:hover {
|
||||
@@ -59,12 +61,30 @@ defineProps<{
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.metric-icon-wrapper.neutral { background: #f0f2f5; color: #595959; }
|
||||
.metric-icon-wrapper.brand { background: #e6f4ff; color: #1677ff; }
|
||||
.metric-icon-wrapper.success { background: #f6ffed; color: #52c41a; }
|
||||
.metric-icon-wrapper.warn { background: #fffbe6; color: #faad14; }
|
||||
.metric-icon-wrapper.danger { background: #fff2f0; color: #ff4d4f; }
|
||||
.metric-icon-wrapper.info { background: #e6f7ff; color: #1890ff; }
|
||||
.metric-icon-wrapper.neutral {
|
||||
background: #f0f2f5;
|
||||
color: #595959;
|
||||
}
|
||||
.metric-icon-wrapper.brand {
|
||||
background: #e6f4ff;
|
||||
color: #1677ff;
|
||||
}
|
||||
.metric-icon-wrapper.success {
|
||||
background: #f6ffed;
|
||||
color: #52c41a;
|
||||
}
|
||||
.metric-icon-wrapper.warn {
|
||||
background: #fffbe6;
|
||||
color: #faad14;
|
||||
}
|
||||
.metric-icon-wrapper.danger {
|
||||
background: #fff2f0;
|
||||
color: #ff4d4f;
|
||||
}
|
||||
.metric-icon-wrapper.info {
|
||||
background: #e6f7ff;
|
||||
color: #1890ff;
|
||||
}
|
||||
|
||||
.metric-title-group {
|
||||
display: flex;
|
||||
@@ -101,18 +121,42 @@ defineProps<{
|
||||
margin-top: auto;
|
||||
}
|
||||
|
||||
html[data-theme="dark"] .metric-card {
|
||||
html[data-theme='dark'] .metric-card {
|
||||
background: #141414;
|
||||
border-color: #303030;
|
||||
}
|
||||
html[data-theme="dark"] .metric-icon-wrapper.neutral { background: #262626; color: rgba(255, 255, 255, 0.45); }
|
||||
html[data-theme="dark"] .metric-icon-wrapper.brand { background: rgba(22, 119, 255, 0.2); color: #177ddc; }
|
||||
html[data-theme="dark"] .metric-icon-wrapper.success { background: rgba(82, 196, 26, 0.2); color: #49aa19; }
|
||||
html[data-theme="dark"] .metric-icon-wrapper.warn { background: rgba(250, 173, 20, 0.2); color: #d89614; }
|
||||
html[data-theme="dark"] .metric-icon-wrapper.danger { background: rgba(255, 77, 79, 0.2); color: #a61d24; }
|
||||
html[data-theme="dark"] .metric-icon-wrapper.info { background: rgba(24, 144, 255, 0.2); color: #177ddc; }
|
||||
html[data-theme="dark"] .eyebrow,
|
||||
html[data-theme="dark"] .label { color: rgba(255, 255, 255, 0.45); }
|
||||
html[data-theme="dark"] .value { color: rgba(255, 255, 255, 0.85); }
|
||||
html[data-theme="dark"] .label { border-top-color: #303030; }
|
||||
html[data-theme='dark'] .metric-icon-wrapper.neutral {
|
||||
background: #262626;
|
||||
color: rgba(255, 255, 255, 0.45);
|
||||
}
|
||||
html[data-theme='dark'] .metric-icon-wrapper.brand {
|
||||
background: rgba(22, 119, 255, 0.2);
|
||||
color: #177ddc;
|
||||
}
|
||||
html[data-theme='dark'] .metric-icon-wrapper.success {
|
||||
background: rgba(82, 196, 26, 0.2);
|
||||
color: #49aa19;
|
||||
}
|
||||
html[data-theme='dark'] .metric-icon-wrapper.warn {
|
||||
background: rgba(250, 173, 20, 0.2);
|
||||
color: #d89614;
|
||||
}
|
||||
html[data-theme='dark'] .metric-icon-wrapper.danger {
|
||||
background: rgba(255, 77, 79, 0.2);
|
||||
color: #a61d24;
|
||||
}
|
||||
html[data-theme='dark'] .metric-icon-wrapper.info {
|
||||
background: rgba(24, 144, 255, 0.2);
|
||||
color: #177ddc;
|
||||
}
|
||||
html[data-theme='dark'] .eyebrow,
|
||||
html[data-theme='dark'] .label {
|
||||
color: rgba(255, 255, 255, 0.45);
|
||||
}
|
||||
html[data-theme='dark'] .value {
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
}
|
||||
html[data-theme='dark'] .label {
|
||||
border-top-color: #303030;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,60 +1,63 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from "vue";
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
current: number;
|
||||
pageSize: number;
|
||||
total: number;
|
||||
maxVisiblePages?: number;
|
||||
}>(), {
|
||||
maxVisiblePages: 5,
|
||||
});
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
current: number
|
||||
pageSize: number
|
||||
total: number
|
||||
maxVisiblePages?: number
|
||||
}>(),
|
||||
{
|
||||
maxVisiblePages: 5,
|
||||
},
|
||||
)
|
||||
|
||||
const emit = defineEmits<{
|
||||
(event: "change", page: number): void;
|
||||
}>();
|
||||
(event: 'change', page: number): void
|
||||
}>()
|
||||
|
||||
type PageToken = number | "ellipsis";
|
||||
type PageToken = number | 'ellipsis'
|
||||
|
||||
const totalPages = computed(() => Math.max(1, Math.ceil(props.total / props.pageSize)));
|
||||
const totalPages = computed(() => Math.max(1, Math.ceil(props.total / props.pageSize)))
|
||||
|
||||
const tokens = computed<PageToken[]>(() => {
|
||||
if (totalPages.value <= props.maxVisiblePages) {
|
||||
return Array.from({ length: totalPages.value }, (_value, index) => index + 1);
|
||||
return Array.from({ length: totalPages.value }, (_value, index) => index + 1)
|
||||
}
|
||||
|
||||
const pages: PageToken[] = [1];
|
||||
let start = Math.max(2, props.current - 1);
|
||||
let end = Math.min(totalPages.value - 1, props.current + 1);
|
||||
const pages: PageToken[] = [1]
|
||||
let start = Math.max(2, props.current - 1)
|
||||
let end = Math.min(totalPages.value - 1, props.current + 1)
|
||||
|
||||
while (end - start < 2 && start > 2) {
|
||||
start -= 1;
|
||||
start -= 1
|
||||
}
|
||||
while (end - start < 2 && end < totalPages.value - 1) {
|
||||
end += 1;
|
||||
end += 1
|
||||
}
|
||||
|
||||
if (start > 2) {
|
||||
pages.push("ellipsis");
|
||||
pages.push('ellipsis')
|
||||
}
|
||||
|
||||
for (let page = start; page <= end; page += 1) {
|
||||
pages.push(page);
|
||||
pages.push(page)
|
||||
}
|
||||
|
||||
if (end < totalPages.value - 1) {
|
||||
pages.push("ellipsis");
|
||||
pages.push('ellipsis')
|
||||
}
|
||||
|
||||
pages.push(totalPages.value);
|
||||
return pages;
|
||||
});
|
||||
pages.push(totalPages.value)
|
||||
return pages
|
||||
})
|
||||
|
||||
function goTo(page: number) {
|
||||
if (page === props.current || page < 1 || page > totalPages.value) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
emit("change", page);
|
||||
emit('change', page)
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -65,7 +68,10 @@ function goTo(page: number) {
|
||||
</button>
|
||||
|
||||
<div class="pagination__pages">
|
||||
<template v-for="token in tokens" :key="`${token}-${typeof token === 'number' ? token : Math.random()}`">
|
||||
<template
|
||||
v-for="token in tokens"
|
||||
:key="`${token}-${typeof token === 'number' ? token : Math.random()}`"
|
||||
>
|
||||
<span v-if="token === 'ellipsis'" class="pagination__ellipsis">…</span>
|
||||
<button
|
||||
v-else
|
||||
@@ -78,7 +84,11 @@ function goTo(page: number) {
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<button class="pagination__nav" :disabled="props.current >= totalPages" @click="goTo(props.current + 1)">
|
||||
<button
|
||||
class="pagination__nav"
|
||||
:disabled="props.current >= totalPages"
|
||||
@click="goTo(props.current + 1)"
|
||||
>
|
||||
下一页
|
||||
</button>
|
||||
</nav>
|
||||
@@ -112,7 +122,11 @@ function goTo(page: number) {
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease, opacity 0.2s ease;
|
||||
transition:
|
||||
background-color 0.2s ease,
|
||||
border-color 0.2s ease,
|
||||
color 0.2s ease,
|
||||
opacity 0.2s ease;
|
||||
}
|
||||
|
||||
.pagination__nav:hover:not(:disabled),
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
const props = defineProps<{
|
||||
tone?: "neutral" | "brand" | "success" | "warn" | "danger" | "info";
|
||||
label: string;
|
||||
subtle?: boolean;
|
||||
}>();
|
||||
tone?: 'neutral' | 'brand' | 'success' | 'warn' | 'danger' | 'info'
|
||||
label: string
|
||||
subtle?: boolean
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -62,7 +62,7 @@ const props = defineProps<{
|
||||
border-color: rgba(37, 99, 235, 0.22);
|
||||
}
|
||||
|
||||
html[data-theme="dark"] .badge {
|
||||
html[data-theme='dark'] .badge {
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
import { PlaySquareOutlined } from "@ant-design/icons-vue";
|
||||
|
||||
defineProps<{
|
||||
eyebrow?: string;
|
||||
title: string;
|
||||
description?: string;
|
||||
}>();
|
||||
eyebrow?: string
|
||||
title: string
|
||||
description?: string
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -62,7 +60,7 @@ defineProps<{
|
||||
}
|
||||
|
||||
.panel-title::before {
|
||||
content: "";
|
||||
content: '';
|
||||
display: inline-block;
|
||||
width: 4px;
|
||||
height: 14px;
|
||||
|
||||
Reference in New Issue
Block a user