// Android (Material 3) shared components and screens // Wrapped in AndroidDevice (412 × 892), inner content ~396 × 820. const M = { // Material 3 token mapping for our blue brand primary: '#1B5BFF', onPrimary: '#FFFFFF', primaryContainer: '#DCE7FF', onPrimaryContainer: '#0B1F4D', secondary: '#5B9EFF', tertiary: '#22C29A', error: '#E5484D', surface: '#FAFBFE', surfaceDim: '#EFF3FA', surfaceContainer: '#EEF3FF', surfaceContainerHigh: '#E2EAFA', surfaceContainerLow: '#F5F7FC', surfaceVariant: '#E4E8F2', onSurface: '#0B132B', onSurfaceVariant: '#5B6784', outline: '#B5BFD4', outlineVar: '#D9DFEC', }; // ── Material Top App Bar ────────────────────────────────────── function MdAppBar({ title, leading = 'back', trailing = ['bell'], subtitle, tone = 'surface' }) { const bg = tone === 'primary' ? M.primary : (tone === 'surfaceContainer' ? M.surfaceContainer : M.surface); const fg = tone === 'primary' ? 'white' : M.onSurface; const muted = tone === 'primary' ? 'rgba(255,255,255,0.85)' : M.onSurfaceVariant; const Leading = { back: IconChevL, menu: IconFilter, none: null }[leading]; return (
{Leading && (
)}
{title}
{subtitle &&
{subtitle}
}
{trailing.map((t, i) => { const I = { bell: IconBell, search: IconSearch, cart: IconCart, more: null, heart: IconHeart, close: IconClose }[t]; return (
{I ? : (
)}
); })}
); } // ── Material 3 bottom navigation bar (with active pill) ────── function MdBottomNav({ active = 'home' }) { const items = [ { id: 'home', label: 'Home', Icon: IconHome }, { id: 'browse', label: 'Browse', Icon: IconSearch }, { id: 'cart', label: 'Cart', Icon: IconCart, badge: 3 }, { id: 'orders', label: 'Orders', Icon: IconBox }, { id: 'profile', label: 'You', Icon: IconUser }, ]; return (
{items.map((it) => { const isActive = it.id === active; return (
{it.badge && (
{it.badge}
)}
{it.label}
); })}
); } // ── M3 FAB ─────────────────────────────────────────────────── function MdFab({ icon: I = IconRx, label, extended = false, bottom = 116, right = 16 }) { if (extended) { return (
{label}
); } return (
); } // ── M3 Filled / Tonal / Outlined / Text buttons ────────────── function MdButton({ children, variant = 'filled', icon: I, full = false, style = {} }) { const base = { height: 40, borderRadius: 20, padding: '0 24px', border: 'none', fontSize: 14, fontWeight: 600, letterSpacing: 0.1, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 8, fontFamily: 'Roboto, system-ui, sans-serif', cursor: 'pointer', width: full ? '100%' : 'auto', ...style, }; const variants = { filled: { background: M.primary, color: 'white' }, tonal: { background: M.primaryContainer, color: M.onPrimaryContainer }, outlined: { background: 'transparent', color: M.primary, border: `1px solid ${M.outline}` }, text: { background: 'transparent', color: M.primary, padding: '0 12px' }, elevated: { background: M.surfaceContainerLow, color: M.primary, boxShadow: '0 1px 3px rgba(0,0,0,0.10)' }, }; return ; } // ── M3 Filter / Assist chip ────────────────────────────────── function MdChip({ children, selected = false, icon = null, style = {} }) { return (
{selected && } {icon && !selected && icon} {children}
); } // ── Search bar (M3 docked) ─────────────────────────────────── function MdSearchBar({ value = 'Search medicines, brands, tests', leading = 'menu' }) { const L = { menu: IconFilter, search: IconSearch, back: IconChevL }[leading]; return (
{value}
); } // ── Section header (Material style) ────────────────────────── function MdSection({ title, action = 'View all' }) { return (
{title}
{action &&
{action}
}
); } Object.assign(window, { M, MdAppBar, MdBottomNav, MdFab, MdButton, MdChip, MdSearchBar, MdSection, });