feat(web): iOS/iPad 下载卡合一 + 双按钮 + 正式版「?」气泡提示
- 三张 iOS/iPad 卡合成一张:测试版(TestFlight,实心可点)+ 正式版(App Store,描边禁用)双按钮。 - 「?」移入正式版按钮内,自定义 tooltip 气泡(走设计 token,上浮淡入+小箭头)替代原生 title, 悬浮/聚焦显示「美区即将上线 · 需美区 Apple ID」;光标不再变问号。 - 新增 i18n 文案 dl.us_soon(6 语)。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -7,11 +7,17 @@ interface Props { t: T }
|
||||
const { t } = Astro.props;
|
||||
|
||||
// href 缺省 = 未接入下载 → 禁用「敬请期待」占位。
|
||||
// iOS/iPad 目前仅「测试版」(TestFlight 公开链接,需美区 Apple ID);「正式版」(App Store)敬请期待。
|
||||
const plats: { icon: string; name: string; ver: string; href?: string; badge?: string; note?: string }[] = [
|
||||
{ icon: 'smartphone', name: 'iOS', ver: 'iOS 15+', href: SITE.downloads.ios, badge: t('dl.beta'), note: t('dl.us_id') },
|
||||
{ icon: 'tablet', name: 'iPad', ver: 'iPadOS 15+', href: SITE.downloads.ios, badge: t('dl.beta'), note: t('dl.us_id') },
|
||||
{ icon: 'smartphone', name: 'iOS / iPad', ver: 'App Store', badge: t('dl.stable') },
|
||||
// iOS/iPad 合成一张卡、两个按钮:「测试版」(TestFlight 公开链接) 现已可装,
|
||||
// 「正式版」(App Store) 禁用,按钮内带「?」——悬浮提示「美区即将上线,需美区 Apple ID」。
|
||||
type Action = { label: string; href?: string; hint?: string };
|
||||
const plats: { icon: string; name: string; ver: string; href?: string; badge?: string; note?: string; actions?: Action[] }[] = [
|
||||
{
|
||||
icon: 'smartphone', name: 'iOS / iPad', ver: 'iOS / iPadOS 15+',
|
||||
actions: [
|
||||
{ label: t('dl.beta'), href: SITE.downloads.ios },
|
||||
{ label: t('dl.stable'), hint: `${t('dl.us_soon')} · ${t('dl.us_id')}` },
|
||||
],
|
||||
},
|
||||
{ icon: 'smartphone', name: 'Android', ver: 'Android 9+', href: SITE.downloads.android },
|
||||
{ icon: 'laptop', name: 'macOS', ver: 'macOS 12+', href: SITE.downloads.macos },
|
||||
{ icon: 'monitor', name: 'Windows', ver: 'Win 10/11', href: SITE.downloads.windows },
|
||||
@@ -35,7 +41,24 @@ const plats: { icon: string; name: string; ver: string; href?: string; badge?: s
|
||||
{p.note && <span class="q" title={p.note} tabindex="0" aria-label={p.note}>?</span>}
|
||||
</div>
|
||||
<div class="pv">{p.ver}</div>
|
||||
{p.href ? (
|
||||
{p.actions ? (
|
||||
<div class="btns">
|
||||
{p.actions.map((a) => (
|
||||
a.href ? (
|
||||
<a class="b2 beta" href={a.href}><span>{a.label}</span></a>
|
||||
) : (
|
||||
<span class="b2 disabled" aria-disabled="true">
|
||||
<span>{a.label}</span>
|
||||
{a.hint && (
|
||||
<span class="q" tabindex="0" aria-label={a.hint}>
|
||||
?<span class="tip" role="tooltip">{a.hint}</span>
|
||||
</span>
|
||||
)}
|
||||
</span>
|
||||
)
|
||||
))}
|
||||
</div>
|
||||
) : p.href ? (
|
||||
<a class="gb" href={p.href}><Icon name="download" /><span>{t('dl.get')}</span></a>
|
||||
) : (
|
||||
<span class="gb disabled" aria-disabled="true"><Icon name="download" /><span>{t('dl.soon')}</span></span>
|
||||
@@ -56,9 +79,45 @@ const plats: { icon: string; name: string; ver: string; href?: string; badge?: s
|
||||
font-family: var(--font-mono); letter-spacing: .02em;
|
||||
}
|
||||
.dl .q {
|
||||
position: relative;
|
||||
display: inline-flex; align-items: center; justify-content: center;
|
||||
width: 16px; height: 16px; border-radius: 50%;
|
||||
font-size: 11px; font-weight: 700; cursor: help;
|
||||
font-size: 11px; font-weight: 700; cursor: default;
|
||||
background: var(--bg-subtle); color: var(--fg3);
|
||||
}
|
||||
/* 自定义提示气泡:走设计 token,悬浮/聚焦「?」时上浮显示,带小箭头。 */
|
||||
.dl .q .tip {
|
||||
position: absolute; bottom: calc(100% + 9px); left: 50%;
|
||||
transform: translateX(-50%) translateY(4px);
|
||||
width: max-content; max-width: 210px; white-space: normal;
|
||||
padding: 8px 11px; border-radius: var(--radius-md, 10px);
|
||||
background: var(--fg1); color: var(--bg);
|
||||
font-family: var(--font-sans); font-size: 12px; font-weight: 500;
|
||||
line-height: 1.45; text-align: center; letter-spacing: 0;
|
||||
box-shadow: var(--shadow-md, 0 6px 20px rgba(45,30,20,.18));
|
||||
opacity: 0; visibility: hidden; pointer-events: none; z-index: 20;
|
||||
transition: opacity var(--dur-base, .18s) var(--ease-out, ease),
|
||||
transform var(--dur-base, .18s) var(--ease-out, ease),
|
||||
visibility var(--dur-base, .18s);
|
||||
}
|
||||
.dl .q .tip::after {
|
||||
content: ""; position: absolute; top: 100%; left: 50%;
|
||||
transform: translateX(-50%);
|
||||
border: 5px solid transparent; border-top-color: var(--fg1);
|
||||
}
|
||||
.dl .q:hover .tip, .dl .q:focus-visible .tip {
|
||||
opacity: 1; visibility: visible; transform: translateX(-50%) translateY(0);
|
||||
}
|
||||
/* iOS/iPad 单卡双按钮:测试版(实心 accent 可点)+ 正式版(描边禁用,内含「?」悬浮提示)。 */
|
||||
.dl .btns { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; margin-top: 2px; }
|
||||
.dl .b2 {
|
||||
display: inline-flex; align-items: center; justify-content: center; gap: 6px;
|
||||
padding: 8px 15px; border-radius: 999px; line-height: 1.15;
|
||||
font-size: 13px; font-weight: 600; text-decoration: none;
|
||||
border: 1px solid var(--accent); color: var(--accent);
|
||||
}
|
||||
.dl .b2.beta { background: var(--accent); color: var(--fg-on-accent); border-color: var(--accent); }
|
||||
/* 禁用态:不导航(本就是 span)+ 默认光标,但不禁用指针事件——否则内含「?」的 title 悬浮失效。 */
|
||||
.dl .b2.disabled { border-color: var(--border); color: var(--fg3); cursor: default; }
|
||||
.dl .b2 .q { background: transparent; border: 1px solid var(--border); }
|
||||
</style>
|
||||
|
||||
@@ -140,6 +140,7 @@ export const STRINGS: Record<string, Record<Lang, string>> = {
|
||||
'dl.beta': { zh: '测试版', en: 'Beta', ja: 'ベータ版', ko: '베타', ru: 'Бета', es: 'Beta' },
|
||||
'dl.stable': { zh: '正式版', en: 'Stable', ja: '正式版', ko: '정식판', ru: 'Релиз', es: 'Estable' },
|
||||
'dl.us_id': { zh: '需美区 Apple ID', en: 'Requires a US Apple ID', ja: '米国 Apple ID が必要', ko: '미국 Apple ID 필요', ru: 'Нужен Apple ID (США)', es: 'Requiere un Apple ID de EE. UU.' },
|
||||
'dl.us_soon': { zh: '美区即将上线', en: 'Coming to US App Store', ja: '米国 App Store で近日公開', ko: '미국 App Store 출시 예정', ru: 'Скоро в App Store (США)', es: 'Pronto en App Store (EE. UU.)' },
|
||||
|
||||
'docs.eyebrow': { zh: '文档', en: 'Docs', ja: 'ドキュメント', ko: '문서', ru: 'Документация', es: 'Documentación' },
|
||||
'docs.h': { zh: '需要帮助?都在这里', en: 'Need help? It’s all here', ja: 'お困りですか?すべてここに', ko: '도움이 필요하세요? 모두 여기에', ru: 'Нужна помощь? Всё здесь', es: '¿Necesitas ayuda? Todo está aquí' },
|
||||
|
||||
Reference in New Issue
Block a user