@veevarts/design-system 2.1.0-beta.6 → 2.1.0-beta.8

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.
Files changed (98) hide show
  1. package/dist/index.cjs +8 -8
  2. package/dist/index.js +6549 -5083
  3. package/dist/patterns/ActivityTimeline/ActivityTimeline.d.ts +3 -0
  4. package/dist/patterns/ActivityTimeline/index.d.ts +2 -0
  5. package/dist/patterns/ActivityTimeline/styles.d.ts +15 -0
  6. package/dist/patterns/ActivityTimeline/types.d.ts +15 -0
  7. package/dist/patterns/AdminTable/AdminTable.d.ts +1 -0
  8. package/dist/patterns/AdminTable/styles.d.ts +6 -0
  9. package/dist/patterns/AdminToolbar/AdminToolbar.d.ts +1 -0
  10. package/dist/patterns/AmountList/AmountList.d.ts +3 -0
  11. package/dist/patterns/AmountList/index.d.ts +2 -0
  12. package/dist/patterns/AmountList/styles.d.ts +23 -0
  13. package/dist/patterns/AmountList/types.d.ts +26 -0
  14. package/dist/patterns/CardList/CardList.d.ts +3 -0
  15. package/dist/patterns/CardList/index.d.ts +2 -0
  16. package/dist/patterns/CardList/styles.d.ts +16 -0
  17. package/dist/patterns/CardList/types.d.ts +19 -0
  18. package/dist/patterns/CardStack/CardStack.d.ts +7 -0
  19. package/dist/patterns/CardStack/index.d.ts +2 -0
  20. package/dist/patterns/CardStack/styles.d.ts +2 -0
  21. package/dist/patterns/CellText/CellText.d.ts +16 -0
  22. package/dist/patterns/CellText/index.d.ts +2 -0
  23. package/dist/patterns/CellText/styles.d.ts +7 -0
  24. package/dist/patterns/FilterSelect/FilterSelect.d.ts +3 -0
  25. package/dist/patterns/FilterSelect/index.d.ts +2 -0
  26. package/dist/patterns/FilterSelect/styles.d.ts +14 -0
  27. package/dist/patterns/FilterSelect/types.d.ts +13 -0
  28. package/dist/patterns/InstallmentSchedule/types.d.ts +29 -5
  29. package/dist/patterns/InstallmentSchedule/utils.d.ts +6 -0
  30. package/dist/patterns/KeyValueChip/KeyValueChip.d.ts +1 -0
  31. package/dist/patterns/KeyValueRows/KeyValueRows.d.ts +13 -0
  32. package/dist/patterns/KeyValueRows/index.d.ts +2 -0
  33. package/dist/patterns/KeyValueRows/styles.d.ts +8 -0
  34. package/dist/patterns/LineItemRows/LineItemRows.d.ts +17 -0
  35. package/dist/patterns/LineItemRows/index.d.ts +2 -0
  36. package/dist/patterns/LineItemRows/styles.d.ts +13 -0
  37. package/dist/patterns/ListPanel/ListPanel.d.ts +2 -0
  38. package/dist/patterns/LoadMoreFooter/LoadMoreFooter.d.ts +3 -0
  39. package/dist/patterns/LoadMoreFooter/index.d.ts +2 -0
  40. package/dist/patterns/LoadMoreFooter/styles.d.ts +7 -0
  41. package/dist/patterns/LoadMoreFooter/types.d.ts +10 -0
  42. package/dist/patterns/PageHeader/PageHeader.d.ts +1 -0
  43. package/dist/patterns/PaymentSubAmountInput/PaymentSubAmountInput.d.ts +2 -0
  44. package/dist/patterns/PillTabs/PillTabs.d.ts +3 -0
  45. package/dist/patterns/PillTabs/ids.d.ts +9 -0
  46. package/dist/patterns/PillTabs/index.d.ts +3 -0
  47. package/dist/patterns/PillTabs/styles.d.ts +10 -0
  48. package/dist/patterns/PillTabs/types.d.ts +13 -0
  49. package/dist/patterns/RecordCard/RecordCard.d.ts +3 -0
  50. package/dist/patterns/RecordCard/index.d.ts +2 -0
  51. package/dist/patterns/RecordCard/styles.d.ts +15 -0
  52. package/dist/patterns/RecordCard/types.d.ts +17 -0
  53. package/dist/patterns/RecordHeader/RecordHeader.d.ts +3 -0
  54. package/dist/patterns/RecordHeader/index.d.ts +2 -0
  55. package/dist/patterns/RecordHeader/styles.d.ts +43 -0
  56. package/dist/patterns/RecordHeader/types.d.ts +30 -0
  57. package/dist/patterns/RecordLayout/RecordLayout.d.ts +3 -0
  58. package/dist/patterns/RecordLayout/index.d.ts +2 -0
  59. package/dist/patterns/RecordLayout/styles.d.ts +8 -0
  60. package/dist/patterns/RecordLayout/types.d.ts +6 -0
  61. package/dist/patterns/RecordTotals/RecordTotals.d.ts +19 -0
  62. package/dist/patterns/RecordTotals/index.d.ts +2 -0
  63. package/dist/patterns/RecordTotals/styles.d.ts +19 -0
  64. package/dist/patterns/RelatedRecordList/RelatedRecordList.d.ts +3 -0
  65. package/dist/patterns/RelatedRecordList/index.d.ts +2 -0
  66. package/dist/patterns/RelatedRecordList/styles.d.ts +19 -0
  67. package/dist/patterns/RelatedRecordList/types.d.ts +17 -0
  68. package/dist/patterns/StatTiles/StatTiles.d.ts +3 -0
  69. package/dist/patterns/StatTiles/index.d.ts +2 -0
  70. package/dist/patterns/StatTiles/styles.d.ts +8 -0
  71. package/dist/patterns/StatTiles/types.d.ts +12 -0
  72. package/dist/patterns/StatusChip/StatusChip.d.ts +3 -3
  73. package/dist/patterns/Summary/components/GrandTotalRow.d.ts +1 -0
  74. package/dist/patterns/Summary/components/ItemRow.d.ts +1 -0
  75. package/dist/patterns/Summary/components/SummaryBody.d.ts +4 -1
  76. package/dist/patterns/Summary/components/TotalsLineRow.d.ts +3 -2
  77. package/dist/patterns/Summary/types.d.ts +31 -9
  78. package/dist/patterns/TableSkeleton/TableSkeleton.d.ts +1 -0
  79. package/dist/patterns/ToolbarButton/ToolbarButton.d.ts +2 -0
  80. package/dist/patterns/index.d.ts +33 -1
  81. package/dist/patterns/shared/hasContent.d.ts +2 -0
  82. package/dist/patterns/shared/index.d.ts +1 -0
  83. package/dist/patterns/shared/motion.d.ts +6 -0
  84. package/dist/patterns/shared/recordTone.d.ts +9 -0
  85. package/dist/patterns/shared/rem.d.ts +4 -0
  86. package/dist/patterns/shared/useContainerWidth.d.ts +6 -0
  87. package/dist/patterns/shared/useDecimalDraft.d.ts +33 -0
  88. package/dist/tailwind/index.cjs +17 -1
  89. package/dist/tailwind/index.d.ts +39 -0
  90. package/dist/tailwind/index.mjs +17 -1
  91. package/dist/test/ReducedMotion.d.ts +4 -0
  92. package/dist/test/RootFontSize.d.ts +5 -0
  93. package/dist/test/container-width.d.ts +14 -0
  94. package/dist/test/contrast.d.ts +1 -0
  95. package/dist/test/px-classes.d.ts +2 -0
  96. package/dist/test/root-font-size.d.ts +8 -0
  97. package/dist/tokens/pos-surface.d.ts +7 -0
  98. package/package.json +1 -1
@@ -0,0 +1,43 @@
1
+ export declare const RECORD_HEADER_WIDE_REM = 48;
2
+ export declare const recordHeaderClass: {
3
+ readonly base: "mb-4 overflow-hidden rounded-2xl border border-pos-line bg-white shadow-[0_1px_4px_rgba(0,0,0,.06),0_4px_12px_rgba(0,0,0,.06)]";
4
+ readonly band: "flex items-center gap-2.5 border-b border-pos-hair bg-pos-page px-4 py-2.5";
5
+ readonly back: "inline-flex size-[1.625rem] shrink-0 items-center justify-center rounded-[0.625rem] text-default-500 outline-none transition-colors hover:bg-default-100 focus-visible:outline focus-visible:outline-2 focus-visible:outline-primary motion-reduce:transition-none [html[data-pos-reduce-motion=true]_&]:transition-none";
6
+ readonly backIcon: "size-[0.875rem]";
7
+ readonly breadcrumb: "min-w-0 flex-1";
8
+ readonly breadcrumbList: "flex-nowrap gap-[0.375rem]";
9
+ readonly crumbBase: "min-w-0";
10
+ readonly crumb: "whitespace-nowrap text-[0.875rem] text-default-500 data-[disabled=true]:opacity-100 data-[current=true]:overflow-hidden data-[current=true]:font-normal data-[current=true]:text-default-900";
11
+ readonly crumbSeparator: "ms-[0.375rem] px-0 text-default-400 data-[disabled=true]:opacity-100";
12
+ readonly body: "flex flex-wrap gap-5";
13
+ readonly bodyWide: "px-5 pb-5 pt-[1.125rem]";
14
+ readonly bodyNarrow: "p-4";
15
+ readonly identity: "min-w-0 flex-[1_1_18.75rem]";
16
+ readonly title: "m-0 font-semibold tracking-[-.02em] text-default-900 [overflow-wrap:anywhere]";
17
+ readonly titleWide: "text-[1.5rem]";
18
+ readonly titleNarrow: "text-[1.3125rem]";
19
+ readonly meta: "m-0 mt-[0.6875rem] flex list-none flex-col gap-[0.4375rem] p-0";
20
+ readonly metaLine: "flex min-w-0 items-center gap-[0.5625rem] text-[0.84375rem] text-default-700";
21
+ readonly metaIcon: "flex shrink-0 text-default-400 [&_svg]:size-[0.9375rem]";
22
+ readonly metaText: "min-w-0 truncate";
23
+ readonly money: "flex flex-col gap-[0.3125rem]";
24
+ readonly moneyWide: "ml-auto min-w-[12.5rem] flex-none items-end text-right";
25
+ readonly moneyNarrow: "w-full items-start text-left";
26
+ readonly amountLabel: "text-[0.8125rem] text-default-500";
27
+ readonly amount: "whitespace-nowrap font-bold tracking-[-.03em] tabular-nums text-default-900";
28
+ readonly amountWide: "text-[1.9375rem] leading-[1.1]";
29
+ readonly amountNarrow: "text-[1.6875rem] leading-[1.1]";
30
+ readonly amountCaption: "text-[0.8125rem] text-default-500";
31
+ readonly recordId: "text-[0.8125rem] text-default-500";
32
+ readonly chips: "mt-[0.1875rem] flex flex-wrap gap-1.5";
33
+ readonly chipsWide: "justify-end";
34
+ readonly chipsNarrow: "justify-start";
35
+ readonly statItems: "m-0 mt-2.5 flex flex-wrap gap-[1.375rem]";
36
+ readonly stat: "flex flex-col-reverse";
37
+ readonly statWide: "text-right";
38
+ readonly statNarrow: "text-left";
39
+ readonly statValue: "m-0 text-[0.9375rem] font-bold tabular-nums text-default-900";
40
+ readonly statLabel: "mt-0.5 text-[0.75rem] text-default-500";
41
+ readonly statsWide: "px-5 pb-5";
42
+ readonly statsNarrow: "px-4 pb-4";
43
+ };
@@ -0,0 +1,30 @@
1
+ import { ReactNode } from 'react';
2
+ import { RecordTone } from '../shared/recordTone';
3
+ export interface RecordHeaderStat {
4
+ id?: string;
5
+ label: ReactNode;
6
+ value: ReactNode;
7
+ tone?: RecordTone;
8
+ }
9
+ export interface RecordHeaderProps {
10
+ breadcrumb: Array<{
11
+ label: string;
12
+ onClick?: () => void;
13
+ }>;
14
+ onBack?: () => void;
15
+ backLabel: string;
16
+ title: ReactNode;
17
+ meta?: Array<{
18
+ icon?: ReactNode;
19
+ text: ReactNode;
20
+ }>;
21
+ amountLabel?: string;
22
+ amount?: ReactNode;
23
+ amountCaption?: ReactNode;
24
+ recordId?: ReactNode;
25
+ chips?: ReactNode;
26
+ statItems?: RecordHeaderStat[];
27
+ stats?: ReactNode;
28
+ banner?: ReactNode;
29
+ 'data-testid'?: string;
30
+ }
@@ -0,0 +1,3 @@
1
+ import { default as React } from 'react';
2
+ import { RecordLayoutProps } from './types';
3
+ export declare const RecordLayout: React.FC<RecordLayoutProps>;
@@ -0,0 +1,2 @@
1
+ export { RecordLayout } from './RecordLayout';
2
+ export type { RecordLayoutProps } from './types';
@@ -0,0 +1,8 @@
1
+ export declare const RECORD_LAYOUT_SPLIT_REM = 50;
2
+ export declare const recordLayoutClass: {
3
+ readonly base: "grid items-start gap-4";
4
+ readonly split: "grid-cols-[minmax(0,1fr)_23.25rem]";
5
+ readonly stacked: "grid-cols-[minmax(0,1fr)]";
6
+ readonly column: "min-w-0";
7
+ readonly aside: "flex min-w-0 flex-col gap-[0.875rem]";
8
+ };
@@ -0,0 +1,6 @@
1
+ import { ReactNode } from 'react';
2
+ export interface RecordLayoutProps {
3
+ children: ReactNode;
4
+ aside?: ReactNode;
5
+ 'data-testid'?: string;
6
+ }
@@ -0,0 +1,19 @@
1
+ import { default as React } from 'react';
2
+ import { SignedAmountTone } from '../shared/recordTone';
3
+ export interface RecordTotalsRow {
4
+ id: string;
5
+ label: React.ReactNode;
6
+ note?: React.ReactNode;
7
+ value: React.ReactNode;
8
+ tone?: SignedAmountTone;
9
+ }
10
+ export interface RecordTotalsProps {
11
+ rows: RecordTotalsRow[];
12
+ total: {
13
+ label: React.ReactNode;
14
+ value: React.ReactNode;
15
+ };
16
+ memo?: React.ReactNode;
17
+ 'data-testid'?: string;
18
+ }
19
+ export declare const RecordTotals: React.FC<RecordTotalsProps>;
@@ -0,0 +1,2 @@
1
+ export { RecordTotals } from './RecordTotals';
2
+ export type { RecordTotalsProps, RecordTotalsRow } from './RecordTotals';
@@ -0,0 +1,19 @@
1
+ export declare const RECORD_TOTALS_WIDE_REM = 37.5;
2
+ export declare const recordTotalsClass: {
3
+ readonly base: "mx-5 border-t border-pos-hair pb-[1.125rem] pt-2.5";
4
+ readonly rowWide: "flex items-baseline gap-4";
5
+ readonly rowNarrow: "flex flex-wrap items-baseline gap-x-3";
6
+ readonly labelWide: "shrink-0 grow-0 basis-[11.875rem]";
7
+ readonly labelNarrow: "flex-auto";
8
+ readonly noteWide: "min-w-0 flex-1";
9
+ readonly noteNarrow: "order-3 mt-px basis-full";
10
+ readonly row: "py-2";
11
+ readonly label: "text-[0.875rem] text-default-900";
12
+ readonly note: "text-[0.8125rem] text-default-500";
13
+ readonly value: "ml-auto shrink-0 whitespace-nowrap text-right text-[0.875rem] tabular-nums text-default-900";
14
+ readonly totalRule: "mt-1.5 border-t border-pos-line";
15
+ readonly totalRow: "pt-3";
16
+ readonly totalLabel: "text-[0.9375rem] font-bold text-default-900";
17
+ readonly totalValue: "ml-auto shrink-0 whitespace-nowrap text-right text-[1.0625rem] font-bold tabular-nums text-default-900";
18
+ readonly memo: "mt-2 text-[0.78125rem] leading-[1.6] text-default-500";
19
+ };
@@ -0,0 +1,3 @@
1
+ import { default as React } from 'react';
2
+ import { RelatedRecordListProps } from './types';
3
+ export declare const RelatedRecordList: React.FC<RelatedRecordListProps>;
@@ -0,0 +1,2 @@
1
+ export { RelatedRecordList } from './RelatedRecordList';
2
+ export type { RelatedRecordListProps, RelatedRecordRow } from './types';
@@ -0,0 +1,19 @@
1
+ export declare const relatedRecordListClass: {
2
+ readonly base: "overflow-hidden rounded-2xl border border-pos-line bg-white shadow-[0_1px_4px_rgba(0,0,0,.06),0_4px_12px_rgba(0,0,0,.06)]";
3
+ readonly header: "flex flex-wrap items-center gap-2 px-5 pt-4";
4
+ readonly title: "m-0 min-w-0 text-[0.90625rem] font-semibold text-default-900 [overflow-wrap:anywhere]";
5
+ readonly count: "rounded-full bg-default-100 px-2 py-px text-[0.75rem] font-semibold text-default-600";
6
+ readonly list: "m-0 list-none p-0";
7
+ readonly item: "border-t border-pos-hair";
8
+ readonly itemFirstHeadless: "border-t-0";
9
+ readonly row: "flex w-full items-center gap-2.5 px-5 py-3 text-left";
10
+ readonly rowInteractive: "cursor-pointer outline-none transition-colors hover:bg-default-50 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-primary motion-reduce:transition-none [html[data-pos-reduce-motion=true]_&]:transition-none";
11
+ readonly rowBody: "flex min-w-0 flex-1 flex-col";
12
+ readonly rowHead: "flex min-w-0 flex-wrap items-center gap-2";
13
+ readonly primaryLinked: "min-w-0 text-[0.875rem] font-normal text-primary [overflow-wrap:anywhere]";
14
+ readonly primaryPlain: "min-w-0 text-[0.875rem] font-normal text-default-900 [overflow-wrap:anywhere]";
15
+ readonly secondary: "mt-[0.1875rem] block min-w-0 truncate text-[0.8125rem] text-default-500";
16
+ readonly amount: "max-w-[45%] shrink-0 text-right text-[0.875rem] font-semibold tabular-nums text-default-900 [overflow-wrap:anywhere]";
17
+ readonly empty: "min-w-0 px-5 pb-5 pt-[0.875rem] text-[0.875rem] text-default-500 [overflow-wrap:anywhere]";
18
+ readonly emptyHeadless: "pt-5";
19
+ };
@@ -0,0 +1,17 @@
1
+ import { ReactNode } from 'react';
2
+ export interface RelatedRecordRow {
3
+ id: string;
4
+ primary: ReactNode;
5
+ chip?: ReactNode;
6
+ secondary?: ReactNode;
7
+ amount?: ReactNode;
8
+ amountTone?: 'positive' | 'negative' | 'neutral';
9
+ onSelect?: () => void;
10
+ }
11
+ export interface RelatedRecordListProps {
12
+ title?: ReactNode;
13
+ count?: number;
14
+ rows: RelatedRecordRow[];
15
+ emptyContent: ReactNode;
16
+ 'data-testid'?: string;
17
+ }
@@ -0,0 +1,3 @@
1
+ import { default as React } from 'react';
2
+ import { StatTilesProps } from './types';
3
+ export declare const StatTiles: React.FC<StatTilesProps>;
@@ -0,0 +1,2 @@
1
+ export { StatTiles } from './StatTiles';
2
+ export type { StatTilesProps, StatTileItem } from './types';
@@ -0,0 +1,8 @@
1
+ export declare const STAT_TILES_PAIR_MIN = 560;
2
+ export declare const statTilesClass: {
3
+ readonly base: "grid gap-3";
4
+ readonly tile: "min-w-0 rounded-[14px] border border-pos-line bg-white px-[18px] py-4 shadow-[0_1px_4px_rgba(0,0,0,.06),0_4px_12px_rgba(0,0,0,.06)]";
5
+ readonly value: "text-[23px] font-bold leading-[1.2] tracking-[-.02em] tabular-nums text-default-900 [overflow-wrap:anywhere]";
6
+ readonly label: "mt-[5px] text-[13.5px] text-default-500";
7
+ readonly caption: "mt-0.5 text-[12.5px] text-default-500";
8
+ };
@@ -0,0 +1,12 @@
1
+ import { ReactNode } from 'react';
2
+ import { RecordTone } from '../shared/recordTone';
3
+ export interface StatTileItem {
4
+ label: string;
5
+ value: ReactNode;
6
+ tone?: RecordTone;
7
+ caption?: ReactNode;
8
+ }
9
+ export interface StatTilesProps {
10
+ items: StatTileItem[];
11
+ 'data-testid'?: string;
12
+ }
@@ -1,7 +1,7 @@
1
1
  import { default as React } from 'react';
2
2
  import { ChipProps } from '../../components';
3
3
  /** Domain-agnostic lifecycle states an admin row can be in. */
4
- export type StatusChipStatus = 'active' | 'archived' | 'inactive' | 'draft' | 'pending' | 'success' | 'warning' | 'danger' | 'neutral';
4
+ export type StatusChipStatus = 'active' | 'archived' | 'inactive' | 'draft' | 'pending' | 'success' | 'warning' | 'danger' | 'neutral' | 'info' | 'violet';
5
5
  export interface StatusChipProps {
6
6
  /** Lifecycle state — selects the colour/tone only, never the text. */
7
7
  status: StatusChipStatus;
@@ -12,12 +12,12 @@ export interface StatusChipProps {
12
12
  * `'dot'` variant: a soft, radius-full pill with a leading tone dot,
13
13
  * 12px / weight-600 text, tuned for dense admin lifecycle tables.
14
14
  */
15
- variant?: ChipProps['variant'] | 'dot';
15
+ variant?: ChipProps['variant'] | 'dot' | 'plain';
16
16
  /** Chip size. Default `'sm'`. Ignored by `variant="dot"`. */
17
17
  size?: ChipProps['size'];
18
18
  /**
19
19
  * Override the colour derived from `status`. Escape hatch for the
20
- * rare state not covered by `StatusChipStatus`. Ignored by `variant="dot"`.
20
+ * rare state not covered by `StatusChipStatus`. Ignored by `variant="dot"` and `variant="plain"`.
21
21
  */
22
22
  color?: ChipProps['color'];
23
23
  /** Optional leading element (dot, icon). Ignored by `variant="dot"`. */
@@ -6,6 +6,7 @@ export interface GrandTotalRowProps {
6
6
  amount: Money;
7
7
  };
8
8
  locale: string;
9
+ compact?: boolean;
9
10
  className?: string;
10
11
  }
11
12
  export declare const GrandTotalRow: React.FC<GrandTotalRowProps>;
@@ -7,5 +7,6 @@ export interface ItemRowProps {
7
7
  removeAriaLabel: string;
8
8
  /** Show the per-item remove control. Defaults to `true`. */
9
9
  showRemoveButton?: boolean;
10
+ compact?: boolean;
10
11
  }
11
12
  export declare const ItemRow: React.FC<ItemRowProps>;
@@ -9,9 +9,12 @@ export interface SummaryBodyProps {
9
9
  locale: string;
10
10
  onRemoveItem?: (id: string) => void;
11
11
  removeAriaLabel: string;
12
- /** Show the per-item remove control. Defaults to `true`. */
12
+ onRemoveTotalRow?: (id: string) => void;
13
+ removeTotalRowAriaLabel: string;
14
+ /** Show the per-item and per-totals-row remove controls. Defaults to `true`. */
13
15
  showRemoveButton?: boolean;
14
16
  emptyState?: React.ReactNode;
17
+ compact?: boolean;
15
18
  classNames: SummaryClassNames;
16
19
  }
17
20
  export declare const SummaryBody: React.FC<SummaryBodyProps>;
@@ -1,12 +1,13 @@
1
1
  import { default as React } from 'react';
2
- import { SummaryPostTotalRow } from '../types';
2
+ import { SummaryTotalRow } from '../types';
3
3
  export interface TotalsLineRowProps {
4
- row: SummaryPostTotalRow;
4
+ row: SummaryTotalRow;
5
5
  locale: string;
6
6
  emphasized: boolean;
7
7
  onRemove?: (id: string) => void;
8
8
  removeAriaLabel?: string;
9
9
  /** Show the per-row remove control. Defaults to `true`. */
10
10
  showRemoveButton?: boolean;
11
+ compact?: boolean;
11
12
  }
12
13
  export declare const TotalsLineRow: React.FC<TotalsLineRowProps>;
@@ -1,5 +1,6 @@
1
1
  import { ReactNode } from 'react';
2
2
  import { Money } from '../../utils/money';
3
+ import { RecordTone } from '../shared/recordTone';
3
4
  export type { Money } from '../../utils/money';
4
5
  /**
5
6
  * A generic, parametrizable detail row rendered under a line item — an icon +
@@ -56,6 +57,12 @@ export interface SummaryLineItem {
56
57
  * show an auto-renewal note and a pay-by-installments line.
57
58
  */
58
59
  details?: SummaryItemDetail[];
60
+ /** Pre-formatted list price, rendered struck through before `amount`. */
61
+ originalAmount?: string;
62
+ /** Node rendered under the amount, right-aligned (e.g. a `StatusChip`). */
63
+ trailing?: ReactNode;
64
+ /** Tints the whole row with the tone's fill. */
65
+ tone?: RecordTone;
59
66
  }
60
67
  /** The "Pay Service fee" radio-toggle row. */
61
68
  export interface SummaryServiceFee {
@@ -66,18 +73,18 @@ export interface SummaryServiceFee {
66
73
  /** Fires when the row/radio is toggled. */
67
74
  onToggle?: () => void;
68
75
  }
69
- /** A plain totals row (Subtotal, Taxes). */
76
+ /** A plain totals row (Subtotal, Discounts, Taxes). */
70
77
  export interface SummaryTotalRow {
71
78
  /** Stable key for `data-testid` (e.g. 'subtotal', 'taxes'). */
72
79
  key: string;
73
80
  label: ReactNode;
74
81
  amount: Money;
82
+ /** Stable id; when set and `onRemoveTotalRow` exists, the row shows the remove control (e.g. one row per removable discount). */
83
+ id?: string;
75
84
  }
76
85
  /**
77
- * A post-total row — the same flat shape as {@link SummaryTotalRow}, plus an
78
- * optional `id` that (together with `onRemovePostTotalRow`) enables the same
79
- * trash remove control the line items use. Kept as its own interface so the
80
- * pre-total `rows` — where an id/remove has no meaning — stay untouched.
86
+ * A post-total row — the same flat shape as {@link SummaryTotalRow}; rows with
87
+ * an `id` show the trash remove control when `onRemovePostTotalRow` exists.
81
88
  */
82
89
  export interface SummaryPostTotalRow extends SummaryTotalRow {
83
90
  /** Stable id; when set and `onRemovePostTotalRow` exists, the row shows the remove control. */
@@ -94,6 +101,8 @@ export interface SummaryPrimaryAction {
94
101
  export interface SummaryLabels {
95
102
  /** Aria label for the per-item remove control. Default "Remove item". */
96
103
  removeAriaLabel?: string;
104
+ /** Aria label for the per-totals-row remove control. Default "Remove discount". */
105
+ removeTotalRowAriaLabel?: string;
97
106
  /** Aria label for the per-post-total-row remove control. Default "Remove applied code". */
98
107
  removePostTotalRowAriaLabel?: string;
99
108
  /** Aria label for the collapse/expand press target. Default "Toggle summary". */
@@ -150,7 +159,11 @@ export interface SummaryProps {
150
159
  items?: SummaryLineItem[];
151
160
  /** Optional "Pay Service fee" radio-toggle row. */
152
161
  serviceFee?: SummaryServiceFee;
153
- /** Plain totals rows rendered above the Total (Subtotal, Taxes). */
162
+ /**
163
+ * Plain totals rows rendered above the Total (Subtotal, Discounts, Taxes).
164
+ * Rows with an `id` show the trash remove control when `onRemoveTotalRow`
165
+ * is provided (same gating as the item remove, incl. `showRemoveButton`).
166
+ */
154
167
  rows?: SummaryTotalRow[];
155
168
  /** The emphasized Total row (label default "Total"). */
156
169
  total: {
@@ -182,9 +195,9 @@ export interface SummaryProps {
182
195
  */
183
196
  ctaCaption?: ReactNode;
184
197
  /**
185
- * Whether the remove (trash) controls are shown — per-item and
186
- * per-post-total-row alike. Defaults to `true`; pass `false` to hide them
187
- * even when `onRemoveItem` / `onRemovePostTotalRow` are wired. Independent
198
+ * Whether the remove (trash) controls are shown — per-item, per-totals-row
199
+ * and per-post-total-row alike. Defaults to `true`; pass `false` to hide them
200
+ * even when `onRemoveItem` / `onRemoveTotalRow` / `onRemovePostTotalRow` are wired. Independent
188
201
  * of the handlers so a host can keep them but suppress the controls.
189
202
  */
190
203
  showRemoveButton?: boolean;
@@ -213,6 +226,8 @@ export interface SummaryProps {
213
226
  primaryAction?: SummaryPrimaryAction;
214
227
  /** When provided, item rows show a red trash remove control. */
215
228
  onRemoveItem?: (id: string) => void;
229
+ /** When provided, totals rows (above the Total) with an `id` show the same red trash remove control. */
230
+ onRemoveTotalRow?: (id: string) => void;
216
231
  /** When provided, post-total rows with an `id` show the same red trash remove control. */
217
232
  onRemovePostTotalRow?: (id: string) => void;
218
233
  /**
@@ -231,6 +246,13 @@ export interface SummaryProps {
231
246
  /** Rendered when there are no items. */
232
247
  emptyState?: ReactNode;
233
248
  labels?: SummaryLabels;
249
+ /**
250
+ * Visual density. `'compact'` drops the card's title and the prices row, removes the
251
+ * `{qty} x` prefix, separates items with dividers, renders the totals rows
252
+ * small and muted and a smaller Total without a divider above it (e.g. a POS
253
+ * cart panel). Defaults to `'default'`.
254
+ */
255
+ density?: 'default' | 'compact';
234
256
  'data-testid'?: string;
235
257
  className?: string;
236
258
  /** Per-slot class overrides (Design-System `classNames` convention). */
@@ -25,6 +25,7 @@ export interface TableSkeletonProps {
25
25
  barHeight?: number;
26
26
  /** Right-aligns the last column's bar, for a trailing numeric or actions column. */
27
27
  alignLastRight?: boolean;
28
+ appearance?: 'pulse' | 'shimmer';
28
29
  className?: string;
29
30
  classNames?: TableSkeletonClassNames;
30
31
  'data-testid'?: string;
@@ -10,6 +10,7 @@ export type ToolbarButtonProps = Omit<ComponentPropsWithoutRef<typeof Button>, '
10
10
  * count straight through without guarding it.
11
11
  */
12
12
  count?: number;
13
+ appearance?: 'pill' | 'outline';
13
14
  /** Forwarded as `data-testid`. */
14
15
  testId?: string;
15
16
  };
@@ -23,6 +24,7 @@ export declare const ToolbarButton: React.ForwardRefExoticComponent<Omit<Omit<Om
23
24
  * count straight through without guarding it.
24
25
  */
25
26
  count?: number;
27
+ appearance?: "pill" | "outline";
26
28
  /** Forwarded as `data-testid`. */
27
29
  testId?: string;
28
30
  } & React.RefAttributes<HTMLButtonElement>>;
@@ -99,7 +99,7 @@ export { Summary } from './Summary';
99
99
  export type { SummaryProps, SummaryLineItem, SummaryItemDetail, SummaryServiceFee, SummaryTotalRow, SummaryPostTotalRow, SummaryPrimaryAction, SummaryLabels, } from './Summary';
100
100
  export { WizardShell } from './WizardShell';
101
101
  export type { WizardShellProps, WizardStep, WizardStepState, WizardShellPrimaryAction, WizardShellSecondaryAction, WizardShellTotalRow, WizardShellLabels, } from './WizardShell';
102
- export type { TenderError, DestinationLine, DestinationStatus } from './shared';
102
+ export type { TenderError, DestinationLine, DestinationStatus, RecordTone } from './shared';
103
103
  export { LineItemList } from './LineItemList';
104
104
  export type { LineItemListProps, LineItemView, ItemSelection, LineItemState, LineItemRestockView, ItemDisposition, AmountOnlyView, LineItemListLabels, } from './LineItemList';
105
105
  export { MetaCard } from './MetaCard';
@@ -120,3 +120,35 @@ export { PinField } from './PinField';
120
120
  export type { PinFieldProps, PinFieldLabels } from './PinField';
121
121
  export { OutcomeView } from './OutcomeView';
122
122
  export type { OutcomeViewProps, OutcomeViewLabels, ReceiptChannel } from './OutcomeView';
123
+ export { FilterSelect } from './FilterSelect';
124
+ export type { FilterSelectProps, FilterSelectOption } from './FilterSelect';
125
+ export { LoadMoreFooter } from './LoadMoreFooter';
126
+ export type { LoadMoreFooterProps, LoadMoreStatus } from './LoadMoreFooter';
127
+ export { CardList } from './CardList';
128
+ export type { CardListProps, CardListItem } from './CardList';
129
+ export { RecordHeader } from './RecordHeader';
130
+ export type { RecordHeaderProps, RecordHeaderStat } from './RecordHeader';
131
+ export { RecordLayout } from './RecordLayout';
132
+ export type { RecordLayoutProps } from './RecordLayout';
133
+ export { StatTiles } from './StatTiles';
134
+ export type { StatTilesProps, StatTileItem } from './StatTiles';
135
+ export { PillTabs, pillTabId, pillTabPanelId, pillTabPanelProps } from './PillTabs';
136
+ export type { PillTabsProps, PillTabItem } from './PillTabs';
137
+ export { AmountList } from './AmountList';
138
+ export type { AmountListProps, AmountListRow } from './AmountList';
139
+ export { ActivityTimeline } from './ActivityTimeline';
140
+ export type { ActivityTimelineProps, ActivityTimelineEvent } from './ActivityTimeline';
141
+ export { RelatedRecordList } from './RelatedRecordList';
142
+ export type { RelatedRecordListProps, RelatedRecordRow } from './RelatedRecordList';
143
+ export { RecordCard } from './RecordCard';
144
+ export type { RecordCardProps, RecordCardVariant, RecordCardBody } from './RecordCard';
145
+ export { CardStack } from './CardStack';
146
+ export type { CardStackProps, CardStackLayout } from './CardStack';
147
+ export { KeyValueRows } from './KeyValueRows';
148
+ export type { KeyValueRowsProps, KeyValueRow, KeyValueRowsDensity } from './KeyValueRows';
149
+ export { LineItemRows } from './LineItemRows';
150
+ export type { LineItemRowsProps, LineItemRow } from './LineItemRows';
151
+ export { RecordTotals } from './RecordTotals';
152
+ export type { RecordTotalsProps, RecordTotalsRow } from './RecordTotals';
153
+ export { CellText, ChipStack } from './CellText';
154
+ export type { CellTextProps, CellTextVariant, ChipStackProps } from './CellText';
@@ -0,0 +1,2 @@
1
+ import { ReactNode } from 'react';
2
+ export declare function hasContent(node: ReactNode): boolean;
@@ -1 +1,2 @@
1
1
  export type { TenderError, DestinationLine, DestinationStatus } from './types';
2
+ export type { RecordTone } from './recordTone';
@@ -0,0 +1,6 @@
1
+ export declare const POS_REDUCE_MOTION_ATTRIBUTE = "data-pos-reduce-motion";
2
+ export declare const stillTransitionClass = "motion-reduce:transition-none [html[data-pos-reduce-motion=true]_&]:transition-none";
3
+ export declare const stillAnimationClass = "motion-reduce:animate-none [html[data-pos-reduce-motion=true]_&]:animate-none";
4
+ export declare const shimmerClass = "rounded-[0.375rem] bg-[linear-gradient(90deg,#F0F0F1_0,#F9F9FA_12.5rem,#F0F0F1_25rem)] bg-[length:50rem_100%] animate-record-shimmer motion-reduce:animate-none [html[data-pos-reduce-motion=true]_&]:animate-none";
5
+ export declare function prefersReducedMotion(): boolean;
6
+ export declare function useReducedMotion(): boolean;
@@ -0,0 +1,9 @@
1
+ import { CSSProperties } from 'react';
2
+ export type RecordTone = 'ok' | 'warn' | 'danger' | 'info' | 'violet' | 'neutral';
3
+ export interface RecordTonePair {
4
+ fg: string;
5
+ bg: string;
6
+ }
7
+ export declare const RECORD_TONE: Record<RecordTone, RecordTonePair>;
8
+ export type SignedAmountTone = 'positive' | 'negative' | 'neutral';
9
+ export declare function amountToneStyle(tone: SignedAmountTone | undefined): CSSProperties | undefined;
@@ -0,0 +1,4 @@
1
+ export declare const ROOT_FONT_PX = 16;
2
+ export declare const rem: (px: number) => string;
3
+ export declare function rootFontSizePx(): number;
4
+ export declare const atLeastRem: (widthPx: number, rems: number) => boolean;
@@ -0,0 +1,6 @@
1
+ export declare const CONTAINER_MEDIUM = 768;
2
+ export declare const CONTAINER_WIDE = 1120;
3
+ export declare function useContainerWidth<T extends HTMLElement>(): {
4
+ ref: import('react').RefObject<T | null>;
5
+ width: number;
6
+ };
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Keeps the text a cashier typed into a money input separate from the number
3
+ * the host holds.
4
+ *
5
+ * A money input whose display is `String(value)` loses what the cashier is
6
+ * mid-way through typing: `'40.'` parses to `40` and is re-rendered as `'40'`,
7
+ * so the next `0` produces `'400'` and `'40.00'` ends up read as 4000. The hook
8
+ * keeps the typed string and shows it while it still parses to `value` (the
9
+ * echo of the cashier's own keystroke). When the host holds a number the draft
10
+ * does not represent (a reset, a prefill, a host that ignores the keystroke),
11
+ * the input shows `format(value)` instead, so the host stays in control.
12
+ */
13
+ /**
14
+ * Whether `text` is one amount, possibly partial, in a currency with
15
+ * `fractionDigits` minor digits: digits, then at most one `.` or `,` followed
16
+ * by at most `fractionDigits` digits (`''`, `'40'`, `'40.'`, `'40,5'`, `'.5'`).
17
+ * Anything else would show one amount while emitting another, because
18
+ * `parseFloat` reads only a prefix and `,` is the decimal separator: `'40.5.9'`
19
+ * and `'4a'` would emit 40.5 and 4, and `'1,000'` would emit 1. Callers reject
20
+ * such a keystroke instead of storing it, so the input keeps what it showed.
21
+ */
22
+ export declare const isDecimalDraft: (text: string, fractionDigits: number) => boolean;
23
+ /** Parses a typed amount (`'40.5'`, `'40,5'`, `'40.'`); `null` when there is no number yet (`''`, `'.'`, `','`). */
24
+ export declare const parseDecimalDraft: (draft: string) => number | null;
25
+ export interface DecimalDraft {
26
+ /** The text to show in the input. */
27
+ draft: string;
28
+ /** Stores the text the cashier typed. */
29
+ setDraft: (next: string) => void;
30
+ /** Rewrites the draft in its canonical form (`'40.'` → `'40'`) without changing its value. */
31
+ normalize: () => void;
32
+ }
33
+ export declare const useDecimalDraft: (value: number | null | undefined, format: (value: number | null | undefined) => string) => DecimalDraft;
@@ -274,6 +274,9 @@ var posSurfaceTokens = {
274
274
  line: "#E7E7E9",
275
275
  /** `--line2`: the lighter hairline under list rows and above the role bar. */
276
276
  "line-2": "#F1F1F3",
277
+ hair: "#F0F0F1",
278
+ page: "#FBFBFB",
279
+ field: "#E5E5E5",
277
280
  /** `--okb` / `--okf` */
278
281
  "ok-fill": "#EAF3DE",
279
282
  ok: "#3B6D11",
@@ -288,6 +291,10 @@ var posSurfaceTokens = {
288
291
  /** `--ib` / `--if` */
289
292
  "info-fill": "#EAF1FC",
290
293
  info: "#1D4FA8",
294
+ "violet-fill": "#F1ECFB",
295
+ violet: "#6D28D9",
296
+ "neutral-fill": "#F4F4F5",
297
+ neutral: "#52525B",
291
298
  /** `.btn-dstr` — the fill behind an irreversible confirmation. */
292
299
  destructive: "#A32D2D"
293
300
  };
@@ -314,7 +321,16 @@ var tailwindTheme = {
314
321
  spacing,
315
322
  fontSize: typography.fontSize,
316
323
  fontWeight: typography.fontWeight,
317
- lineHeight: typography.lineHeight
324
+ lineHeight: typography.lineHeight,
325
+ keyframes: {
326
+ "record-shimmer": {
327
+ "0%": { backgroundPosition: "-25rem 0" },
328
+ "100%": { backgroundPosition: "25rem 0" }
329
+ }
330
+ },
331
+ animation: {
332
+ "record-shimmer": "record-shimmer 1.3s linear infinite"
333
+ }
318
334
  };
319
335
  function deepMerge(target, source) {
320
336
  if (!source || typeof source !== "object") {