Desktop: custom context menus everywhere, never the browser's menu
One ContextMenu in the design system (keyboard, type-ahead, submenus, check items, disabled reasons, Shift+F10 / Menu key, viewport placement, light and dark). The native menu is prevented globally; text fields keep Cut / Copy / Paste / Select all. Menus on sidebar and portfolio apps, app hero, releases, store art, live art, reviews, checks, editor fields, catalog, prices, accounts, app folders, ignored.
This commit is contained in:
parent
944b24fe59
commit
dece83c3e8
23 changed files with 839 additions and 28 deletions
|
|
@ -2,7 +2,7 @@
|
|||
// the portfolio home as reusable parts. PageHeader, Hero (app hero with screenshots, two-store pipeline, next step),
|
||||
// Section, StatTile, Pipeline, StatusPill, EmptyState, Tabs, Toolbar, Dialog, plus the per-app tint (useTint / tintStyle)
|
||||
// and the rendered-screenshot loader (useShots) the cards and the hero share.
|
||||
import { type CSSProperties, type KeyboardEvent, type ReactNode, useEffect, useId, useRef, useState } from 'react';
|
||||
import { type CSSProperties, type KeyboardEvent, type MouseEvent as ReactMouseEvent, type ReactNode, useEffect, useId, useRef, useState } from 'react';
|
||||
import { api, reads, type RenderImage, type StoreRelease, type ToolResult } from '../api';
|
||||
import { type Key, t } from '../i18n';
|
||||
import { share } from '../lib/format';
|
||||
|
|
@ -179,14 +179,16 @@ 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 }: {
|
||||
export function Hero({ name, icon, projectId, ids, badges, links, all, ios, android, cta, onCta, next, children, onContextMenu }: {
|
||||
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;
|
||||
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);
|
||||
return (
|
||||
<section className="ds-hero" style={tintStyle(hue)} aria-label={name}>
|
||||
<section className="ds-hero" 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" />
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue