@veevarts/design-system 2.1.0-beta.13 → 2.1.0-beta.15

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 (45) hide show
  1. package/dist/components/Select/Select.d.ts +10 -0
  2. package/dist/index.cjs +8 -8
  3. package/dist/index.d.ts +2 -0
  4. package/dist/index.js +4947 -4060
  5. package/dist/patterns/AdminToolbar/AdminToolbar.d.ts +10 -2
  6. package/dist/patterns/AdminToolbar/index.d.ts +1 -0
  7. package/dist/patterns/AdminToolbar/styles.d.ts +49 -0
  8. package/dist/patterns/AdminToolbar/types.d.ts +2 -0
  9. package/dist/patterns/CardList/styles.d.ts +5 -1
  10. package/dist/patterns/CardList/types.d.ts +1 -0
  11. package/dist/patterns/DiscardGuard/DiscardGuard.d.ts +23 -0
  12. package/dist/patterns/DiscardGuard/context.d.ts +25 -0
  13. package/dist/patterns/DiscardGuard/index.d.ts +6 -0
  14. package/dist/patterns/DiscardGuard/useDiscardGuard.d.ts +38 -0
  15. package/dist/patterns/EntityRow/EntityList.d.ts +9 -0
  16. package/dist/patterns/EntityRow/EntityRow.d.ts +3 -0
  17. package/dist/patterns/EntityRow/context.d.ts +2 -0
  18. package/dist/patterns/EntityRow/icons.d.ts +3 -0
  19. package/dist/patterns/EntityRow/index.d.ts +3 -0
  20. package/dist/patterns/EntityRow/initials.d.ts +6 -0
  21. package/dist/patterns/EntityRow/styles.d.ts +59 -0
  22. package/dist/patterns/EntityRow/types.d.ts +118 -0
  23. package/dist/patterns/FilterSelect/styles.d.ts +6 -5
  24. package/dist/patterns/InlineConfirm/InlineConfirm.d.ts +38 -0
  25. package/dist/patterns/InlineConfirm/index.d.ts +2 -0
  26. package/dist/patterns/InlineConfirm/styles.d.ts +16 -0
  27. package/dist/patterns/ModalPanels/ModalPanels.d.ts +35 -0
  28. package/dist/patterns/ModalPanels/context.d.ts +20 -0
  29. package/dist/patterns/ModalPanels/focus.d.ts +39 -0
  30. package/dist/patterns/ModalPanels/index.d.ts +6 -0
  31. package/dist/patterns/ModalPanels/styles.d.ts +13 -0
  32. package/dist/patterns/ModalPanels/useModalPanels.d.ts +30 -0
  33. package/dist/patterns/PaginationSummary/PaginationSummary.d.ts +12 -0
  34. package/dist/patterns/PaginationSummary/index.d.ts +1 -1
  35. package/dist/patterns/PillTabs/index.d.ts +1 -1
  36. package/dist/patterns/PillTabs/styles.d.ts +14 -4
  37. package/dist/patterns/PillTabs/types.d.ts +8 -0
  38. package/dist/patterns/RecordCard/index.d.ts +1 -1
  39. package/dist/patterns/RecordCard/styles.d.ts +3 -2
  40. package/dist/patterns/RecordCard/types.d.ts +5 -0
  41. package/dist/patterns/index.d.ts +12 -4
  42. package/dist/providers/DensityProvider.d.ts +7 -0
  43. package/dist/providers/density.d.ts +17 -0
  44. package/dist/providers/index.d.ts +4 -0
  45. package/package.json +2 -2
@@ -0,0 +1,30 @@
1
+ /** One panel on the stack. `key` is unique per visit, so pushing the same panel twice mounts it twice. */
2
+ export interface ModalPanelEntry<TPanel> {
3
+ readonly key: string;
4
+ readonly panel: TPanel;
5
+ }
6
+ export interface ModalPanelsController<TPanel> {
7
+ /** The panel on top — the one on screen. */
8
+ readonly current: TPanel;
9
+ /** Bottom to top. Every entry stays mounted; only the last one is shown. */
10
+ readonly entries: readonly ModalPanelEntry<TPanel>[];
11
+ /** True when there is a panel beneath the current one. */
12
+ readonly canGoBack: boolean;
13
+ /** Opens `panel` on top; Back returns to the one showing now. */
14
+ push: (panel: TPanel) => void;
15
+ /** Returns to the panel beneath. No-op on the first panel. */
16
+ back: () => void;
17
+ /** Swaps the top panel for `panel` (e.g. a saved form for its detail); Back skips the old one. */
18
+ replace: (panel: TPanel) => void;
19
+ /** Starts over with a single fresh panel — `initial` unless another is given. */
20
+ reset: (panel?: TPanel) => void;
21
+ }
22
+ /**
23
+ * The back-stack behind `ModalPanels`: which panel is on screen, and where Back
24
+ * goes from it. Back goes where the operator came from because the stack
25
+ * remembers it — no per-panel "return to" flags to keep in step.
26
+ *
27
+ * Owned by the component that owns the modal, so it outlives the modal's
28
+ * content; call `reset()` when the modal closes to start the next visit fresh.
29
+ */
30
+ export declare function useModalPanels<TPanel>(initial: TPanel): ModalPanelsController<TPanel>;
@@ -3,6 +3,12 @@ export interface PaginationSummaryClassNames {
3
3
  base?: string;
4
4
  emphasis?: string;
5
5
  }
6
+ /** The range `format` receives; `from` and `to` are both 0 when there is nothing to show. */
7
+ export interface PaginationSummaryRange {
8
+ from: number;
9
+ to: number;
10
+ total: number;
11
+ }
6
12
  export interface PaginationSummaryProps {
7
13
  /** Current page, 1-based. */
8
14
  page: number;
@@ -19,6 +25,12 @@ export interface PaginationSummaryProps {
19
25
  * avoid reading the change twice.
20
26
  */
21
27
  announce?: boolean;
28
+ /**
29
+ * Writes the sentence instead of the built-in English "Showing {range} of
30
+ * {total} {unit}". Use it to translate; `unit` and `classNames.emphasis`
31
+ * do not apply, since the returned node is the whole sentence.
32
+ */
33
+ format?: (range: PaginationSummaryRange) => React.ReactNode;
22
34
  className?: string;
23
35
  classNames?: PaginationSummaryClassNames;
24
36
  'data-testid'?: string;
@@ -1,3 +1,3 @@
1
1
  export { PaginationSummary } from './PaginationSummary';
2
- export type { PaginationSummaryProps, PaginationSummaryClassNames } from './PaginationSummary';
2
+ export type { PaginationSummaryProps, PaginationSummaryClassNames, PaginationSummaryRange } from './PaginationSummary';
3
3
  export { pageRange } from './page-range';
@@ -1,3 +1,3 @@
1
1
  export { PillTabs } from './PillTabs';
2
2
  export { pillTabId, pillTabPanelId, pillTabPanelProps } from './ids';
3
- export type { PillTabsProps, PillTabItem } from './types';
3
+ export type { PillTabsProps, PillTabItem, PillTabsSize } from './types';
@@ -1,10 +1,20 @@
1
+ import { PillTabsSize } from './types';
1
2
  export declare const pillTabsClass: {
2
3
  readonly base: "mb-3.5 w-full";
3
4
  readonly tabList: "w-full gap-1 rounded-full border border-pos-line bg-default-100 p-1";
4
5
  readonly cursor: "rounded-full bg-white shadow-[0_1px_3px_rgba(0,0,0,.10)]";
5
- readonly tab: "h-auto flex-1 px-[0.875rem] py-[0.5625rem] data-[hover-unselected=true]:opacity-100";
6
+ readonly tab: "h-auto flex-1 data-[hover-unselected=true]:opacity-100";
6
7
  readonly tabStill: "rounded-full data-[selected=true]:bg-white data-[selected=true]:shadow-[0_1px_3px_rgba(0,0,0,.10)]";
7
- readonly tabContent: "text-[0.84375rem] leading-[1.5] font-normal text-default-600 group-data-[selected=true]:font-semibold group-data-[selected=true]:text-default-900";
8
- readonly title: "inline-flex items-center gap-[0.4375rem] whitespace-nowrap";
9
- readonly count: "rounded-full bg-default-200 px-[0.4375rem] py-px text-[0.71875rem] leading-[1.5] font-semibold text-default-600 group-data-[selected=true]:bg-acct-rust-fill group-data-[selected=true]:text-primary-600";
8
+ readonly tabContent: "leading-[1.5] font-normal text-default-600 group-data-[selected=true]:font-semibold group-data-[selected=true]:text-default-900";
9
+ readonly title: "flex items-center whitespace-nowrap";
10
+ readonly icon: "flex shrink-0";
11
+ readonly count: "rounded-full bg-default-200 py-px leading-[1.5] font-semibold text-default-600 group-data-[selected=true]:bg-acct-rust-fill group-data-[selected=true]:text-primary-600";
10
12
  };
13
+ /** `lg`: 12px above and below a 24px line (16px text) is a 48px tab, in rem so it scales. */
14
+ export declare const pillTabsSizeClass: Record<PillTabsSize, {
15
+ tab: string;
16
+ tabContent: string;
17
+ title: string;
18
+ icon: string;
19
+ count: string;
20
+ }>;
@@ -1,7 +1,13 @@
1
+ import { ReactNode } from 'react';
2
+ export type PillTabsSize = 'md' | 'lg';
1
3
  export interface PillTabItem {
2
4
  key: string;
3
5
  label: string;
4
6
  count?: number;
7
+ /** Decorative glyph before the label; hidden from assistive tech, the label names the tab. */
8
+ icon?: ReactNode;
9
+ /** Replaces the derived `<data-testid>-<key>`; the count becomes `<this>-count`. */
10
+ 'data-testid'?: string;
5
11
  }
6
12
  export interface PillTabsProps {
7
13
  items: PillTabItem[];
@@ -9,5 +15,7 @@ export interface PillTabsProps {
9
15
  onChange: (key: string) => void;
10
16
  ariaLabel: string;
11
17
  idPrefix?: string;
18
+ /** `md` (default) is the 38px record-page tab; `lg` is the 48px touch target, with larger text. */
19
+ size?: PillTabsSize;
12
20
  'data-testid'?: string;
13
21
  }
@@ -1,2 +1,2 @@
1
1
  export { RecordCard } from './RecordCard';
2
- export type { RecordCardProps, RecordCardVariant, RecordCardBody } from './types';
2
+ export type { RecordCardProps, RecordCardVariant, RecordCardBody, RecordCardSurface } from './types';
@@ -1,7 +1,7 @@
1
- import { RecordCardBody, RecordCardVariant } from './types';
1
+ import { RecordCardBody, RecordCardSurface, RecordCardVariant } from './types';
2
2
  export declare const recordCardShadow = "shadow-[0_1px_4px_rgba(0,0,0,.06),0_4px_12px_rgba(0,0,0,.06)]";
3
3
  export declare const recordCardClass: {
4
- 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)]";
4
+ readonly base: "overflow-hidden rounded-2xl border border-pos-line bg-white";
5
5
  readonly title: "m-0 min-w-0 text-[0.90625rem] font-semibold text-default-900 [overflow-wrap:anywhere]";
6
6
  readonly count: "rounded-full bg-default-100 px-2 py-px text-[0.75rem] font-semibold text-default-600";
7
7
  readonly icon: "flex shrink-0 text-default-500 [&_svg]:size-[1.125rem]";
@@ -11,5 +11,6 @@ export declare const recordCardClass: {
11
11
  readonly footerAfterContent: "mt-[0.875rem]";
12
12
  readonly footerAfterDescription: "mt-3";
13
13
  };
14
+ export declare const recordCardSurfaceClass: Record<RecordCardSurface, string>;
14
15
  export declare const recordCardHeaderClass: Record<RecordCardVariant, string>;
15
16
  export declare const recordCardBodyClass: Record<RecordCardVariant, Record<RecordCardBody, string>>;
@@ -1,6 +1,8 @@
1
1
  import { ReactNode } from 'react';
2
2
  export type RecordCardVariant = 'section' | 'aside';
3
3
  export type RecordCardBody = 'padded' | 'rows' | 'flush' | 'none';
4
+ /** `card` sits on a grey page with the layered shadow; `flat` keeps the border and drops the shadow, for a card inside a modal. */
5
+ export type RecordCardSurface = 'card' | 'flat';
4
6
  export interface RecordCardProps {
5
7
  title?: ReactNode;
6
8
  titleAs?: 'h2' | 'h3' | 'h4';
@@ -12,6 +14,9 @@ export interface RecordCardProps {
12
14
  footer?: ReactNode;
13
15
  variant?: RecordCardVariant;
14
16
  body?: RecordCardBody;
17
+ surface?: RecordCardSurface;
18
+ /** Merged onto the root, after the chrome (e.g. `break-inside-avoid` in a multi-column host). */
19
+ className?: string;
15
20
  children?: ReactNode;
16
21
  'data-testid'?: string;
17
22
  }
@@ -58,7 +58,7 @@ export type { TableSkeletonProps, TableSkeletonClassNames } from './TableSkeleto
58
58
  export { AdminTable, adminRowClass, adminTableClass, adminTableFooterClass, adminTdClass, adminThClass, } from './AdminTable';
59
59
  export type { AdminTableProps, AdminTableColumn, AdminTableClassNames } from './AdminTable';
60
60
  export { AdminToolbar } from './AdminToolbar';
61
- export type { AdminToolbarProps } from './AdminToolbar';
61
+ export type { AdminToolbarProps, AdminToolbarSearchWidth, AdminToolbarSize } from './AdminToolbar';
62
62
  export { ToolbarButton } from './ToolbarButton';
63
63
  export type { ToolbarButtonProps } from './ToolbarButton';
64
64
  export { UnderlineTabs } from './UnderlineTabs';
@@ -69,8 +69,10 @@ export { RowActions } from './RowActions';
69
69
  export type { RowActionsProps, RowAction } from './RowActions';
70
70
  export { PickerRow } from './PickerRow';
71
71
  export type { PickerRowProps } from './PickerRow';
72
+ export { EntityRow, EntityList, EntityListSkeleton } from './EntityRow';
73
+ export type { EntityRowProps, EntityRowSize, EntityRowVariant, EntityRowTag, EntityRowTagTone, EntityRowLeading, EntityRowAction, EntityListProps, EntityListSkeletonProps, } from './EntityRow';
72
74
  export { PaginationSummary, pageRange } from './PaginationSummary';
73
- export type { PaginationSummaryProps, PaginationSummaryClassNames } from './PaginationSummary';
75
+ export type { PaginationSummaryProps, PaginationSummaryClassNames, PaginationSummaryRange } from './PaginationSummary';
74
76
  export { ListPanel } from './ListPanel';
75
77
  export type { ListPanelProps, ListPanelClassNames } from './ListPanel';
76
78
  export { CashTenderForm } from './CashTenderForm';
@@ -97,6 +99,12 @@ export { PaymentSubAmountInput } from './PaymentSubAmountInput';
97
99
  export type { PaymentSubAmountInputProps } from './PaymentSubAmountInput';
98
100
  export { ConfirmDialog } from './ConfirmDialog';
99
101
  export type { ConfirmDialogProps, ConfirmDialogVariant } from './ConfirmDialog';
102
+ export { InlineConfirm } from './InlineConfirm';
103
+ export type { InlineConfirmProps, InlineConfirmVariant, InlineConfirmSize } from './InlineConfirm';
104
+ export { ModalPanels, ModalPanelHeader, useModalPanel, useModalPanels } from './ModalPanels';
105
+ export type { ModalPanelsProps, ModalPanelHeaderProps, ModalPanelState, ModalPanelsController, ModalPanelEntry, } from './ModalPanels';
106
+ export { DiscardGuard, useDiscardGuard, useDiscardGuardActions, useReportUnsavedChanges } from './DiscardGuard';
107
+ export type { DiscardGuardProps, DiscardGuardController, DiscardGuardActions } from './DiscardGuard';
100
108
  export { Summary } from './Summary';
101
109
  export type { SummaryProps, SummaryLineItem, SummaryItemDetail, SummaryServiceFee, SummaryTotalRow, SummaryPostTotalRow, SummaryPrimaryAction, SummaryLabels, } from './Summary';
102
110
  export { WizardShell } from './WizardShell';
@@ -135,7 +143,7 @@ export type { RecordLayoutProps } from './RecordLayout';
135
143
  export { StatTiles } from './StatTiles';
136
144
  export type { StatTilesProps, StatTileItem } from './StatTiles';
137
145
  export { PillTabs, pillTabId, pillTabPanelId, pillTabPanelProps } from './PillTabs';
138
- export type { PillTabsProps, PillTabItem } from './PillTabs';
146
+ export type { PillTabsProps, PillTabItem, PillTabsSize } from './PillTabs';
139
147
  export { AmountList } from './AmountList';
140
148
  export type { AmountListProps, AmountListRow } from './AmountList';
141
149
  export { ActivityTimeline } from './ActivityTimeline';
@@ -143,7 +151,7 @@ export type { ActivityTimelineProps, ActivityTimelineEvent } from './ActivityTim
143
151
  export { RelatedRecordList } from './RelatedRecordList';
144
152
  export type { RelatedRecordListProps, RelatedRecordRow } from './RelatedRecordList';
145
153
  export { RecordCard } from './RecordCard';
146
- export type { RecordCardProps, RecordCardVariant, RecordCardBody } from './RecordCard';
154
+ export type { RecordCardProps, RecordCardVariant, RecordCardBody, RecordCardSurface } from './RecordCard';
147
155
  export { CardStack } from './CardStack';
148
156
  export type { CardStackProps, CardStackLayout } from './CardStack';
149
157
  export { KeyValueRows } from './KeyValueRows';
@@ -0,0 +1,7 @@
1
+ import { ReactNode } from 'react';
2
+ import { Density } from './density';
3
+ export interface DensityProviderProps {
4
+ density: Density;
5
+ children: ReactNode;
6
+ }
7
+ export declare function DensityProvider({ density, children }: DensityProviderProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * The density context and the hooks that read it. Split from
3
+ * `DensityProvider.tsx` so that file exports a component only (fast refresh).
4
+ */
5
+ export type Density = 'default' | 'touch';
6
+ /** The HeroUI control sizes a density maps onto. */
7
+ export type ControlSize = 'sm' | 'md' | 'lg';
8
+ export declare const DensityContext: import('react').Context<Density>;
9
+ /** The density of the nearest `DensityProvider`; `'default'` outside one. */
10
+ export declare function useDensity(): Density;
11
+ /**
12
+ * The HeroUI size for a control whose everyday size is `base`.
13
+ *
14
+ * A component passes the size it has always had and gets `lg` back only under
15
+ * `touch`, so a page that never mounts the provider is untouched.
16
+ */
17
+ export declare function useControlSize<TBase extends ControlSize>(base: TBase): TBase | 'lg';
@@ -1 +1,5 @@
1
1
  export { HeroUIProvider } from './HeroUIProvider';
2
+ export { DensityProvider } from './DensityProvider';
3
+ export type { DensityProviderProps } from './DensityProvider';
4
+ export { useDensity, useControlSize } from './density';
5
+ export type { Density, ControlSize } from './density';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@veevarts/design-system",
3
3
  "private": false,
4
- "version": "2.1.0-beta.13",
4
+ "version": "2.1.0-beta.15",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",
@@ -104,7 +104,7 @@
104
104
  "eslint-plugin-react-hooks": "^7.0.1",
105
105
  "eslint-plugin-react-refresh": "^0.4.24",
106
106
  "eslint-plugin-storybook": "^10.0.8",
107
- "framer-motion": "^11.15.0",
107
+ "framer-motion": "^12.43.0",
108
108
  "globals": "^16.5.0",
109
109
  "jsdom": "^27.4.0",
110
110
  "lucide-react": "^0.562.0",