Desktop: compact app hero on every tab but Releases; Ctrl+K lists the current app's menu actions; Alt+Up/Down switches apps; shortcuts list; no focus ring on code-focused headings
This commit is contained in:
parent
a656240bfb
commit
7c18b3f7dd
7 changed files with 63 additions and 10 deletions
|
|
@ -179,16 +179,19 @@ export function PageHeader({ title, subtitle, eyebrow, actions, icon }: { title:
|
|||
}
|
||||
|
||||
/** App hero: screenshots strip, big icon, name, ids, store links, the two-store pipeline and the next step. */
|
||||
export function Hero({ name, icon, projectId, ids, badges, links, all, ios, android, cta, onCta, next, children, onContextMenu }: {
|
||||
export function Hero({ name, icon, projectId, ids, badges, links, all, ios, android, cta, onCta, next, children, onContextMenu, compact }: {
|
||||
name: string; icon: string | null; projectId: string | null; ids?: ReactNode; badges?: ReactNode; links?: ReactNode;
|
||||
/** The app's context menu (useContextMenu props). */
|
||||
onContextMenu?: (e: ReactMouseEvent) => void;
|
||||
/** One slim row (icon, name, ids, next step): every tab but the overview, so the tab's content starts high. */
|
||||
compact?: boolean;
|
||||
all: StoreRelease[]; ios: boolean; android: boolean; cta?: Cta | null; onCta?: (tab: AppTab) => void; next?: string | null; children?: ReactNode;
|
||||
}) {
|
||||
const hue = useTint(icon, name);
|
||||
const shots = useShots(projectId, 4);
|
||||
const shots = useShots(compact ? null : projectId, 4);
|
||||
const ctaBtn = cta && <button className={`btn ${cta.primary ? 'btn-primary' : ''} pf-cta`} onClick={() => onCta?.(cta.tab)}><Icon name={cta.icon} />{cta.text}</button>;
|
||||
return (
|
||||
<section className="ds-hero" style={tintStyle(hue)} aria-label={name} onContextMenu={onContextMenu}>
|
||||
<section className={`ds-hero${compact ? ' compact' : ''}`} style={tintStyle(hue)} aria-label={name} onContextMenu={onContextMenu}>
|
||||
<div className="ds-hero-main">
|
||||
<div className="ds-hero-id">
|
||||
<AppIcon name={name} src={icon} className="ds-hero-icon" />
|
||||
|
|
@ -197,18 +200,19 @@ export function Hero({ name, icon, projectId, ids, badges, links, all, ios, andr
|
|||
{ids && <div className="ds-hero-ids">{ids}</div>}
|
||||
{links && <div className="ds-hero-links">{links}</div>}
|
||||
</div>
|
||||
{compact && ctaBtn && <div className="ds-hero-cta">{ctaBtn}</div>}
|
||||
</div>
|
||||
<div className="ds-hero-pipe">
|
||||
{!compact && <div className="ds-hero-pipe">
|
||||
<Pipeline all={all} ios={ios} android={android} size="lg" />
|
||||
<div className="ds-hero-foot">
|
||||
<div className="ds-hero-next"><span className="pf-next-l">{t('pf.next')}</span><span className="ds-hero-next-v num">{next ?? '–'}</span></div>
|
||||
{cta && <button className={`btn ${cta.primary ? 'btn-primary' : ''} pf-cta`} onClick={() => onCta?.(cta.tab)}><Icon name={cta.icon} />{cta.text}</button>}
|
||||
{ctaBtn}
|
||||
</div>
|
||||
</div>
|
||||
</div>}
|
||||
{children}
|
||||
</div>
|
||||
{/* no screenshots: no second (cropped) copy of the icon, which already leads the hero */}
|
||||
{shots.length > 0 && <div className="ds-hero-shots" aria-hidden="true">
|
||||
{!compact && shots.length > 0 && <div className="ds-hero-shots" aria-hidden="true">
|
||||
{shots.map((s, i) => <img key={i} src={s} alt="" draggable={false} />)}
|
||||
</div>}
|
||||
</section>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue