fix(web): 皮肤主题 - 修复提示浮层文字对比度
This commit is contained in:
@@ -3,12 +3,14 @@ package service
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"math"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/textproto"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
@@ -48,6 +50,52 @@ func TestAppearanceDefaultsPreserveBuiltInBrand(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuiltInAppearanceSkinTooltipPairsMeetContrast(t *testing.T) {
|
||||
for _, skin := range defaultAppearanceSkinThemes() {
|
||||
modes := []struct {
|
||||
name string
|
||||
tokens AppearanceSkinModeTokens
|
||||
}{
|
||||
{name: "light", tokens: skin.Tokens.Light},
|
||||
{name: "dark", tokens: skin.Tokens.Dark},
|
||||
}
|
||||
for _, mode := range modes {
|
||||
ratio := appearanceColorContrastRatio(t, mode.tokens.Overlay, mode.tokens.Text)
|
||||
if ratio < 4.5 {
|
||||
t.Errorf("skin %s %s tooltip contrast = %.2f, want at least 4.5", skin.ID, mode.name, ratio)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func appearanceColorContrastRatio(t *testing.T, foreground, background string) float64 {
|
||||
t.Helper()
|
||||
contrastLuminance := func(color string) float64 {
|
||||
if len(color) != 7 || color[0] != '#' {
|
||||
t.Fatalf("unsupported test color %q", color)
|
||||
}
|
||||
channels := make([]float64, 3)
|
||||
for index := range channels {
|
||||
value, err := strconv.ParseUint(color[1+index*2:3+index*2], 16, 8)
|
||||
if err != nil {
|
||||
t.Fatalf("parse test color %q: %v", color, err)
|
||||
}
|
||||
srgb := float64(value) / 255
|
||||
if srgb <= 0.04045 {
|
||||
channels[index] = srgb / 12.92
|
||||
} else {
|
||||
channels[index] = math.Pow((srgb+0.055)/1.055, 2.4)
|
||||
}
|
||||
}
|
||||
return 0.2126*channels[0] + 0.7152*channels[1] + 0.0722*channels[2]
|
||||
}
|
||||
foregroundLuminance := contrastLuminance(foreground)
|
||||
backgroundLuminance := contrastLuminance(background)
|
||||
lighter := math.Max(foregroundLuminance, backgroundLuminance)
|
||||
darker := math.Min(foregroundLuminance, backgroundLuminance)
|
||||
return (lighter + 0.05) / (darker + 0.05)
|
||||
}
|
||||
|
||||
func TestAppearanceBackfillsVersionSixFieldsForExistingSetting(t *testing.T) {
|
||||
svc, db, _, _ := newAppearanceTestService(t)
|
||||
legacy := model.SystemSetting{Key: appearanceSettingKey, ValueJSON: `{"schemaVersion":1,"brandName":"旧品牌","skinId":"classic"}`}
|
||||
|
||||
@@ -13015,6 +13015,18 @@ html:not(.dark) .creation-history-drawer-root {
|
||||
backdrop-filter: none !important;
|
||||
}
|
||||
|
||||
/* Tooltip 必须使用同一套浮层背景/前景语义色。Ant Design 会让它继承
|
||||
colorTextLightSolid(实心按钮文字色),深色主题下会形成深底深字。 */
|
||||
:where(.ant-tooltip) {
|
||||
--ant-tooltip-arrow-background-color: var(--popover) !important;
|
||||
--ant-tooltip-overlay-color: var(--popover-foreground) !important;
|
||||
}
|
||||
|
||||
:where(.ant-tooltip-container, .ant-tooltip-inner) {
|
||||
background: var(--popover) !important;
|
||||
color: var(--popover-foreground) !important;
|
||||
}
|
||||
|
||||
:where(.ant-select-item-option, .ant-dropdown-menu-item, .ant-dropdown-menu-submenu-title, .ant-cascader-menu-item, .ant-mentions-dropdown-menu-item) {
|
||||
min-height: 36px;
|
||||
margin-block: 2px;
|
||||
|
||||
@@ -155,6 +155,10 @@ describe("site appearance and editable skin library", () => {
|
||||
expect(editorSource).toContain("后台菜单");
|
||||
expect(globalStyles).toContain("--control-switch-checked-bg: #16a34a");
|
||||
expect(globalStyles).toContain("--plugin-switch-checked-bg: var(--control-switch-checked-bg)");
|
||||
expect(globalStyles).toContain("--ant-tooltip-arrow-background-color: var(--popover) !important");
|
||||
expect(globalStyles).toContain("--ant-tooltip-overlay-color: var(--popover-foreground) !important");
|
||||
expect(globalStyles).toContain(":where(.ant-tooltip-container, .ant-tooltip-inner)");
|
||||
expect(globalStyles).toContain("color: var(--popover-foreground) !important");
|
||||
expect(adminStyles).toContain("--admin-status-warning: var(--palette-status-warning)");
|
||||
expect(adminStyles).toContain("border-radius: var(--menu-radius);");
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user