Lobby
Two-tier chrome, quest panel, Royal Pass strip and the gift dock.
MaxLEVEL 12
2,450
12
Home
Royal GamesHis Majesty awaits
Chapter 3
The East Gate
12/20
31/60
⏳ 2d 4hRoyal Pass12 rewards waiting
Daily Gift ready
⚑ 2d 4h
"use client";
import {
Avatar,
Body,
Bolt,
BottomStack,
BundleCell,
BundleCells,
Button,
Chrome,
ChromeRow,
Coin,
CornerRibbon,
Counter,
Counters,
Dim,
Dock,
FloatChrome,
Gem,
GroupKicker,
Heart,
LevelBadge,
MapPin,
MapScene,
Meter,
Pack,
PackRow,
Panel,
PageDots,
Podium,
PodiumColumn,
ProfileChip,
RankRow,
Ribbon,
Screen,
ScreenName,
SettingsRow,
ShopRow,
StarBurst,
Strike,
Tab,
TabBar,
TimerPill,
Toggle,
TopRibbon,
Slider,
Version,
Well,
Wordmark,
YouBadge,
} from "@objectifthunes/royal-games-ui";
import { useState, type ReactNode } from "react";
const ignoreAction = () => undefined;
interface ResourceCountersProps {
interactive?: boolean;
onAddCoins?: () => void;
onAddGems?: () => void;
}
interface NavigationProps {
onNavigate?: (value: string) => void;
}
function ResourceCounters({
interactive = true,
onAddCoins = ignoreAction,
onAddGems = ignoreAction,
}: ResourceCountersProps) {
return (
<Counters aria-label="Player resources">
{interactive ? (
<>
<Counter graphic={<Coin />} onAdd={onAddCoins} addLabel="Add coins">
2,450
</Counter>
<Counter graphic={<Gem />} onAdd={onAddGems} addLabel="Add gems">
12
</Counter>
</>
) : (
<>
<Counter graphic={<Coin />}>2,450</Counter>
<Counter graphic={<Gem />}>12</Counter>
</>
)}
</Counters>
);
}
interface RoyalChromeProps {
name: ReactNode;
onAddCoins?: () => void;
onAddGems?: () => void;
onOpenSettings?: () => void;
}
function RoyalChrome({
name,
onAddCoins = ignoreAction,
onAddGems = ignoreAction,
onOpenSettings = ignoreAction,
}: RoyalChromeProps) {
return (
<Chrome>
<ChromeRow tone="velvet">
<ProfileChip
avatar={
<Avatar decorative size="small">
♛
</Avatar>
}
name="Max"
caption="LEVEL 12"
/>
<ResourceCounters onAddCoins={onAddCoins} onAddGems={onAddGems} />
</ChromeRow>
<ChromeRow tone="stone">
<ScreenName>{name}</ScreenName>
<Button
tone="primary"
size="small"
iconOnly
aria-label="Settings"
onClick={onOpenSettings}
>
⚙
</Button>
</ChromeRow>
</Chrome>
);
}
interface RoyalTabsProps extends NavigationProps {
initial: string;
}
function RoyalTabs({ initial, onNavigate = ignoreAction }: RoyalTabsProps) {
const [tab, setTab] = useState(initial);
const handleTabChange = (value: string) => {
setTab(value);
onNavigate(value);
};
return (
<TabBar
aria-label="Primary navigation"
value={tab}
onValueChange={handleTabChange}
>
<Tab value="shop" icon="🛒">
Shop
</Tab>
<Tab value="ranks" icon="♛">
Ranks
</Tab>
<Tab value="home" icon="⌂">
Home
</Tab>
<Tab value="map" icon="⚑">
Map
</Tab>
<Tab value="more" icon="⚙" dot>
More
</Tab>
</TabBar>
);
}
// SCREEN_RECIPE: LobbyScreen
export interface LobbyScreenProps extends NavigationProps {
onAddCoins?: () => void;
onAddGems?: () => void;
onClaimGift?: () => void;
onOpenPass?: () => void;
onOpenSettings?: () => void;
onPlay?: () => void;
}
/** Copy-ready dashboard recipe; hosts replace sample data and callbacks. */
export function LobbyScreen({
onAddCoins = ignoreAction,
onAddGems = ignoreAction,
onClaimGift = ignoreAction,
onNavigate = ignoreAction,
onOpenPass = ignoreAction,
onOpenSettings = ignoreAction,
onPlay = ignoreAction,
}: LobbyScreenProps = {}) {
return (
<Screen aria-label="Royal Games home">
<RoyalChrome
name="Home"
onAddCoins={onAddCoins}
onAddGems={onAddGems}
onOpenSettings={onOpenSettings}
/>
<Body layout="dashboard">
<Wordmark strap="His Majesty awaits">Royal Games</Wordmark>
<Panel tone="paper">
<GroupKicker variant="compact">Chapter 3</GroupKicker>
<ScreenName as="h2">The East Gate</ScreenName>
<Counters aria-label="Chapter objectives" layout="spread">
<Counter density="compact" graphic="⚑">
12/20
</Counter>
<Counter density="compact" graphic="★">
31/60
</Counter>
<TimerPill aria-label="Two days and four hours remaining">
⏳ <b>2d 4h</b>
</TimerPill>
</Counters>
<Button tone="accent" size="hero" onClick={onPlay}>
PLAY
</Button>
</Panel>
<Panel tone="primary">
<SettingsRow
variant="control"
icon="👑"
label="Royal Pass"
caption="12 rewards waiting"
control={
<Counters aria-label="Royal Pass position and action">
<PageDots count={3} index={0} />
<Button tone="gold" size="small" onClick={onOpenPass}>
GO
</Button>
</Counters>
}
/>
</Panel>
</Body>
<BottomStack>
<Dock tone="stone" density="roomy">
<SettingsRow
variant="control"
icon="🎁"
label="Daily Gift ready"
control={
<Counters aria-label="Daily gift actions">
<Button tone="positive" size="small" onClick={onClaimGift}>
CLAIM
</Button>
<TimerPill aria-label="Two days and four hours remaining">
⚑ <b>2d 4h</b>
</TimerPill>
</Counters>
}
/>
</Dock>
<RoyalTabs initial="home" onNavigate={onNavigate} />
</BottomStack>
</Screen>
);
}This is the exact component rendered above, including imports, responsive placement, state, and interaction wiring. Copy it as a starting screen and replace the example data and artwork with your game's values.