outrank Arco button variants and drop the credential hint
The neon tube rules never applied. Arco emits .arco-btn-primary along with three attribute variants ([type='button'], [type='submit'], [type='reset']) that lift specificity to (0,2,0), and their :hover forms reach (0,3,0) — all of which beat a bare .arco-btn-primary. Every rule now uses .arco-btn.arco-btn-X[type='...'] so the skin wins regardless of the rendered html-type; login is a submit button, which is why it stayed solid. Verified with jsdom computed styles against the real arco.css. Also remove the default-credential chips from the login page: printing admin / 123456 on a sign-in screen leaks the credentials of a reachable deployment. The one-click fill shortcut stays. The test that asserted the hint is now shown is inverted to assert it is absent.
This commit is contained in:
@@ -12,7 +12,6 @@ export default {
|
||||
tokenLogin: 'Token',
|
||||
usernamePlaceholder: 'Username',
|
||||
passwordPlaceholder: 'Password',
|
||||
defaultCredentialsHint: 'Default username: admin. Default password: 123456.',
|
||||
credentialsRequired: 'Please enter username and password',
|
||||
invalidCredentials: 'Invalid username or password',
|
||||
tooManyAttempts: 'Too many failed attempts, please try again later',
|
||||
@@ -24,7 +23,7 @@ export default {
|
||||
offline: 'Cannot reach the server · you can still try to log in',
|
||||
showPassword: 'Show password',
|
||||
hidePassword: 'Hide password',
|
||||
fillDefaultCredentials: 'Fill in admin / 123456',
|
||||
fillDefaults: 'Sign in with the default account',
|
||||
localDeploymentNote: 'Self-hosted · no telemetry · data never leaves this machine',
|
||||
tokenHint: 'The token returned by POST /api/auth/login is stored in localStorage',
|
||||
accessDenied: 'You do not have permission to access this resource.',
|
||||
|
||||
@@ -12,7 +12,6 @@ export default {
|
||||
tokenLogin: '令牌登录',
|
||||
usernamePlaceholder: '用户名',
|
||||
passwordPlaceholder: '密码',
|
||||
defaultCredentialsHint: '默认登录名:admin,默认密码:123456',
|
||||
credentialsRequired: '请输入用户名和密码',
|
||||
invalidCredentials: '用户名或密码错误',
|
||||
tooManyAttempts: '登录失败次数过多,请稍后重试',
|
||||
@@ -24,7 +23,7 @@ export default {
|
||||
offline: '无法连接到服务器 · 登录仍可尝试',
|
||||
showPassword: '显示密码',
|
||||
hidePassword: '隐藏密码',
|
||||
fillDefaultCredentials: '填入 admin / 123456',
|
||||
fillDefaults: '使用默认账号登录',
|
||||
localDeploymentNote: '本地部署 · 无遥测 · 数据不出机器',
|
||||
tokenHint: '登录后 POST /api/auth/login 返回的 token 存入 localStorage',
|
||||
accessDenied: '你没有权限访问该资源',
|
||||
|
||||
@@ -169,11 +169,26 @@ $neon-hv: var(--accent-hover);
|
||||
text-shadow: 0 0 8px rgba(var(--accent-primary-rgb), 0.45);
|
||||
}
|
||||
|
||||
// Arco 为按钮写了 `.arco-btn-primary[type='button']` / `[type='submit']` / `[type='reset']`
|
||||
// 三个属性选择器变体,把特异性从 (0,1,0) 抬到 (0,2,0);它的 hover 变体则是
|
||||
// `.arco-btn-primary[type='submit']:hover` → (0,3,0)。所以下面每条规则都用
|
||||
// `.arco-btn.arco-btn-X[type='...']`(0,3,0)打底,状态规则用 (0,4,0),
|
||||
// 稳压过 Arco 的一整族变体。只写 `.arco-btn-primary` 会被压过,而 a-button
|
||||
// 默认 html-type 就是 button —— 漏掉属性选择器等于所有按钮都不生效。
|
||||
|
||||
// 默认按钮(secondary / 默认态):不发光的幽灵按钮,只在 hover 时点亮管壁
|
||||
.arco-btn-secondary,
|
||||
.arco-btn-secondary.arco-btn-status-warning,
|
||||
.arco-btn-outline,
|
||||
.arco-btn-default {
|
||||
.arco-btn.arco-btn-secondary,
|
||||
.arco-btn.arco-btn-secondary[type='button'],
|
||||
.arco-btn.arco-btn-secondary[type='submit'],
|
||||
.arco-btn.arco-btn-secondary[type='reset'],
|
||||
.arco-btn.arco-btn-outline,
|
||||
.arco-btn.arco-btn-outline[type='button'],
|
||||
.arco-btn.arco-btn-outline[type='submit'],
|
||||
.arco-btn.arco-btn-outline[type='reset'],
|
||||
.arco-btn.arco-btn-default,
|
||||
.arco-btn.arco-btn-default[type='button'],
|
||||
.arco-btn.arco-btn-default[type='submit'],
|
||||
.arco-btn.arco-btn-default[type='reset'] {
|
||||
color: $text-secondary;
|
||||
background: transparent;
|
||||
border: 1px solid $border-color;
|
||||
@@ -191,7 +206,10 @@ $neon-hv: var(--accent-hover);
|
||||
}
|
||||
|
||||
// 主按钮:霓虹管
|
||||
.arco-btn-primary {
|
||||
.arco-btn.arco-btn-primary,
|
||||
.arco-btn.arco-btn-primary[type='button'],
|
||||
.arco-btn.arco-btn-primary[type='submit'],
|
||||
.arco-btn.arco-btn-primary[type='reset'] {
|
||||
@include neon-tube(0.34);
|
||||
font-weight: 600;
|
||||
|
||||
@@ -229,7 +247,10 @@ $neon-hv: var(--accent-hover);
|
||||
text-shadow: 0 0 8px rgba(var(--error-rgb), 0.4);
|
||||
}
|
||||
|
||||
.arco-btn-dangerous {
|
||||
.arco-btn.arco-btn-dangerous,
|
||||
.arco-btn.arco-btn-dangerous[type='button'],
|
||||
.arco-btn.arco-btn-dangerous[type='submit'],
|
||||
.arco-btn.arco-btn-dangerous[type='reset'] {
|
||||
@include neon-tube-danger(0.26);
|
||||
font-weight: 500;
|
||||
|
||||
@@ -252,8 +273,14 @@ $neon-hv: var(--accent-hover);
|
||||
}
|
||||
|
||||
// 文字 / 链接按钮:无管壁,只让文字带辉光
|
||||
.arco-btn-text,
|
||||
.arco-btn-link {
|
||||
.arco-btn.arco-btn-text,
|
||||
.arco-btn.arco-btn-link,
|
||||
.arco-btn.arco-btn-text[type='button'],
|
||||
.arco-btn.arco-btn-text[type='submit'],
|
||||
.arco-btn.arco-btn-text[type='reset'],
|
||||
.arco-btn.arco-btn-link[type='button'],
|
||||
.arco-btn.arco-btn-link[type='submit'],
|
||||
.arco-btn.arco-btn-link[type='reset'] {
|
||||
background: transparent;
|
||||
border: 1px solid transparent;
|
||||
box-shadow: none;
|
||||
@@ -268,12 +295,18 @@ $neon-hv: var(--accent-hover);
|
||||
}
|
||||
|
||||
// 禁用态:灯管熄灭
|
||||
.arco-btn-primary.arco-btn-disabled,
|
||||
.arco-btn-secondary.arco-btn-disabled,
|
||||
.arco-btn-outline.arco-btn-disabled,
|
||||
.arco-btn-dangerous.arco-btn-disabled,
|
||||
.arco-btn-text.arco-btn-disabled,
|
||||
.arco-btn-link.arco-btn-disabled {
|
||||
.arco-btn.arco-btn-primary.arco-btn-disabled,
|
||||
.arco-btn.arco-btn-secondary.arco-btn-disabled,
|
||||
.arco-btn.arco-btn-outline.arco-btn-disabled,
|
||||
.arco-btn.arco-btn-dangerous.arco-btn-disabled,
|
||||
.arco-btn.arco-btn-text.arco-btn-disabled,
|
||||
.arco-btn.arco-btn-link.arco-btn-disabled,
|
||||
.arco-btn.arco-btn-primary[type='button'].arco-btn-disabled,
|
||||
.arco-btn.arco-btn-primary[type='submit'].arco-btn-disabled,
|
||||
.arco-btn.arco-btn-secondary[type='button'].arco-btn-disabled,
|
||||
.arco-btn.arco-btn-secondary[type='submit'].arco-btn-disabled,
|
||||
.arco-btn.arco-btn-dangerous[type='button'].arco-btn-disabled,
|
||||
.arco-btn.arco-btn-dangerous[type='submit'].arco-btn-disabled {
|
||||
color: var(--text-faint);
|
||||
background: transparent;
|
||||
border-color: var(--border-light);
|
||||
@@ -288,7 +321,9 @@ $neon-hv: var(--accent-hover);
|
||||
50% { opacity: 0.62; }
|
||||
}
|
||||
|
||||
.arco-btn-primary.arco-btn-loading {
|
||||
.arco-btn.arco-btn-primary.arco-btn-loading,
|
||||
.arco-btn.arco-btn-primary[type='button'].arco-btn-loading,
|
||||
.arco-btn.arco-btn-primary[type='submit'].arco-btn-loading {
|
||||
@include neon-tube(0.4);
|
||||
animation: neon-pulse 1.1s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@@ -169,13 +169,8 @@ function fillDefaultCredentials() {
|
||||
</form>
|
||||
|
||||
<footer class="login-ft">
|
||||
<div class="login-sep"><span>{{ t("login.defaultCredentialsHint") }}</span></div>
|
||||
<div class="login-chips">
|
||||
<span class="login-chip"><span class="dot"></span>{{ t("login.username") }} <b>admin</b></span>
|
||||
<span class="login-chip"><span class="dot"></span>{{ t("login.passwordPlaceholder") }} <b>123456</b></span>
|
||||
</div>
|
||||
<button type="button" class="login-copy" @click="fillDefaultCredentials">
|
||||
⧉ {{ t("login.fillDefaultCredentials") }}
|
||||
⧉ {{ t("login.fillDefaults") }}
|
||||
</button>
|
||||
<p class="login-legal">
|
||||
{{ t("login.localDeploymentNote") }}<br />
|
||||
@@ -499,58 +494,6 @@ function fillDefaultCredentials() {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.login-sep {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 11px;
|
||||
margin: 0 0 14px;
|
||||
font-size: 11px;
|
||||
color: var(--text-faint);
|
||||
|
||||
&::before,
|
||||
&::after {
|
||||
content: "";
|
||||
flex: 1;
|
||||
height: 1px;
|
||||
background: var(--border-light);
|
||||
}
|
||||
}
|
||||
|
||||
.login-chips {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
gap: 7px;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.login-chip {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 4px 9px;
|
||||
border: 1px solid var(--border-light);
|
||||
border-radius: 20px;
|
||||
background: $bg-card;
|
||||
font-family: $font-code;
|
||||
font-size: 11px;
|
||||
line-height: 1.4;
|
||||
color: $text-muted;
|
||||
|
||||
b {
|
||||
color: $accent-primary;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.dot {
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
border-radius: 50%;
|
||||
background: $success;
|
||||
box-shadow: 0 0 5px $success;
|
||||
}
|
||||
}
|
||||
|
||||
.login-copy {
|
||||
width: 100%;
|
||||
height: 34px;
|
||||
|
||||
Reference in New Issue
Block a user