updates on the design on the kpi cards

This commit is contained in:
2026-08-20 16:53:34 +05:30
parent ce32465a6f
commit 1bf89adb6a
10 changed files with 973 additions and 274 deletions

View File

@@ -6,40 +6,83 @@ import { Heading } from '@astryxdesign/core/Heading';
import { Text } from '@astryxdesign/core/Text';
import { StatusDot } from '@astryxdesign/core/StatusDot';
// ==============================|| PAGE HEADER (Doormile-style clean title) ||============================== //
// A plain, un-boxed page title + optional live subtitle + an action slot
// (zone selector, primary button, etc.). Replaces the heavy boxed/gradient
// header so every operator page opens with a calm, corporate heading.
//
// Astryx: Heading level={1} resolves to --text-heading-1-size (1.5rem), the
// same size the old MUI `variant="h3"` rendered — the visual weight of every
// page title is unchanged by the migration. The old responsive
// `direction={{ xs: 'column', sm: 'row' }}` is now wrap="wrap" on a single
// HStack: the action slot drops to its own line once it can't fit, which is
// the behaviour that breakpoint was approximating.
import { DT } from 'themes/dt/tokens';
export default function PageHeader({ title, subtitle, live = false, action }) {
// ==============================|| PAGE HEADER ||============================== //
//
// A plain, un-boxed page title + optional live indicator + an action slot
// (zone selector, primary button, etc.), so every operator page opens with a
// calm, corporate heading.
//
// The STRUCTURE follows KROW's page frame; the colours and the type are the
// console's own and are unchanged — `Heading level={1}` and `Text
// type="supporting"` resolve to exactly the same tokens they did before.
//
// Title · meta · ● Live [ actions ]
// subtitle
// ──────────────────────────────────────────────────────────────
//
// Two things the KROW work changed:
//
// - The bottom hairline. KROW closes every page header with a rule, and it
// is what makes the header read as a REGION of the page rather than as
// the first item in the content stack — without it, a page header and a
// section heading look identical and the page has no top.
//
// - `live` moved from beside the subtitle up onto the title row. It was
// putting the page's only motion cue on its quietest line; a live
// indicator belongs where people look for it. It is still the same
// pulsing `StatusDot variant="success"` — nothing about its colour moved.
//
// `meta` is new and optional: a real count that belongs beside the name
// ("1,248 orders"), with tabular figures so it doesn't jitter as it updates.
//
// `action` keeps its name and still wraps to its own line once it can't fit,
// which is the behaviour the old responsive `direction={{ xs: 'column', sm:
// 'row' }}` was approximating.
export default function PageHeader({ title, subtitle, meta, live = false, action }) {
return (
<HStack justify="between" vAlign="center" wrap="wrap" gap={2} paddingBlock={1}>
<VStack gap={0.5} padding={0} minWidth={0}>
<Heading level={1} maxLines={1}>
{title}
</Heading>
{subtitle && (
<HStack gap={1} vAlign="center">
<VStack
gap={0}
padding={0}
style={{
paddingBottom: 16,
// The existing hairline at 50% alpha — a page header's rule should sit
// under the table borders it introduces, not match them.
borderBottom: `1px solid ${DT.borderSubtle}80`
}}
>
<HStack justify="between" vAlign="center" wrap="wrap" gap={2} paddingBlock={1}>
{/* minWidth in `style` — VStack has no such prop (see StatCard). */}
<VStack gap={0.5} padding={0} style={{ minWidth: 0 }}>
<HStack gap={2} vAlign="center" wrap="wrap">
<Heading level={1} maxLines={1}>
{title}
</Heading>
{meta != null && (
<Text type="supporting" hasTabularNumbers>
{meta}
</Text>
)}
{live && <StatusDot variant="success" label="Live" isPulsing />}
<Text type="supporting">{subtitle}</Text>
</HStack>
{subtitle && <Text type="supporting">{subtitle}</Text>}
</VStack>
{action && (
<HStack gap={1.5} vAlign="center" wrap="wrap" style={{ flexShrink: 0 }}>
{action}
</HStack>
)}
</VStack>
{action && <HStack gap={1.5}>{action}</HStack>}
</HStack>
</HStack>
</VStack>
);
}
PageHeader.propTypes = {
title: PropTypes.node,
subtitle: PropTypes.node,
meta: PropTypes.node,
live: PropTypes.bool,
action: PropTypes.node
};