@caratlogic/design-system 0.1.30 → 0.1.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,9 @@
1
1
  import type { ReactElement } from 'react';
2
2
  import type { DocumentHeroProps } from './DocumentHero.types';
3
- export type { DocumentHeroBar, DocumentHeroBarTone, DocumentHeroBreakdown, DocumentHeroMeta, DocumentHeroPayment, DocumentHeroProps, DocumentHeroSegment, DocumentHeroSegmentTone, DocumentHeroStatusTone, DocumentHeroTone, } from './DocumentHero.types';
3
+ export type { DocumentHeroBreakdown, DocumentHeroDetail, DocumentHeroFact, DocumentHeroFactTone, DocumentHeroProgress, DocumentHeroProps, DocumentHeroSegment, DocumentHeroSegmentTone, DocumentHeroTone, } from './DocumentHero.types';
4
4
  /**
5
- * The top of a document detail page: its total, how much of it is settled
6
- * (paid, or carats returned/sold) and its key dates. Data-only.
5
+ * The top of a document detail page: the headline amount (balance, total, value),
6
+ * how much of it is settled, and the key dates and facts beside it. Data-only.
7
7
  */
8
- export declare function DocumentHero({ label, total, caption, captionTone, payment, bars, breakdown, meta, statusTone, className, }: DocumentHeroProps): ReactElement;
8
+ export declare function DocumentHero({ label, labelIcon, tone, amount, amountNote, progress, breakdown, facts, details, detailsLabel, detailsIcon, className, }: DocumentHeroProps): ReactElement;
9
9
  //# sourceMappingURL=DocumentHero.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DocumentHero.d.ts","sourceRoot":"","sources":["../../../../src/components/molecules/DocumentHero/DocumentHero.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAE1C,OAAO,KAAK,EAAyB,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAgBrF,YAAY,EACV,eAAe,EACf,mBAAmB,EACnB,qBAAqB,EACrB,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACnB,uBAAuB,EACvB,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,sBAAsB,CAAC;AAuC9B;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,KAAK,EACL,OAAO,EACP,WAAuB,EACvB,OAAO,EACP,IAAI,EACJ,SAAS,EACT,IAAS,EACT,UAAsB,EACtB,SAAS,GACV,EAAE,iBAAiB,GAAG,YAAY,CAgIlC"}
1
+ {"version":3,"file":"DocumentHero.d.ts","sourceRoot":"","sources":["../../../../src/components/molecules/DocumentHero/DocumentHero.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAE1C,OAAO,KAAK,EAIV,iBAAiB,EAElB,MAAM,sBAAsB,CAAC;AAa9B,YAAY,EACV,qBAAqB,EACrB,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,EACpB,iBAAiB,EACjB,mBAAmB,EACnB,uBAAuB,EACvB,gBAAgB,GACjB,MAAM,sBAAsB,CAAC;AAqK9B;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,SAAS,EACT,IAAgB,EAChB,MAAM,EACN,UAAU,EACV,QAAQ,EACR,SAAS,EACT,KAAU,EACV,OAAY,EACZ,YAAY,EACZ,WAAW,EACX,SAAS,GACV,EAAE,iBAAiB,GAAG,YAAY,CAmGlC"}
@@ -1,27 +1,23 @@
1
1
  import type { ReactNode } from 'react';
2
- export type DocumentHeroTone = 'default' | 'success' | 'destructive';
3
- /** The document's state, tinting the hero: settled, at risk, draft/void… */
4
- export type DocumentHeroStatusTone = 'neutral' | 'success' | 'info' | 'warning' | 'destructive' | 'muted';
5
- export type DocumentHeroBarTone = 'primary' | 'success' | 'info';
6
- export interface DocumentHeroPayment {
7
- paid: ReactNode;
8
- outstanding: ReactNode;
2
+ /**
3
+ * The document's state: colours the heading, the bar's track and the facts panel to match its status pill.
4
+ * The amount itself stays neutral.
5
+ */
6
+ export type DocumentHeroTone = 'default' | 'success' | 'info' | 'warning' | 'destructive' | 'muted';
7
+ /** Colours a fact's icon tile and note; `success` also colours its value. */
8
+ export type DocumentHeroFactTone = 'default' | 'success' | 'warning' | 'destructive';
9
+ export interface DocumentHeroProgress {
9
10
  /** 0–100; clamped. */
10
11
  percent: number;
11
- /** e.g. "39% paid · partially paid". */
12
- caption?: ReactNode;
13
- paidLabel?: string;
14
- outstandingLabel?: string;
15
- }
16
- export interface DocumentHeroBar {
17
- label: string;
18
- /** Shown at the right of the bar, e.g. "5.20 ct". */
19
- value: ReactNode;
20
- /** 0–100; clamped. */
21
- percent: number;
22
- tone?: DocumentHeroBarTone;
12
+ /** Highlighted at the start of the line under the bar, e.g. "$2,000.00". */
13
+ value?: ReactNode;
14
+ /** Follows `value`, e.g. "paid". */
15
+ label?: ReactNode;
16
+ /** End of the line under the bar, e.g. "39%" or "4 days before due date". */
17
+ trailing?: ReactNode;
23
18
  }
24
- export type DocumentHeroSegmentTone = 'success' | 'info' | 'primary' | 'warning' | 'remaining';
19
+ /** `primary-soft` is a lighter tint of the brand colour, for pairing with `primary` in one bar. */
20
+ export type DocumentHeroSegmentTone = 'success' | 'info' | 'primary' | 'primary-soft' | 'warning' | 'remaining';
25
21
  export interface DocumentHeroSegment {
26
22
  label: string;
27
23
  /** Shown under the label, e.g. "4.38 ct". */
@@ -39,34 +35,45 @@ export interface DocumentHeroBreakdown {
39
35
  /** e.g. "100% settled · 4.38 ct on memo". */
40
36
  caption?: ReactNode;
41
37
  }
42
- export interface DocumentHeroMeta {
38
+ export interface DocumentHeroFact {
43
39
  label: string;
44
40
  value: ReactNode;
45
- /** Shows the cell in red text, e.g. an overdue due date. */
46
- danger?: boolean;
47
- /** Shown in muted italics when there's no value, e.g. "Not paid yet". Defaults to "Not provided". */
41
+ /** Icon element or a short glyph such as a currency symbol. */
42
+ icon: ReactNode;
43
+ /** Small text after the value, e.g. "in 7 days" or "6 days overdue". */
44
+ note?: ReactNode;
45
+ tone?: DocumentHeroFactTone;
46
+ /** Shown muted when there's no value. Defaults to "Not provided". */
47
+ emptyLabel?: string;
48
+ /** Adds a small link after the value, e.g. "View" scrolling to the payments. */
49
+ onAction?: () => void;
50
+ actionLabel?: string;
51
+ }
52
+ export interface DocumentHeroDetail {
53
+ label: string;
54
+ value: ReactNode;
55
+ /** Shown muted when there's no value. Defaults to "Not provided". */
48
56
  emptyLabel?: string;
49
57
  }
50
58
  export interface DocumentHeroProps {
51
- /** e.g. "Invoice total". */
59
+ /** Small heading above the amount, e.g. "Balance due". */
52
60
  label: string;
53
- total: ReactNode;
54
- /** e.g. "USD · paid in full on 3 Oct 2026". */
55
- caption?: ReactNode;
56
- captionTone?: DocumentHeroTone;
57
- /**
58
- * Light status tint: on the payment / bars panel when there is one, else on the whole card.
59
- * `destructive` on a payment also tints the progress track (e.g. overdue).
60
- */
61
- statusTone?: DocumentHeroStatusTone;
62
- /** Paid vs outstanding with a progress bar. */
63
- payment?: DocumentHeroPayment;
64
- /** Carat (or any quantity) bars, e.g. on memo / returned / sold. Used when there's no `payment`. */
65
- bars?: DocumentHeroBar[];
66
- /** A whole split into parts on one stacked bar. Used when there's no `payment`; wins over `bars`. */
61
+ labelIcon?: ReactNode;
62
+ tone?: DocumentHeroTone;
63
+ amount: ReactNode;
64
+ /** Beside the amount, e.g. "of $5,176.50 total". */
65
+ amountNote?: ReactNode;
66
+ /** Bar under the amount, e.g. how much is paid. */
67
+ progress?: DocumentHeroProgress;
68
+ /** A whole split into parts on one stacked bar. Used instead of `progress`. */
67
69
  breakdown?: DocumentHeroBreakdown;
68
- /** Key dates and facts along the bottom. */
69
- meta?: DocumentHeroMeta[];
70
+ /** Key dates and facts, listed on the right (below on narrow screens). Keep to about four. */
71
+ facts?: DocumentHeroFact[];
72
+ /** Secondary facts (tax registration, references…) in a slim strip along the bottom. */
73
+ details?: DocumentHeroDetail[];
74
+ /** Names the details strip, e.g. "GST". */
75
+ detailsLabel?: string;
76
+ detailsIcon?: ReactNode;
70
77
  className?: string;
71
78
  }
72
79
  //# sourceMappingURL=DocumentHero.types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DocumentHero.types.d.ts","sourceRoot":"","sources":["../../../../src/components/molecules/DocumentHero/DocumentHero.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,SAAS,GAAG,aAAa,CAAC;AAErE,4EAA4E;AAC5E,MAAM,MAAM,sBAAsB,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,aAAa,GAAG,OAAO,CAAC;AAC1G,MAAM,MAAM,mBAAmB,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC;AAEjE,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,SAAS,CAAC;IAChB,WAAW,EAAE,SAAS,CAAC;IACvB,sBAAsB;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,wCAAwC;IACxC,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,KAAK,EAAE,SAAS,CAAC;IACjB,sBAAsB;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,mBAAmB,CAAC;CAC5B;AAED,MAAM,MAAM,uBAAuB,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,CAAC;AAE/F,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,KAAK,EAAE,SAAS,CAAC;IACjB,iFAAiF;IACjF,MAAM,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,IAAI,EAAE,uBAAuB,CAAC;CAC/B;AAED,6FAA6F;AAC7F,MAAM,WAAW,qBAAqB;IACpC,+DAA+D;IAC/D,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAChC,6CAA6C;IAC7C,OAAO,CAAC,EAAE,SAAS,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,CAAC;IACjB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,qGAAqG;IACrG,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,CAAC;IACjB,+CAA+C;IAC/C,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAC/B;;;OAGG;IACH,UAAU,CAAC,EAAE,sBAAsB,CAAC;IACpC,+CAA+C;IAC/C,OAAO,CAAC,EAAE,mBAAmB,CAAC;IAC9B,oGAAoG;IACpG,IAAI,CAAC,EAAE,eAAe,EAAE,CAAC;IACzB,qGAAqG;IACrG,SAAS,CAAC,EAAE,qBAAqB,CAAC;IAClC,4CAA4C;IAC5C,IAAI,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
1
+ {"version":3,"file":"DocumentHero.types.d.ts","sourceRoot":"","sources":["../../../../src/components/molecules/DocumentHero/DocumentHero.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GACxB,SAAS,GACT,SAAS,GACT,MAAM,GACN,SAAS,GACT,aAAa,GACb,OAAO,CAAC;AAEZ,6EAA6E;AAC7E,MAAM,MAAM,oBAAoB,GAC5B,SAAS,GACT,SAAS,GACT,SAAS,GACT,aAAa,CAAC;AAElB,MAAM,WAAW,oBAAoB;IACnC,sBAAsB;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,4EAA4E;IAC5E,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,oCAAoC;IACpC,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,mGAAmG;AACnG,MAAM,MAAM,uBAAuB,GAC/B,SAAS,GACT,MAAM,GACN,SAAS,GACT,cAAc,GACd,SAAS,GACT,WAAW,CAAC;AAEhB,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,KAAK,EAAE,SAAS,CAAC;IACjB,iFAAiF;IACjF,MAAM,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,IAAI,EAAE,uBAAuB,CAAC;CAC/B;AAED,6FAA6F;AAC7F,MAAM,WAAW,qBAAqB;IACpC,+DAA+D;IAC/D,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAChC,6CAA6C;IAC7C,OAAO,CAAC,EAAE,SAAS,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,CAAC;IACjB,+DAA+D;IAC/D,IAAI,EAAE,SAAS,CAAC;IAChB,wEAAwE;IACxE,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,IAAI,CAAC,EAAE,oBAAoB,CAAC;IAC5B,qEAAqE;IACrE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gFAAgF;IAChF,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,CAAC;IACjB,qEAAqE;IACrE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB,MAAM,EAAE,SAAS,CAAC;IAClB,oDAAoD;IACpD,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,mDAAmD;IACnD,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IAChC,+EAA+E;IAC/E,SAAS,CAAC,EAAE,qBAAqB,CAAC;IAClC,8FAA8F;IAC9F,KAAK,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC3B,wFAAwF;IACxF,OAAO,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAC/B,2CAA2C;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
@@ -1,22 +1,13 @@
1
- import type { DocumentHeroBarTone, DocumentHeroSegment, DocumentHeroSegmentTone, DocumentHeroStatusTone, DocumentHeroTone } from './DocumentHero.types';
1
+ import type { DocumentHeroFactTone, DocumentHeroSegment, DocumentHeroSegmentTone, DocumentHeroTone } from './DocumentHero.types';
2
2
  export declare function clampPercent(value: number): number;
3
- export declare function getCaptionClassName(tone: DocumentHeroTone): string;
4
- export declare function getBarClassName(tone: DocumentHeroBarTone): string;
3
+ export declare function getLabelClassName(tone: DocumentHeroTone): string;
4
+ export declare function getFactsPanelClassName(tone: DocumentHeroTone): string;
5
+ export declare function getProgressTrackClassName(tone: DocumentHeroTone): string;
6
+ export declare function getFactIconClassName(tone: DocumentHeroFactTone): string;
7
+ export declare function getFactNoteClassName(tone: DocumentHeroFactTone): string;
5
8
  export declare function getSegmentClassName(tone: DocumentHeroSegmentTone): string;
6
9
  /** Each segment's width in percent of the segments' sum; all 0 when there's nothing to split. */
7
10
  export declare function getSegmentPercents(segments: DocumentHeroSegment[]): number[];
8
- /** A complete payment uses the brand green; a partial one the "paid" green. */
9
- export declare function getProgressFillClassName(percent: number): string;
10
- /** Background tint for the status area (the side panel, or the whole card without one). */
11
- export declare function getStatusTintClassName(tone: DocumentHeroStatusTone): string;
12
- /** The panel beside the total only takes a colour when the status has one. */
13
- export declare function getAsidePanelClassName(tone: DocumentHeroStatusTone): string;
14
11
  /** No value to show: blank, or the "—" placeholder apps pass. */
15
- export declare function isEmptyMetaValue(value: unknown): boolean;
16
- export declare function getProgressTrackClassName(tone: DocumentHeroStatusTone): string;
17
- /** Up to four meta cells per row from `md`, two on phones. */
18
- export declare function getMetaColumns(count: number): number;
19
- export declare function getMetaGridClassName(count: number): string;
20
- /** Hairlines by position, so they're right whether two or `cols` cells share a row. */
21
- export declare function getMetaCellClassName(index: number, count: number): string;
12
+ export declare function isEmptyFactValue(value: unknown): boolean;
22
13
  //# sourceMappingURL=DocumentHero.utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DocumentHero.utils.d.ts","sourceRoot":"","sources":["../../../../src/components/molecules/DocumentHero/DocumentHero.utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACnB,uBAAuB,EACvB,sBAAsB,EACtB,gBAAgB,EACjB,MAAM,sBAAsB,CAAC;AAE9B,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGlD;AAQD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,gBAAgB,GAAG,MAAM,CAElE;AAQD,wBAAgB,eAAe,CAAC,IAAI,EAAE,mBAAmB,GAAG,MAAM,CAEjE;AAUD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,uBAAuB,GAAG,MAAM,CAEzE;AAED,iGAAiG;AACjG,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,mBAAmB,EAAE,GAAG,MAAM,EAAE,CAI5E;AAED,+EAA+E;AAC/E,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEhE;AAYD,2FAA2F;AAC3F,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,sBAAsB,GAAG,MAAM,CAE3E;AAED,8EAA8E;AAC9E,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,sBAAsB,GAAG,MAAM,CAE3E;AAED,iEAAiE;AACjE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAExD;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,sBAAsB,GAAG,MAAM,CAE9E;AAED,8DAA8D;AAC9D,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEpD;AASD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,uFAAuF;AACvF,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAWzE"}
1
+ {"version":3,"file":"DocumentHero.utils.d.ts","sourceRoot":"","sources":["../../../../src/components/molecules/DocumentHero/DocumentHero.utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,oBAAoB,EACpB,mBAAmB,EACnB,uBAAuB,EACvB,gBAAgB,EACjB,MAAM,sBAAsB,CAAC;AAE9B,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGlD;AAWD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,gBAAgB,GAAG,MAAM,CAEhE;AAYD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,gBAAgB,GAAG,MAAM,CAErE;AAWD,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,gBAAgB,GAAG,MAAM,CAExE;AASD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,oBAAoB,GAAG,MAAM,CAEvE;AASD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,oBAAoB,GAAG,MAAM,CAEvE;AAWD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,uBAAuB,GAAG,MAAM,CAEzE;AAED,iGAAiG;AACjG,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,mBAAmB,EAAE,GAAG,MAAM,EAAE,CAM5E;AAED,iEAAiE;AACjE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAKxD"}
@@ -1,3 +1,3 @@
1
1
  export { DocumentHero } from './DocumentHero';
2
- export type { DocumentHeroBar, DocumentHeroBarTone, DocumentHeroBreakdown, DocumentHeroMeta, DocumentHeroPayment, DocumentHeroProps, DocumentHeroSegment, DocumentHeroSegmentTone, DocumentHeroStatusTone, DocumentHeroTone, } from './DocumentHero';
2
+ export type { DocumentHeroBreakdown, DocumentHeroDetail, DocumentHeroFact, DocumentHeroFactTone, DocumentHeroProgress, DocumentHeroProps, DocumentHeroSegment, DocumentHeroSegmentTone, DocumentHeroTone, } from './DocumentHero';
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/molecules/DocumentHero/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,YAAY,EACV,eAAe,EACf,mBAAmB,EACnB,qBAAqB,EACrB,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACnB,uBAAuB,EACvB,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/molecules/DocumentHero/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,YAAY,EACV,qBAAqB,EACrB,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,EACpB,iBAAiB,EACjB,mBAAmB,EACnB,uBAAuB,EACvB,gBAAgB,GACjB,MAAM,gBAAgB,CAAC"}
@@ -31,7 +31,7 @@ export declare function DetailPageSkeleton({ sections, }: {
31
31
  sections?: number;
32
32
  }): ReactElement;
33
33
  export interface DocumentDetailSkeletonProps {
34
- /** Right half of the hero: paid/outstanding progress, quantity bars, or none. */
34
+ /** Bar under the hero amount: a payment/progress bar, quantity bars, or none. */
35
35
  aside?: 'payment' | 'bars' | 'none';
36
36
  /** Section cards below the hero (customer, items, notes…). */
37
37
  sections?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"Skeletons.d.ts","sourceRoot":"","sources":["../../../../src/components/molecules/Skeletons/Skeletons.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAI1C,oDAAoD;AACpD,wBAAgB,aAAa,IAAI,YAAY,CAO5C;AAED,MAAM,WAAW,4BAA4B;IAC3C,gDAAgD;IAChD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6BAA6B;IAC7B,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IAChB,6DAA6D;IAC7D,MAAM,CAAC,EAAE,KAAK,GAAG,SAAS,GAAG,MAAM,CAAC;IACpC,iDAAiD;IACjD,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,EACtC,MAAU,EACV,OAAW,EACX,MAAc,EACd,WAAkB,GACnB,EAAE,4BAA4B,GAAG,YAAY,CAwC7C;AAED,iFAAiF;AACjF,wBAAgB,aAAa,CAAC,EAAE,IAAQ,EAAE,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,YAAY,CAa3E;AAED,2GAA2G;AAC3G,wBAAgB,iBAAiB,CAAC,EAAE,IAAS,EAAE,SAAS,EAAE,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,YAAY,CAS/G;AAED,qFAAqF;AACrF,wBAAgB,kBAAkB,CAAC,EACjC,QAAY,GACb,EAAE;IACD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,YAAY,CAkCf;AAED,MAAM,WAAW,2BAA2B;IAC1C,iFAAiF;IACjF,KAAK,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;IACpC,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iDAAiD;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,sGAAsG;AACtG,wBAAgB,sBAAsB,CAAC,EACrC,KAAiB,EACjB,QAAY,EACZ,KAA0B,GAC3B,EAAE,2BAA2B,GAAG,YAAY,CAoF5C"}
1
+ {"version":3,"file":"Skeletons.d.ts","sourceRoot":"","sources":["../../../../src/components/molecules/Skeletons/Skeletons.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAI1C,oDAAoD;AACpD,wBAAgB,aAAa,IAAI,YAAY,CAO5C;AAED,MAAM,WAAW,4BAA4B;IAC3C,gDAAgD;IAChD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6BAA6B;IAC7B,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IAChB,6DAA6D;IAC7D,MAAM,CAAC,EAAE,KAAK,GAAG,SAAS,GAAG,MAAM,CAAC;IACpC,iDAAiD;IACjD,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,EACtC,MAAU,EACV,OAAW,EACX,MAAc,EACd,WAAkB,GACnB,EAAE,4BAA4B,GAAG,YAAY,CAwC7C;AAED,iFAAiF;AACjF,wBAAgB,aAAa,CAAC,EAAE,IAAQ,EAAE,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,YAAY,CAa3E;AAED,2GAA2G;AAC3G,wBAAgB,iBAAiB,CAAC,EAAE,IAAS,EAAE,SAAS,EAAE,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,YAAY,CAS/G;AAED,qFAAqF;AACrF,wBAAgB,kBAAkB,CAAC,EACjC,QAAY,GACb,EAAE;IACD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,YAAY,CAkCf;AAED,MAAM,WAAW,2BAA2B;IAC1C,iFAAiF;IACjF,KAAK,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;IACpC,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iDAAiD;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,sGAAsG;AACtG,wBAAgB,sBAAsB,CAAC,EACrC,KAAiB,EACjB,QAAY,EACZ,KAA0B,GAC3B,EAAE,2BAA2B,GAAG,YAAY,CA8D5C"}
package/dist/index.cjs.js CHANGED
@@ -15473,7 +15473,7 @@ const CollapsibleCard = ({ title, subtitle, icon, headerActions, defaultOpen = t
15473
15473
 
15474
15474
  /** A titled card on a document detail page: payments, customer, items, notes… */
15475
15475
  function DetailSection({ icon, title, count, actions, children, className, bodyClassName, }) {
15476
- return (jsxRuntime.jsxs("section", { className: cn('overflow-hidden rounded-2xl border border-border bg-card', className), children: [jsxRuntime.jsxs("header", { className: "flex flex-wrap items-center gap-2.5 border-b border-border px-4 py-3", children: [jsxRuntime.jsx("span", { "aria-hidden": true, className: "flex size-7 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary dark:bg-primary/20 [&_svg]:size-4", children: icon }), jsxRuntime.jsx("h3", { className: "m-0 text-base font-semibold text-foreground", children: title }), typeof count === 'string' || typeof count === 'number' ? (jsxRuntime.jsx(Badge, { appearance: "soft", color: "secondary", shape: "pill", size: "sm", children: count })) : (count), actions ? jsxRuntime.jsx("div", { className: "ml-auto flex flex-wrap items-center gap-2.5", children: actions }) : null] }), children != null ? jsxRuntime.jsx("div", { className: bodyClassName, children: children }) : null] }));
15476
+ return (jsxRuntime.jsxs("section", { className: cn('overflow-hidden rounded-2xl border border-border bg-card', className), children: [jsxRuntime.jsxs("header", { className: "flex flex-wrap items-center gap-2.5 border-b border-border bg-section-header px-4 py-3", children: [jsxRuntime.jsx("span", { "aria-hidden": true, className: "flex size-7 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary dark:bg-primary/20 [&_svg]:size-4", children: icon }), jsxRuntime.jsx("h3", { className: "m-0 text-base font-semibold text-foreground", children: title }), typeof count === 'string' || typeof count === 'number' ? (jsxRuntime.jsx(Badge, { appearance: "soft", color: "secondary", shape: "pill", size: "sm", children: count })) : (count), actions ? jsxRuntime.jsx("div", { className: "ml-auto flex flex-wrap items-center gap-2.5", children: actions }) : null] }), children != null ? jsxRuntime.jsx("div", { className: bodyClassName, children: children }) : null] }));
15477
15477
  }
15478
15478
 
15479
15479
  const HEADER_TONE_CLASSES = {
@@ -37242,26 +37242,63 @@ function clampPercent$1(value) {
37242
37242
  return 0;
37243
37243
  return Math.min(100, Math.max(0, value));
37244
37244
  }
37245
- const CAPTION_TONE = {
37246
- default: 'text-muted-foreground',
37245
+ const LABEL_TONE = {
37246
+ default: 'text-secondary-foreground',
37247
37247
  success: 'text-amount-paid',
37248
+ info: 'text-info',
37249
+ warning: 'text-badge-amber-text',
37248
37250
  destructive: 'text-amount-outstanding',
37251
+ muted: 'text-secondary-foreground',
37249
37252
  };
37250
- function getCaptionClassName(tone) {
37251
- return CAPTION_TONE[tone];
37253
+ function getLabelClassName(tone) {
37254
+ return LABEL_TONE[tone];
37252
37255
  }
37253
- const BAR_TONE = {
37254
- primary: 'bg-primary',
37255
- success: 'bg-success',
37256
- info: 'bg-info',
37256
+ /** The lightest wash of the status colour, matching the document's status pill. */
37257
+ const PANEL_TONE = {
37258
+ default: 'bg-muted/40',
37259
+ success: 'bg-primary/5 dark:bg-primary/10',
37260
+ info: 'bg-info/5 dark:bg-info/10',
37261
+ warning: 'bg-warning/5 dark:bg-warning/10',
37262
+ destructive: 'bg-destructive/5 dark:bg-destructive/10',
37263
+ muted: 'bg-muted/40',
37257
37264
  };
37258
- function getBarClassName(tone) {
37259
- return BAR_TONE[tone];
37265
+ function getFactsPanelClassName(tone) {
37266
+ return PANEL_TONE[tone];
37267
+ }
37268
+ const TRACK_TONE = {
37269
+ default: 'bg-progress-track',
37270
+ success: 'bg-progress-track',
37271
+ info: 'bg-info/15',
37272
+ warning: 'bg-warning/15',
37273
+ destructive: 'bg-destructive/15',
37274
+ muted: 'bg-progress-track',
37275
+ };
37276
+ function getProgressTrackClassName(tone) {
37277
+ return TRACK_TONE[tone];
37278
+ }
37279
+ const FACT_ICON_TONE = {
37280
+ default: 'bg-muted text-muted-foreground',
37281
+ success: 'bg-badge-green-bg text-amount-paid',
37282
+ warning: 'bg-badge-amber-bg text-badge-amber-text',
37283
+ destructive: 'bg-badge-destructive-bg text-amount-outstanding',
37284
+ };
37285
+ function getFactIconClassName(tone) {
37286
+ return FACT_ICON_TONE[tone];
37287
+ }
37288
+ const FACT_NOTE_TONE = {
37289
+ default: 'text-muted-foreground',
37290
+ success: 'text-amount-paid',
37291
+ warning: 'text-badge-amber-text',
37292
+ destructive: 'text-amount-outstanding',
37293
+ };
37294
+ function getFactNoteClassName(tone) {
37295
+ return FACT_NOTE_TONE[tone];
37260
37296
  }
37261
37297
  const SEGMENT_TONE = {
37262
37298
  success: 'bg-success',
37263
37299
  info: 'bg-info',
37264
37300
  primary: 'bg-primary',
37301
+ 'primary-soft': 'bg-primary/40',
37265
37302
  warning: 'bg-warning',
37266
37303
  remaining: 'bg-progress-track',
37267
37304
  };
@@ -37270,82 +37307,47 @@ function getSegmentClassName$1(tone) {
37270
37307
  }
37271
37308
  /** Each segment's width in percent of the segments' sum; all 0 when there's nothing to split. */
37272
37309
  function getSegmentPercents(segments) {
37273
- const amounts = segments.map((segment) => (Number.isFinite(segment.amount) ? Math.max(0, segment.amount) : 0));
37310
+ const amounts = segments.map((segment) => Number.isFinite(segment.amount) ? Math.max(0, segment.amount) : 0);
37274
37311
  const whole = amounts.reduce((sum, amount) => sum + amount, 0);
37275
37312
  return amounts.map((amount) => (whole > 0 ? (amount / whole) * 100 : 0));
37276
37313
  }
37277
- /** A complete payment uses the brand green; a partial one the "paid" green. */
37278
- function getProgressFillClassName(percent) {
37279
- return percent >= 100 ? 'bg-primary' : 'bg-amount-paid';
37280
- }
37281
- /** The lightest wash of the status colour, so the panel reads like the header pill without shouting. */
37282
- const STATUS_TINT = {
37283
- neutral: '',
37284
- success: 'bg-success/5 dark:bg-success/10',
37285
- info: 'bg-info/5 dark:bg-info/10',
37286
- warning: 'bg-warning/5 dark:bg-warning/10',
37287
- destructive: 'bg-destructive/5 dark:bg-destructive/10',
37288
- muted: 'bg-muted/40',
37289
- };
37290
- /** Background tint for the status area (the side panel, or the whole card without one). */
37291
- function getStatusTintClassName(tone) {
37292
- return STATUS_TINT[tone];
37293
- }
37294
- /** The panel beside the total only takes a colour when the status has one. */
37295
- function getAsidePanelClassName(tone) {
37296
- return STATUS_TINT[tone];
37297
- }
37298
37314
  /** No value to show: blank, or the "—" placeholder apps pass. */
37299
- function isEmptyMetaValue(value) {
37300
- return value == null || (typeof value === 'string' && (value.trim() === '' || value.trim() === '—'));
37301
- }
37302
- function getProgressTrackClassName(tone) {
37303
- return tone === 'destructive' ? 'bg-destructive/15' : 'bg-progress-track';
37304
- }
37305
- /** Up to four meta cells per row from `md`, two on phones. */
37306
- function getMetaColumns(count) {
37307
- return Math.min(4, Math.max(1, count));
37308
- }
37309
- const MD_COLS = {
37310
- 1: 'md:grid-cols-1',
37311
- 2: 'md:grid-cols-2',
37312
- 3: 'md:grid-cols-3',
37313
- 4: 'md:grid-cols-4',
37314
- };
37315
- function getMetaGridClassName(count) {
37316
- return `grid grid-cols-2 ${MD_COLS[getMetaColumns(count)]}`;
37317
- }
37318
- /** Hairlines by position, so they're right whether two or `cols` cells share a row. */
37319
- function getMetaCellClassName(index, count) {
37320
- const cols = getMetaColumns(count);
37321
- return [
37322
- 'min-w-0 border-border px-5 py-3',
37323
- index % 2 === 1 ? 'border-l' : '',
37324
- index >= 2 ? 'border-t' : '',
37325
- index % cols === 0 ? 'md:border-l-0' : 'md:border-l',
37326
- index >= cols ? 'md:border-t' : 'md:border-t-0',
37327
- ]
37328
- .filter(Boolean)
37329
- .join(' ');
37315
+ function isEmptyFactValue(value) {
37316
+ return (value == null ||
37317
+ (typeof value === 'string' && (value.trim() === '' || value.trim() === '—')));
37330
37318
  }
37331
37319
 
37332
- function BreakdownPanel({ breakdown }) {
37320
+ function ProgressBar({ progress, tone, name, }) {
37321
+ const percent = clampPercent$1(progress.percent);
37322
+ return (jsxRuntime.jsxs("div", { className: "mt-4 w-full max-w-xl", children: [jsxRuntime.jsx("div", { role: "progressbar", "aria-label": name, "aria-valuemin": 0, "aria-valuemax": 100, "aria-valuenow": percent, className: cn('h-2 overflow-hidden rounded-full', getProgressTrackClassName(tone)), children: jsxRuntime.jsx("div", { className: "h-full rounded-full bg-primary", style: { width: `${percent}%` } }) }), progress.value != null ||
37323
+ progress.label != null ||
37324
+ progress.trailing != null ? (jsxRuntime.jsxs("div", { className: "mt-2 flex items-center justify-between gap-3 text-xs", children: [jsxRuntime.jsxs("span", { className: "text-secondary-foreground", children: [progress.value != null ? (jsxRuntime.jsx("span", { className: "font-semibold tabular-nums text-amount-paid", children: progress.value })) : null, progress.value != null && progress.label != null ? ' ' : null, progress.label] }), progress.trailing != null ? (jsxRuntime.jsx("span", { className: "text-right tabular-nums text-secondary-foreground", children: progress.trailing })) : null] })) : null] }));
37325
+ }
37326
+ function BreakdownBar({ breakdown, }) {
37333
37327
  const percents = getSegmentPercents(breakdown.segments);
37334
- return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("dl", { className: "m-0 grid grid-flow-col auto-cols-fr gap-4", children: breakdown.segments.map((segment) => (jsxRuntime.jsxs("div", { className: "min-w-0", children: [jsxRuntime.jsxs("dt", { className: "flex items-center gap-1.5 text-xs text-label-subtle", children: [jsxRuntime.jsx("span", { "aria-hidden": true, className: cn('size-2 shrink-0 rounded-full', getSegmentClassName$1(segment.tone)) }), segment.label] }), jsxRuntime.jsx("dd", { className: "m-0 text-lg font-semibold tabular-nums text-foreground", children: segment.value })] }, segment.label))) }), jsxRuntime.jsx("div", { role: "img", "aria-label": `${breakdown.label}: ${breakdown.segments
37328
+ return (jsxRuntime.jsxs("div", { className: "mt-4 w-full max-w-xl", children: [jsxRuntime.jsx("dl", { className: "m-0 grid grid-flow-col auto-cols-fr gap-4", children: breakdown.segments.map((segment) => (jsxRuntime.jsxs("div", { className: "min-w-0", children: [jsxRuntime.jsxs("dt", { className: "flex items-center gap-1.5 text-xs text-muted-foreground", children: [jsxRuntime.jsx("span", { "aria-hidden": true, className: cn('h-1.5 w-3 shrink-0 rounded-full', getSegmentClassName$1(segment.tone), segment.tone === 'remaining' &&
37329
+ 'ring-1 ring-inset ring-border') }), segment.label] }), jsxRuntime.jsx("dd", { className: "m-0 text-base font-semibold tabular-nums text-foreground", children: segment.value })] }, segment.label))) }), jsxRuntime.jsx("div", { role: "img", "aria-label": `${breakdown.label}: ${breakdown.segments
37335
37330
  .map((segment, index) => `${segment.label} ${Math.round(percents[index])}%`)
37336
- .join(', ')}`, className: "mb-2 mt-3 flex h-2 overflow-hidden rounded-full bg-progress-track", children: breakdown.segments.map((segment, index) => segment.tone === 'remaining' || percents[index] === 0 ? null : (jsxRuntime.jsx("div", { className: cn('h-full', getSegmentClassName$1(segment.tone)), style: { width: `${percents[index]}%` } }, segment.label))) }), breakdown.caption ? jsxRuntime.jsx("p", { className: "m-0 text-xs text-muted-foreground", children: breakdown.caption }) : null] }));
37331
+ .join(', ')}`, className: "mt-3 flex h-2 overflow-hidden rounded-full bg-progress-track", children: breakdown.segments.map((segment, index) => segment.tone === 'remaining' || percents[index] === 0 ? null : (jsxRuntime.jsx("div", { className: cn('h-full', getSegmentClassName$1(segment.tone)), style: { width: `${percents[index]}%` } }, segment.label))) }), breakdown.caption ? (jsxRuntime.jsx("p", { className: "m-0 mt-2 text-xs text-secondary-foreground", children: breakdown.caption })) : null] }));
37332
+ }
37333
+ function FactRow({ fact }) {
37334
+ const tone = fact.tone ?? 'default';
37335
+ const empty = isEmptyFactValue(fact.value);
37336
+ return (jsxRuntime.jsxs("div", { className: "flex min-h-10 items-center gap-3 border-b border-border py-1.5 last:border-b-0", children: [jsxRuntime.jsx("span", { "aria-hidden": true, className: cn('flex size-6 shrink-0 items-center justify-center rounded-md text-xs font-semibold [&_svg]:size-3.5', getFactIconClassName(tone)), children: fact.icon }), jsxRuntime.jsx("dt", { className: "min-w-0 flex-1 text-sm text-secondary-foreground", children: fact.label }), jsxRuntime.jsxs("dd", { className: "m-0 flex min-w-0 flex-wrap items-baseline justify-end gap-x-2 text-right", children: [empty ? (jsxRuntime.jsx("span", { className: "text-sm font-medium text-muted-foreground", children: fact.emptyLabel ?? 'Not provided' })) : (jsxRuntime.jsx("span", { className: cn('break-words text-sm font-semibold tabular-nums', tone === 'success' ? 'text-amount-paid' : 'text-foreground'), children: fact.value })), fact.note ? (jsxRuntime.jsx("span", { className: cn('text-xs font-medium', getFactNoteClassName(tone)), children: fact.note })) : null, fact.onAction ? (jsxRuntime.jsx("button", { type: "button", onClick: fact.onAction, className: "text-xs font-medium text-primary underline-offset-2 hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: fact.actionLabel ?? 'View' })) : null] })] }));
37337
37337
  }
37338
37338
  /**
37339
- * The top of a document detail page: its total, how much of it is settled
37340
- * (paid, or carats returned/sold) and its key dates. Data-only.
37339
+ * The top of a document detail page: the headline amount (balance, total, value),
37340
+ * how much of it is settled, and the key dates and facts beside it. Data-only.
37341
37341
  */
37342
- function DocumentHero({ label, total, caption, captionTone = 'default', payment, bars, breakdown, meta = [], statusTone = 'neutral', className, }) {
37343
- const hasAside = !!payment || !!breakdown || (bars?.length ?? 0) > 0;
37344
- const percent = payment ? clampPercent$1(payment.percent) : 0;
37345
- return (jsxRuntime.jsxs("section", { className: cn('overflow-hidden rounded-2xl border border-border bg-card', className), children: [jsxRuntime.jsxs("div", { className: cn('grid grid-cols-1', hasAside ? 'md:grid-cols-[1fr_1.25fr]' : getStatusTintClassName(statusTone)), children: [jsxRuntime.jsxs("div", { className: "min-w-0 px-5 py-4", children: [jsxRuntime.jsx("p", { className: "m-0 text-xs text-label-subtle", children: label }), jsxRuntime.jsx("p", { className: "m-0 mt-1 break-words text-4xl font-semibold leading-none tracking-tight tabular-nums text-foreground", children: total }), caption ? jsxRuntime.jsx("p", { className: cn('m-0 mt-2 text-xs', getCaptionClassName(captionTone)), children: caption }) : null] }), payment ? (jsxRuntime.jsxs("div", { className: cn('min-w-0 border-t border-border px-5 py-4 md:border-l md:border-t-0', getAsidePanelClassName(statusTone)), children: [jsxRuntime.jsxs("div", { className: "flex items-baseline justify-between gap-4", children: [jsxRuntime.jsxs("div", { className: "min-w-0", children: [jsxRuntime.jsx("span", { className: "text-xs text-label-subtle", children: payment.paidLabel ?? 'Amount paid' }), jsxRuntime.jsx("p", { className: "m-0 text-lg font-semibold tabular-nums text-amount-paid", children: payment.paid })] }), jsxRuntime.jsxs("div", { className: "min-w-0 text-right", children: [jsxRuntime.jsx("span", { className: "text-xs text-label-subtle", children: payment.outstandingLabel ?? 'Outstanding' }), jsxRuntime.jsx("p", { className: "m-0 text-lg font-semibold tabular-nums text-amount-outstanding", children: payment.outstanding })] })] }), jsxRuntime.jsx("div", { role: "progressbar", "aria-label": payment.paidLabel ?? 'Amount paid', "aria-valuemin": 0, "aria-valuemax": 100, "aria-valuenow": percent, className: cn('mb-2 mt-3 h-2 overflow-hidden rounded-full', getProgressTrackClassName(statusTone)), children: jsxRuntime.jsx("div", { className: cn('h-full rounded-full', getProgressFillClassName(percent)), style: { width: `${percent}%` } }) }), payment.caption ? jsxRuntime.jsx("p", { className: "m-0 text-xs text-muted-foreground", children: payment.caption }) : null] })) : breakdown ? (jsxRuntime.jsx("div", { className: cn('min-w-0 border-t border-border px-5 py-4 md:border-l md:border-t-0', getAsidePanelClassName(statusTone)), children: jsxRuntime.jsx(BreakdownPanel, { breakdown: breakdown }) })) : bars && bars.length > 0 ? (jsxRuntime.jsx("div", { className: cn('flex min-w-0 flex-col gap-3 border-t border-border px-5 py-4 md:border-l md:border-t-0', getAsidePanelClassName(statusTone)), children: bars.map((bar) => {
37346
- const barPercent = clampPercent$1(bar.percent);
37347
- return (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsxs("div", { className: "mb-1 flex justify-between gap-3 text-xs", children: [jsxRuntime.jsx("span", { className: "text-muted-foreground", children: bar.label }), jsxRuntime.jsx("span", { className: "font-medium tabular-nums text-foreground", children: bar.value })] }), jsxRuntime.jsx("div", { role: "progressbar", "aria-label": bar.label, "aria-valuemin": 0, "aria-valuemax": 100, "aria-valuenow": barPercent, className: "h-2 overflow-hidden rounded-full bg-muted", children: jsxRuntime.jsx("div", { className: cn('h-full rounded-full', getBarClassName(bar.tone ?? 'primary')), style: { width: `${barPercent}%` } }) })] }, bar.label));
37348
- }) })) : null] }), meta.length > 0 ? (jsxRuntime.jsx("dl", { className: cn('m-0 border-t border-border', getMetaGridClassName(meta.length)), children: meta.map((item, index) => (jsxRuntime.jsxs("div", { className: getMetaCellClassName(index, meta.length), children: [jsxRuntime.jsx("dt", { className: cn('text-xs font-semibold uppercase tracking-wider', item.danger ? 'text-amount-outstanding' : 'text-label-subtle'), children: item.label }), isEmptyMetaValue(item.value) ? (jsxRuntime.jsx("dd", { className: "m-0 mt-1 text-sm italic text-muted-foreground", children: item.emptyLabel ?? 'Not provided' })) : (jsxRuntime.jsx("dd", { className: cn('m-0 mt-1 break-words text-sm font-medium', item.danger ? 'text-amount-outstanding' : 'text-foreground'), children: item.value }))] }, item.label))) })) : null] }));
37342
+ function DocumentHero({ label, labelIcon, tone = 'default', amount, amountNote, progress, breakdown, facts = [], details = [], detailsLabel, detailsIcon, className, }) {
37343
+ return (jsxRuntime.jsxs("section", { className: cn('overflow-hidden rounded-2xl border border-border bg-card', className), children: [jsxRuntime.jsxs("div", { className: cn('grid grid-cols-1', facts.length > 0 && 'md:grid-cols-[minmax(0,1.4fr)_minmax(0,1fr)]'), children: [jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-col justify-center px-5 py-4 sm:px-7 sm:py-4", children: [jsxRuntime.jsxs("p", { className: cn('m-0 flex items-center gap-1.5 text-xs font-semibold uppercase tracking-wider [&_svg]:size-3.5', getLabelClassName(tone)), children: [labelIcon, label] }), jsxRuntime.jsxs("div", { className: "mt-1.5 flex flex-wrap items-baseline gap-x-3 gap-y-1", children: [jsxRuntime.jsx("span", { className: "break-all text-4xl font-semibold leading-none tracking-tight tabular-nums text-foreground sm:text-[2.75rem]", children: amount }), amountNote ? (jsxRuntime.jsx("span", { className: "text-sm text-secondary-foreground", children: amountNote })) : null] }), breakdown ? (jsxRuntime.jsx(BreakdownBar, { breakdown: breakdown })) : progress ? (jsxRuntime.jsx(ProgressBar, { progress: progress, tone: tone, name: label })) : null] }), facts.length > 0 ? (jsxRuntime.jsx("dl", { className: cn('m-0 flex min-w-0 flex-col justify-center border-t border-border px-5 py-2 md:border-l md:border-t-0', getFactsPanelClassName(tone)), children: facts.map((fact) => (jsxRuntime.jsx(FactRow, { fact: fact }, fact.label))) })) : null] }), details.length > 0 ? (jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-x-3 gap-y-1.5 border-t border-border px-5 py-2.5 text-xs sm:px-7", children: [detailsLabel ? (jsxRuntime.jsxs("span", { className: "inline-flex shrink-0 items-center gap-1 rounded bg-muted px-1.5 py-0.5 font-semibold text-secondary-foreground [&_svg]:size-3", children: [detailsIcon, detailsLabel] })) : null, jsxRuntime.jsx("dl", { className: "m-0 flex min-w-0 flex-wrap items-center gap-x-3 gap-y-1.5", children: details.map((detail, index) => {
37344
+ const empty = isEmptyFactValue(detail.value);
37345
+ return (jsxRuntime.jsxs("div", { className: "flex min-w-0 items-center gap-x-3", children: [index > 0 ? (jsxRuntime.jsx("span", { "aria-hidden": true, className: "h-3 w-px shrink-0 bg-border" })) : null, jsxRuntime.jsxs("div", { className: "flex min-w-0 items-baseline gap-1.5", children: [jsxRuntime.jsx("dt", { className: "whitespace-nowrap text-muted-foreground", children: detail.label }), jsxRuntime.jsx("dd", { className: cn('m-0 break-words', empty
37346
+ ? 'italic text-label-subtle'
37347
+ : 'font-medium text-foreground'), children: empty
37348
+ ? (detail.emptyLabel ?? 'Not provided')
37349
+ : detail.value })] })] }, detail.label));
37350
+ }) })] })) : null] }));
37349
37351
  }
37350
37352
 
37351
37353
  const DropdownMenu = DropdownMenuPrimitive__namespace.Root;
@@ -67516,7 +67518,7 @@ function DetailPageSkeleton({ sections = 3, }) {
67516
67518
  }
67517
67519
  /** Document detail page (invoice, memo…): header, `DocumentHero` and `DetailSection` placeholders. */
67518
67520
  function DocumentDetailSkeleton({ aside = 'payment', sections = 3, label = 'Loading document', }) {
67519
- return (jsxRuntime.jsxs("div", { role: "status", "aria-busy": "true", "aria-label": label, className: "space-y-4", children: [jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3", children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [jsxRuntime.jsx(SquareSkeleton, { height: 14, width: 80, rounded: "full" }), jsxRuntime.jsx("span", { className: "h-5 w-px bg-border" }), jsxRuntime.jsx(SquareSkeleton, { height: 28, width: 200, rounded: "md" }), jsxRuntime.jsx(SquareSkeleton, { height: 22, width: 72, rounded: "full" })] }), jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsx(SquareSkeleton, { height: 36, width: 112, rounded: "lg" }), jsxRuntime.jsx(SquareSkeleton, { height: 36, width: 80, rounded: "lg" }), jsxRuntime.jsx(SquareSkeleton, { height: 36, width: 128, rounded: "lg" }), jsxRuntime.jsx(SquareSkeleton, { height: 36, width: 36, rounded: "lg" })] })] }), jsxRuntime.jsxs("section", { "aria-hidden": "true", className: "overflow-hidden rounded-2xl border border-border bg-card", children: [jsxRuntime.jsxs("div", { className: cn('grid grid-cols-1', aside !== 'none' && 'md:grid-cols-[1fr_1.25fr]'), children: [jsxRuntime.jsxs("div", { className: "space-y-3 px-5 py-4", children: [jsxRuntime.jsx(SquareSkeleton, { height: 12, width: 96, rounded: "full" }), jsxRuntime.jsx(SquareSkeleton, { height: 36, width: 180, rounded: "md" }), jsxRuntime.jsx(SquareSkeleton, { height: 12, width: 200, rounded: "full" })] }), aside === 'payment' && (jsxRuntime.jsxs("div", { className: "space-y-3 border-t border-border px-5 py-4 md:border-l md:border-t-0", children: [jsxRuntime.jsxs("div", { className: "flex justify-between gap-4", children: [jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [jsxRuntime.jsx(SquareSkeleton, { height: 11, width: 80, rounded: "full" }), jsxRuntime.jsx(SquareSkeleton, { height: 20, width: 104, rounded: "md" })] }), jsxRuntime.jsxs("div", { className: "flex flex-col items-end space-y-1.5", children: [jsxRuntime.jsx(SquareSkeleton, { height: 11, width: 80, rounded: "full" }), jsxRuntime.jsx(SquareSkeleton, { height: 20, width: 104, rounded: "md" })] })] }), jsxRuntime.jsx(SquareSkeleton, { height: 8, className: "w-full", rounded: "full" }), jsxRuntime.jsx(SquareSkeleton, { height: 11, width: 160, rounded: "full" })] })), aside === 'bars' && (jsxRuntime.jsx("div", { className: "space-y-3 border-t border-border px-5 py-4 md:border-l md:border-t-0", children: [0, 1, 2].map((i) => (jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [jsxRuntime.jsxs("div", { className: "flex justify-between", children: [jsxRuntime.jsx(SquareSkeleton, { height: 11, width: 96, rounded: "full" }), jsxRuntime.jsx(SquareSkeleton, { height: 11, width: 56, rounded: "full" })] }), jsxRuntime.jsx(SquareSkeleton, { height: 8, className: "w-full", rounded: "full" })] }, i))) }))] }), jsxRuntime.jsx("div", { className: "grid grid-cols-2 border-t border-border md:grid-cols-4", children: [0, 1, 2, 3].map((i) => (jsxRuntime.jsxs("div", { className: "space-y-2 border-border px-5 py-3 even:border-l [&:nth-child(n+3)]:border-t md:border-l md:first:border-l-0 md:[&:nth-child(n+3)]:border-t-0", children: [jsxRuntime.jsx(SquareSkeleton, { height: 10, width: 56, rounded: "full" }), jsxRuntime.jsx(SquareSkeleton, { height: 14, width: 96, rounded: "full" })] }, i))) })] }), Array.from({ length: sections }).map((_, s) => (jsxRuntime.jsxs("section", { "aria-hidden": "true", className: "overflow-hidden rounded-2xl border border-border bg-card", children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-2.5 border-b border-border px-4 py-3", children: [jsxRuntime.jsx(SquareSkeleton, { height: 28, width: 28, rounded: "lg" }), jsxRuntime.jsx(SquareSkeleton, { height: 15, width: 128, rounded: "full" })] }), jsxRuntime.jsx("div", { className: "space-y-3 p-4", children: Array.from({ length: s === 1 ? 4 : 2 }).map((__, row) => (jsxRuntime.jsx(SquareSkeleton, { height: s === 1 ? 36 : 14, className: row % 2 ? 'w-3/4' : 'w-full', rounded: "md" }, row))) })] }, s))), jsxRuntime.jsx("span", { className: "sr-only", children: label })] }));
67521
+ return (jsxRuntime.jsxs("div", { role: "status", "aria-busy": "true", "aria-label": label, className: "space-y-4", children: [jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3", children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [jsxRuntime.jsx(SquareSkeleton, { height: 14, width: 80, rounded: "full" }), jsxRuntime.jsx("span", { className: "h-5 w-px bg-border" }), jsxRuntime.jsx(SquareSkeleton, { height: 28, width: 200, rounded: "md" }), jsxRuntime.jsx(SquareSkeleton, { height: 22, width: 72, rounded: "full" })] }), jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsx(SquareSkeleton, { height: 36, width: 112, rounded: "lg" }), jsxRuntime.jsx(SquareSkeleton, { height: 36, width: 80, rounded: "lg" }), jsxRuntime.jsx(SquareSkeleton, { height: 36, width: 128, rounded: "lg" }), jsxRuntime.jsx(SquareSkeleton, { height: 36, width: 36, rounded: "lg" })] })] }), jsxRuntime.jsxs("section", { "aria-hidden": "true", className: "grid grid-cols-1 overflow-hidden rounded-2xl border border-border bg-card md:grid-cols-[minmax(0,1.4fr)_minmax(0,1fr)]", children: [jsxRuntime.jsxs("div", { className: "flex flex-col justify-center space-y-3 px-5 py-4 sm:px-7 sm:py-4", children: [jsxRuntime.jsx(SquareSkeleton, { height: 12, width: 96, rounded: "full" }), jsxRuntime.jsx(SquareSkeleton, { height: 40, width: 220, rounded: "md" }), aside !== 'none' && (jsxRuntime.jsxs("div", { className: "w-full max-w-xl space-y-2 pt-1", children: [jsxRuntime.jsx(SquareSkeleton, { height: 8, className: "w-full", rounded: "full" }), jsxRuntime.jsxs("div", { className: "flex justify-between", children: [jsxRuntime.jsx(SquareSkeleton, { height: 11, width: 88, rounded: "full" }), jsxRuntime.jsx(SquareSkeleton, { height: 11, width: 40, rounded: "full" })] })] }))] }), jsxRuntime.jsx("div", { className: "border-t border-border bg-muted/40 px-5 py-2 md:border-l md:border-t-0", children: [0, 1, 2, 3].map((i) => (jsxRuntime.jsxs("div", { className: "flex min-h-10 items-center gap-3 border-b border-border py-1.5 last:border-b-0", children: [jsxRuntime.jsx(SquareSkeleton, { height: 24, width: 24, rounded: "md" }), jsxRuntime.jsx(SquareSkeleton, { height: 12, width: 72, rounded: "full" }), jsxRuntime.jsx(SquareSkeleton, { height: 12, width: 88, rounded: "full", className: "ml-auto" })] }, i))) })] }), Array.from({ length: sections }).map((_, s) => (jsxRuntime.jsxs("section", { "aria-hidden": "true", className: "overflow-hidden rounded-2xl border border-border bg-card", children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-2.5 border-b border-border px-4 py-3", children: [jsxRuntime.jsx(SquareSkeleton, { height: 28, width: 28, rounded: "lg" }), jsxRuntime.jsx(SquareSkeleton, { height: 15, width: 128, rounded: "full" })] }), jsxRuntime.jsx("div", { className: "space-y-3 p-4", children: Array.from({ length: s === 1 ? 4 : 2 }).map((__, row) => (jsxRuntime.jsx(SquareSkeleton, { height: s === 1 ? 36 : 14, className: row % 2 ? 'w-3/4' : 'w-full', rounded: "md" }, row))) })] }, s))), jsxRuntime.jsx("span", { className: "sr-only", children: label })] }));
67520
67522
  }
67521
67523
 
67522
67524
  const SlideOut = ({ open, onOpenChange, ...props }) => {