@agg-build/ui 4.18.1 → 4.19.0

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 (52) hide show
  1. package/README.md +1 -0
  2. package/dist/{chunk-ZNOAKSPT.mjs → chunk-47CCGQH6.mjs} +2 -2
  3. package/dist/{chunk-2OBJ7DYT.mjs → chunk-5YHKIJ23.mjs} +21 -10
  4. package/dist/{chunk-2UPO6G3S.mjs → chunk-DWPBGMVJ.mjs} +50 -6
  5. package/dist/{chunk-VUZ72Q7H.mjs → chunk-DXASFSVL.mjs} +3 -2
  6. package/dist/{chunk-YXMDEUHP.mjs → chunk-GT3DCFIT.mjs} +494 -41
  7. package/dist/{chunk-HFL3CEWG.mjs → chunk-NSQQ62QK.mjs} +4 -4
  8. package/dist/{chunk-NRPS2D3Q.mjs → chunk-ROA5K67W.mjs} +1 -1
  9. package/dist/{chunk-JJ3VVCEP.mjs → chunk-WOCZ4TVT.mjs} +12 -8
  10. package/dist/{chunk-WIGSRHUG.mjs → chunk-XZVGHKMW.mjs} +3 -2
  11. package/dist/{event-market-GX24AP2H.mjs → event-market-2BAMDM5I.mjs} +6 -6
  12. package/dist/events.js +60 -11
  13. package/dist/events.mjs +4 -4
  14. package/dist/index.js +1148 -621
  15. package/dist/index.mjs +17 -9
  16. package/dist/modals.js +3 -2
  17. package/dist/modals.mjs +3 -3
  18. package/dist/pages.js +580 -53
  19. package/dist/pages.mjs +16 -8
  20. package/dist/primitives.js +3 -2
  21. package/dist/primitives.mjs +1 -1
  22. package/dist/styles.css +1 -1
  23. package/dist/tailwind.css +1 -1
  24. package/dist/trading.js +21 -9
  25. package/dist/trading.mjs +4 -4
  26. package/dist/types/pages/index.d.mts +1 -0
  27. package/dist/types/pages/index.d.ts +1 -0
  28. package/dist/types/pages/leaderboard/components/leaderboard-header-row.d.mts +7 -0
  29. package/dist/types/pages/leaderboard/components/leaderboard-header-row.d.ts +7 -0
  30. package/dist/types/pages/leaderboard/components/leaderboard-row.d.mts +7 -0
  31. package/dist/types/pages/leaderboard/components/leaderboard-row.d.ts +7 -0
  32. package/dist/types/pages/leaderboard/components/leaderboard-skeleton.d.mts +3 -0
  33. package/dist/types/pages/leaderboard/components/leaderboard-skeleton.d.ts +3 -0
  34. package/dist/types/pages/leaderboard/components/segmented-control.d.mts +18 -0
  35. package/dist/types/pages/leaderboard/components/segmented-control.d.ts +18 -0
  36. package/dist/types/pages/leaderboard/index.d.mts +28 -0
  37. package/dist/types/pages/leaderboard/index.d.ts +28 -0
  38. package/dist/types/pages/leaderboard/leaderboard.constants.d.mts +8 -0
  39. package/dist/types/pages/leaderboard/leaderboard.constants.d.ts +8 -0
  40. package/dist/types/pages/leaderboard/leaderboard.types.d.mts +11 -0
  41. package/dist/types/pages/leaderboard/leaderboard.types.d.ts +11 -0
  42. package/dist/types/pages/user-profile/position-view-model.d.mts +2 -4
  43. package/dist/types/pages/user-profile/position-view-model.d.ts +2 -4
  44. package/dist/types/primitives/remote-image/index.d.mts +1 -1
  45. package/dist/types/primitives/remote-image/index.d.ts +1 -1
  46. package/dist/types/primitives/remote-image/remote-image.types.d.mts +6 -0
  47. package/dist/types/primitives/remote-image/remote-image.types.d.ts +6 -0
  48. package/dist/types/shared/pnl-format.d.mts +20 -0
  49. package/dist/types/shared/pnl-format.d.ts +20 -0
  50. package/package.json +3 -3
  51. /package/dist/types/{pages/user-profile/components → shared}/default-avatar.d.mts +0 -0
  52. /package/dist/types/{pages/user-profile/components → shared}/default-avatar.d.ts +0 -0
package/dist/trading.js CHANGED
@@ -4136,7 +4136,8 @@ var RemoteImage = ({
4136
4136
  width,
4137
4137
  height,
4138
4138
  onClick,
4139
- ariaLabel
4139
+ ariaLabel,
4140
+ fallback
4140
4141
  }) => {
4141
4142
  const {
4142
4143
  general: { theme }
@@ -4193,7 +4194,7 @@ var RemoteImage = ({
4193
4194
  className: cn(placeholderClasses, classNames == null ? void 0 : classNames.placeholder),
4194
4195
  "aria-hidden": true,
4195
4196
  "aria-errormessage": "Image failed to load",
4196
- children: /* @__PURE__ */ (0, import_jsx_runtime105.jsx)(
4197
+ children: fallback != null ? fallback : /* @__PURE__ */ (0, import_jsx_runtime105.jsx)(
4197
4198
  Icon,
4198
4199
  {
4199
4200
  name: "image",
@@ -10294,7 +10295,7 @@ var resolvePlaceOrderQuoteStatus = ({
10294
10295
  selectedMarket,
10295
10296
  tradeSide = "buy"
10296
10297
  }) => {
10297
- var _a, _b, _c, _d, _e;
10298
+ var _a, _b, _c, _d, _e, _f;
10298
10299
  if (!selectedMarket) {
10299
10300
  return {
10300
10301
  tone: "warning",
@@ -10314,7 +10315,15 @@ var resolvePlaceOrderQuoteStatus = ({
10314
10315
  };
10315
10316
  }
10316
10317
  if (quoteData.status === "no_orderbooks") {
10317
- const serverError = (_a = quoteData.error) == null ? void 0 : _a.trim();
10318
+ const warnings = (_a = quoteData.warnings) != null ? _a : [];
10319
+ if (warnings.length > 0 && warnings.every((warning) => warning.reason === "hosted_cash_unavailable")) {
10320
+ return {
10321
+ tone: "warning",
10322
+ message: labels.betdexBalanceUnavailable,
10323
+ placement: "above-action"
10324
+ };
10325
+ }
10326
+ const serverError = (_b = quoteData.error) == null ? void 0 : _b.trim();
10318
10327
  return {
10319
10328
  tone: "error",
10320
10329
  message: serverError || labels.noOrderbooks,
@@ -10331,24 +10340,24 @@ var resolvePlaceOrderQuoteStatus = ({
10331
10340
  if (quoteData.status === "insufficient_input_amount") {
10332
10341
  return {
10333
10342
  tone: "error",
10334
- message: (_b = quoteData.message) != null ? _b : labels.insufficientInputAmount,
10343
+ message: (_c = quoteData.message) != null ? _c : labels.insufficientInputAmount,
10335
10344
  placement: "above-action"
10336
10345
  };
10337
10346
  }
10338
10347
  if (quoteData.status === "invalid_input") {
10339
10348
  return {
10340
10349
  tone: "error",
10341
- message: (_c = quoteData.message) != null ? _c : labels.quoteUnavailable,
10350
+ message: (_d = quoteData.message) != null ? _d : labels.quoteUnavailable,
10342
10351
  placement: "above-action"
10343
10352
  };
10344
10353
  }
10345
10354
  if (quoteData.status === "insufficient_position") {
10346
- const total = (_d = quoteData.positionAvailability) == null ? void 0 : _d.totalSellableShares;
10355
+ const total = (_e = quoteData.positionAvailability) == null ? void 0 : _e.totalSellableShares;
10347
10356
  const message = total != null ? labels.insufficientPosition(total) : labels.insufficientPositionGeneric;
10348
10357
  return { tone: "error", message, placement: "above-action" };
10349
10358
  }
10350
10359
  if (quoteData.status === "insufficient_depth") {
10351
- const serverError = (_e = quoteData.error) == null ? void 0 : _e.trim();
10360
+ const serverError = (_f = quoteData.error) == null ? void 0 : _f.trim();
10352
10361
  return {
10353
10362
  tone: "error",
10354
10363
  message: tradeSide === "sell" ? serverError || labels.insufficientSellDepth : serverError || labels.insufficientLiquidity,
@@ -12936,6 +12945,7 @@ var renderCardHeader = ({
12936
12945
  headerSubtitle,
12937
12946
  headerImage,
12938
12947
  headerTitle,
12948
+ headerVenue,
12939
12949
  onClose
12940
12950
  }) => {
12941
12951
  if (!headerTitle) return null;
@@ -12946,6 +12956,7 @@ var renderCardHeader = ({
12946
12956
  {
12947
12957
  src: headerImage,
12948
12958
  alt: "",
12959
+ fallback: headerVenue ? /* @__PURE__ */ (0, import_jsx_runtime152.jsx)(VenueLogo, { venue: headerVenue, size: "large" }) : void 0,
12949
12960
  className: "agg-order-market-image h-12 w-12 shrink-0 overflow-hidden rounded-agg-lg object-cover"
12950
12961
  }
12951
12962
  ),
@@ -13272,7 +13283,7 @@ var PlaceOrder = ({
13272
13283
  showResolvingState = false,
13273
13284
  midpointsResult
13274
13285
  }) => {
13275
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, __, _$, _aa, _ba, _ca, _da, _ea, _fa, _ga, _ha;
13286
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, __, _$, _aa, _ba, _ca, _da, _ea, _fa, _ga, _ha, _ia;
13276
13287
  const {
13277
13288
  enableDebug: isExecutionDebugEnabled,
13278
13289
  features: { enableAnimations, showFeesBreakdown, showLimitOrders: limitOrdersFeature },
@@ -15558,6 +15569,7 @@ var PlaceOrder = ({
15558
15569
  headerSubtitle,
15559
15570
  headerImage,
15560
15571
  headerTitle,
15572
+ headerVenue: (_ia = scopedSelectedMarket == null ? void 0 : scopedSelectedMarket.venue) != null ? _ia : scopedSelectedEvent == null ? void 0 : scopedSelectedEvent.venue,
15561
15573
  onClose
15562
15574
  }),
15563
15575
  /* @__PURE__ */ (0, import_jsx_runtime152.jsxs)("div", { className: cn("agg-order-panel-content flex flex-col gap-6", classNames == null ? void 0 : classNames.content), children: [
package/dist/trading.mjs CHANGED
@@ -14,7 +14,7 @@ import {
14
14
  useClaimWinnings,
15
15
  useResolvedMarketClaim,
16
16
  venueRequiresSharedKyc
17
- } from "./chunk-2OBJ7DYT.mjs";
17
+ } from "./chunk-5YHKIJ23.mjs";
18
18
  import {
19
19
  SETTLEMENT_SECTION_ID,
20
20
  Settlement,
@@ -32,9 +32,9 @@ import {
32
32
  prepareSettlementDifferences,
33
33
  resolveDifferenceIconClassName,
34
34
  useEventTradingContext
35
- } from "./chunk-JJ3VVCEP.mjs";
36
- import "./chunk-NRPS2D3Q.mjs";
37
- import "./chunk-WIGSRHUG.mjs";
35
+ } from "./chunk-WOCZ4TVT.mjs";
36
+ import "./chunk-ROA5K67W.mjs";
37
+ import "./chunk-XZVGHKMW.mjs";
38
38
  export {
39
39
  FundKalshiModal,
40
40
  PlaceOrder,
@@ -1,4 +1,5 @@
1
1
  export * from "./home";
2
2
  export * from "./event-market";
3
3
  export * from "./user-profile";
4
+ export * from "./leaderboard";
4
5
  export { DEPOSIT_MODAL_OPEN_EVENT, WITHDRAW_MODAL_OPEN_EVENT, requestAggDepositModalOpen, requestAggWithdrawModalOpen, } from "../shared/deposit-modal-events";
@@ -1,4 +1,5 @@
1
1
  export * from "./home";
2
2
  export * from "./event-market";
3
3
  export * from "./user-profile";
4
+ export * from "./leaderboard";
4
5
  export { DEPOSIT_MODAL_OPEN_EVENT, WITHDRAW_MODAL_OPEN_EVENT, requestAggDepositModalOpen, requestAggWithdrawModalOpen, } from "../shared/deposit-modal-events";
@@ -0,0 +1,7 @@
1
+ import type { LeaderboardMetric } from "../leaderboard.types";
2
+ export interface LeaderboardHeaderRowProps {
3
+ metric: LeaderboardMetric;
4
+ onMetricChange: (metric: LeaderboardMetric) => void;
5
+ }
6
+ /** Column captions; hidden on phones where each cell carries its own caption. */
7
+ export declare function LeaderboardHeaderRow({ metric, onMetricChange, }: LeaderboardHeaderRowProps): JSX.Element;
@@ -0,0 +1,7 @@
1
+ import type { LeaderboardMetric } from "../leaderboard.types";
2
+ export interface LeaderboardHeaderRowProps {
3
+ metric: LeaderboardMetric;
4
+ onMetricChange: (metric: LeaderboardMetric) => void;
5
+ }
6
+ /** Column captions; hidden on phones where each cell carries its own caption. */
7
+ export declare function LeaderboardHeaderRow({ metric, onMetricChange, }: LeaderboardHeaderRowProps): JSX.Element;
@@ -0,0 +1,7 @@
1
+ import type { LeaderboardRow } from "../leaderboard.types";
2
+ export interface LeaderboardRowViewProps {
3
+ row: LeaderboardRow;
4
+ isCurrentUser: boolean;
5
+ className?: string;
6
+ }
7
+ export declare function LeaderboardRowView({ row, isCurrentUser, className, }: LeaderboardRowViewProps): JSX.Element;
@@ -0,0 +1,7 @@
1
+ import type { LeaderboardRow } from "../leaderboard.types";
2
+ export interface LeaderboardRowViewProps {
3
+ row: LeaderboardRow;
4
+ isCurrentUser: boolean;
5
+ className?: string;
6
+ }
7
+ export declare function LeaderboardRowView({ row, isCurrentUser, className, }: LeaderboardRowViewProps): JSX.Element;
@@ -0,0 +1,3 @@
1
+ export declare function LeaderboardSkeleton({ rows }: {
2
+ rows?: number;
3
+ }): JSX.Element;
@@ -0,0 +1,3 @@
1
+ export declare function LeaderboardSkeleton({ rows }: {
2
+ rows?: number;
3
+ }): JSX.Element;
@@ -0,0 +1,18 @@
1
+ export interface SegmentedControlItem<T extends string> {
2
+ value: T;
3
+ label: string;
4
+ }
5
+ export interface SegmentedControlProps<T extends string> {
6
+ /** Accessible group name, e.g. "Period". */
7
+ label: string;
8
+ value: T;
9
+ onChange: (value: T) => void;
10
+ items: SegmentedControlItem<T>[];
11
+ className?: string;
12
+ itemClassName?: string;
13
+ }
14
+ /**
15
+ * Bordered segmented toggle — the same shell as the profile page's position
16
+ * filters (`rounded-agg-sm border`, 1px dividers, pressed item filled).
17
+ */
18
+ export declare function SegmentedControl<T extends string>({ label, value, onChange, items, className, itemClassName, }: SegmentedControlProps<T>): JSX.Element;
@@ -0,0 +1,18 @@
1
+ export interface SegmentedControlItem<T extends string> {
2
+ value: T;
3
+ label: string;
4
+ }
5
+ export interface SegmentedControlProps<T extends string> {
6
+ /** Accessible group name, e.g. "Period". */
7
+ label: string;
8
+ value: T;
9
+ onChange: (value: T) => void;
10
+ items: SegmentedControlItem<T>[];
11
+ className?: string;
12
+ itemClassName?: string;
13
+ }
14
+ /**
15
+ * Bordered segmented toggle — the same shell as the profile page's position
16
+ * filters (`rounded-agg-sm border`, 1px dividers, pressed item filled).
17
+ */
18
+ export declare function SegmentedControl<T extends string>({ label, value, onChange, items, className, itemClassName, }: SegmentedControlProps<T>): JSX.Element;
@@ -0,0 +1,28 @@
1
+ import type { LeaderboardClassNames, LeaderboardMetric, LeaderboardPeriod, LeaderboardRow } from "./leaderboard.types";
2
+ export type { LeaderboardClassNames, LeaderboardMetric, LeaderboardPeriod, LeaderboardRow, } from "./leaderboard.types";
3
+ export { LEADERBOARD_DEFAULT_METRIC, LEADERBOARD_DEFAULT_PERIOD, LEADERBOARD_METRICS, } from "./leaderboard.constants";
4
+ export interface LeaderboardPageProps {
5
+ /** Rows to render. When absent the page fetches via `useLeaderboard`. */
6
+ rows?: LeaderboardRow[];
7
+ isLoading?: boolean;
8
+ error?: unknown;
9
+ hasNextPage?: boolean;
10
+ isLoadingMore?: boolean;
11
+ onLoadMore?: () => void;
12
+ /** Controlled period; uncontrolled state is used when absent. */
13
+ period?: LeaderboardPeriod;
14
+ onPeriodChange?: (period: LeaderboardPeriod) => void;
15
+ metric?: LeaderboardMetric;
16
+ onMetricChange?: (metric: LeaderboardMetric) => void;
17
+ /** Row to mark as "you". Defaults to the signed-in user. */
18
+ currentUserId?: string;
19
+ /** Shown in the subtitle as "Top traders on {appName}". */
20
+ appName?: string;
21
+ onError?: (error: Error) => void;
22
+ className?: string;
23
+ classNames?: LeaderboardClassNames;
24
+ }
25
+ export declare function LeaderboardPage(props: LeaderboardPageProps): JSX.Element;
26
+ export declare namespace LeaderboardPage {
27
+ var displayName: string;
28
+ }
@@ -0,0 +1,28 @@
1
+ import type { LeaderboardClassNames, LeaderboardMetric, LeaderboardPeriod, LeaderboardRow } from "./leaderboard.types";
2
+ export type { LeaderboardClassNames, LeaderboardMetric, LeaderboardPeriod, LeaderboardRow, } from "./leaderboard.types";
3
+ export { LEADERBOARD_DEFAULT_METRIC, LEADERBOARD_DEFAULT_PERIOD, LEADERBOARD_METRICS, } from "./leaderboard.constants";
4
+ export interface LeaderboardPageProps {
5
+ /** Rows to render. When absent the page fetches via `useLeaderboard`. */
6
+ rows?: LeaderboardRow[];
7
+ isLoading?: boolean;
8
+ error?: unknown;
9
+ hasNextPage?: boolean;
10
+ isLoadingMore?: boolean;
11
+ onLoadMore?: () => void;
12
+ /** Controlled period; uncontrolled state is used when absent. */
13
+ period?: LeaderboardPeriod;
14
+ onPeriodChange?: (period: LeaderboardPeriod) => void;
15
+ metric?: LeaderboardMetric;
16
+ onMetricChange?: (metric: LeaderboardMetric) => void;
17
+ /** Row to mark as "you". Defaults to the signed-in user. */
18
+ currentUserId?: string;
19
+ /** Shown in the subtitle as "Top traders on {appName}". */
20
+ appName?: string;
21
+ onError?: (error: Error) => void;
22
+ className?: string;
23
+ classNames?: LeaderboardClassNames;
24
+ }
25
+ export declare function LeaderboardPage(props: LeaderboardPageProps): JSX.Element;
26
+ export declare namespace LeaderboardPage {
27
+ var displayName: string;
28
+ }
@@ -0,0 +1,8 @@
1
+ import type { LeaderboardMetric, LeaderboardPeriod } from "./leaderboard.types";
2
+ export declare const LEADERBOARD_DEFAULT_PERIOD: LeaderboardPeriod;
3
+ export declare const LEADERBOARD_DEFAULT_METRIC: LeaderboardMetric;
4
+ export declare const LEADERBOARD_METRICS: readonly LeaderboardMetric[];
5
+ /** Ranks that get the emphasised chip. */
6
+ export declare const LEADERBOARD_TOP_RANKS = 3;
7
+ /** Shared grid template: rank | identity | trades | volume | P&L. */
8
+ export declare const LEADERBOARD_GRID_CLASS = "grid grid-cols-[36px_minmax(0,1fr)] grid-rows-[auto_auto] gap-x-3 gap-y-2 sm:grid-cols-[48px_minmax(0,1fr)_88px_128px_128px] sm:grid-rows-1 sm:gap-x-3 sm:gap-y-0";
@@ -0,0 +1,8 @@
1
+ import type { LeaderboardMetric, LeaderboardPeriod } from "./leaderboard.types";
2
+ export declare const LEADERBOARD_DEFAULT_PERIOD: LeaderboardPeriod;
3
+ export declare const LEADERBOARD_DEFAULT_METRIC: LeaderboardMetric;
4
+ export declare const LEADERBOARD_METRICS: readonly LeaderboardMetric[];
5
+ /** Ranks that get the emphasised chip. */
6
+ export declare const LEADERBOARD_TOP_RANKS = 3;
7
+ /** Shared grid template: rank | identity | trades | volume | P&L. */
8
+ export declare const LEADERBOARD_GRID_CLASS = "grid grid-cols-[36px_minmax(0,1fr)] grid-rows-[auto_auto] gap-x-3 gap-y-2 sm:grid-cols-[48px_minmax(0,1fr)_88px_128px_128px] sm:grid-rows-1 sm:gap-x-3 sm:gap-y-0";
@@ -0,0 +1,11 @@
1
+ import type { LeaderboardMetric, LeaderboardRow } from "@agg-build/sdk";
2
+ import type { LeaderboardPeriod } from "@agg-build/hooks";
3
+ export type { LeaderboardMetric, LeaderboardRow, LeaderboardPeriod };
4
+ export interface LeaderboardClassNames {
5
+ root?: string;
6
+ header?: string;
7
+ toolbar?: string;
8
+ list?: string;
9
+ row?: string;
10
+ footer?: string;
11
+ }
@@ -0,0 +1,11 @@
1
+ import type { LeaderboardMetric, LeaderboardRow } from "@agg-build/sdk";
2
+ import type { LeaderboardPeriod } from "@agg-build/hooks";
3
+ export type { LeaderboardMetric, LeaderboardRow, LeaderboardPeriod };
4
+ export interface LeaderboardClassNames {
5
+ root?: string;
6
+ header?: string;
7
+ toolbar?: string;
8
+ list?: string;
9
+ row?: string;
10
+ footer?: string;
11
+ }
@@ -1,7 +1,8 @@
1
+ import { formatCurrency, formatSignedCurrency, getPositionTone, type PositionTone } from "../../shared/pnl-format";
1
2
  import type { UserProfilePosition } from "./user-profile.types";
3
+ export { formatCurrency, formatSignedCurrency, getPositionTone, type PositionTone };
2
4
  export type PositionStatus = "open" | "won_unclaimed" | "won_claimed" | "lost" | "sold";
3
5
  export type PositionBucket = "active" | "closed";
4
- export type PositionTone = "positive" | "negative" | "neutral";
5
6
  export type PositionValueDisplay = {
6
7
  primaryLabel: string;
7
8
  deltaLabel: string;
@@ -43,8 +44,6 @@ export type PositionViewModelFormatters = {
43
44
  /** Receives a dollar amount. */
44
45
  formatCurrency?: (value: number) => string;
45
46
  };
46
- export declare const formatCurrency: (value: number | null | undefined, formatCurrencyOverride?: (value: number) => string) => string;
47
- export declare const formatSignedCurrency: (value: number | null | undefined, formatCurrencyOverride?: (value: number) => string) => string;
48
47
  export declare const formatPriceCents: (value: number | null | undefined, formatPrice?: (value: number) => string) => string;
49
48
  export declare const formatSignedPercent: (value: number | null | undefined) => string;
50
49
  export declare const resolvePositionStatus: (position: UserProfilePosition) => PositionStatus;
@@ -61,5 +60,4 @@ export declare const getPnlValue: (position: UserProfilePosition, value: number
61
60
  export declare const getPnlPercent: (position: UserProfilePosition, pnlValue: number | null) => number | null;
62
61
  export declare const getFinalPnlValue: (position: UserProfilePosition, value: number | null) => number | null;
63
62
  export declare const getFinalPnlPercent: (position: UserProfilePosition, pnlValue: number | null) => number | null;
64
- export declare const getPositionTone: (value: number | null | undefined) => PositionTone;
65
63
  export declare const toPositionRowViewModel: (position: UserProfilePosition, labels?: PositionViewModelLabels, formatters?: PositionViewModelFormatters) => PositionRowViewModel;
@@ -1,7 +1,8 @@
1
+ import { formatCurrency, formatSignedCurrency, getPositionTone, type PositionTone } from "../../shared/pnl-format";
1
2
  import type { UserProfilePosition } from "./user-profile.types";
3
+ export { formatCurrency, formatSignedCurrency, getPositionTone, type PositionTone };
2
4
  export type PositionStatus = "open" | "won_unclaimed" | "won_claimed" | "lost" | "sold";
3
5
  export type PositionBucket = "active" | "closed";
4
- export type PositionTone = "positive" | "negative" | "neutral";
5
6
  export type PositionValueDisplay = {
6
7
  primaryLabel: string;
7
8
  deltaLabel: string;
@@ -43,8 +44,6 @@ export type PositionViewModelFormatters = {
43
44
  /** Receives a dollar amount. */
44
45
  formatCurrency?: (value: number) => string;
45
46
  };
46
- export declare const formatCurrency: (value: number | null | undefined, formatCurrencyOverride?: (value: number) => string) => string;
47
- export declare const formatSignedCurrency: (value: number | null | undefined, formatCurrencyOverride?: (value: number) => string) => string;
48
47
  export declare const formatPriceCents: (value: number | null | undefined, formatPrice?: (value: number) => string) => string;
49
48
  export declare const formatSignedPercent: (value: number | null | undefined) => string;
50
49
  export declare const resolvePositionStatus: (position: UserProfilePosition) => PositionStatus;
@@ -61,5 +60,4 @@ export declare const getPnlValue: (position: UserProfilePosition, value: number
61
60
  export declare const getPnlPercent: (position: UserProfilePosition, pnlValue: number | null) => number | null;
62
61
  export declare const getFinalPnlValue: (position: UserProfilePosition, value: number | null) => number | null;
63
62
  export declare const getFinalPnlPercent: (position: UserProfilePosition, pnlValue: number | null) => number | null;
64
- export declare const getPositionTone: (value: number | null | undefined) => PositionTone;
65
63
  export declare const toPositionRowViewModel: (position: UserProfilePosition, labels?: PositionViewModelLabels, formatters?: PositionViewModelFormatters) => PositionRowViewModel;
@@ -2,6 +2,6 @@ import type { RemoteImageProps, RemoteImageStatus } from "./remote-image.types";
2
2
  export type { RemoteImageProps, RemoteImageStatus };
3
3
  /** Renders a remote image with loading skeleton and error placeholder fallbacks. */
4
4
  export declare const RemoteImage: {
5
- ({ src, retinaSrc, alt, title, className, classNames, width, height, onClick, ariaLabel, }: RemoteImageProps): JSX.Element;
5
+ ({ src, retinaSrc, alt, title, className, classNames, width, height, onClick, ariaLabel, fallback, }: RemoteImageProps): JSX.Element;
6
6
  displayName: string;
7
7
  };
@@ -2,6 +2,6 @@ import type { RemoteImageProps, RemoteImageStatus } from "./remote-image.types";
2
2
  export type { RemoteImageProps, RemoteImageStatus };
3
3
  /** Renders a remote image with loading skeleton and error placeholder fallbacks. */
4
4
  export declare const RemoteImage: {
5
- ({ src, retinaSrc, alt, title, className, classNames, width, height, onClick, ariaLabel, }: RemoteImageProps): JSX.Element;
5
+ ({ src, retinaSrc, alt, title, className, classNames, width, height, onClick, ariaLabel, fallback, }: RemoteImageProps): JSX.Element;
6
6
  displayName: string;
7
7
  };
@@ -31,4 +31,10 @@ export type RemoteImageProps = {
31
31
  onClick?: () => void;
32
32
  /** Accessible label applied when the image acts like a control. */
33
33
  ariaLabel?: string;
34
+ /**
35
+ * Rendered instead of the generic image icon when there is no usable image
36
+ * (missing source or load failure), e.g. the owning venue's mark. The
37
+ * caller must pass real existing artwork, never an invented subject image.
38
+ */
39
+ fallback?: React.ReactNode;
34
40
  };
@@ -31,4 +31,10 @@ export type RemoteImageProps = {
31
31
  onClick?: () => void;
32
32
  /** Accessible label applied when the image acts like a control. */
33
33
  ariaLabel?: string;
34
+ /**
35
+ * Rendered instead of the generic image icon when there is no usable image
36
+ * (missing source or load failure), e.g. the owning venue's mark. The
37
+ * caller must pass real existing artwork, never an invented subject image.
38
+ */
39
+ fallback?: React.ReactNode;
34
40
  };
@@ -0,0 +1,20 @@
1
+ export type PositionTone = "positive" | "negative" | "neutral";
2
+ export declare const MISSING_VALUE_LABEL = "\u2014";
3
+ export declare const isFiniteNumber: (value: number | null | undefined) => value is number;
4
+ export declare const formatCurrency: (value: number | null | undefined, formatCurrencyOverride?: (value: number) => string) => string;
5
+ /** Magnitudes below this render as "<$0.01" instead of a misleading "$0.00" when `markNegligible` is set. */
6
+ export declare const NEGLIGIBLE_CURRENCY_THRESHOLD = 0.005;
7
+ export interface SignedCurrencyOptions {
8
+ /**
9
+ * Render a non-zero value that would round to $0.00 as `+<$0.01` / `-<$0.01`
10
+ * so dust (fractional-share settlements, rounding residue) reads as
11
+ * negligible rather than as exactly zero. Exact 0 still renders `$0.00`.
12
+ */
13
+ markNegligible?: boolean;
14
+ }
15
+ export declare const formatSignedCurrency: (value: number | null | undefined, formatCurrencyOverride?: (value: number) => string, options?: SignedCurrencyOptions) => string;
16
+ /** Unsigned counterpart for volume: a positive value below half a cent reads `<$0.01`. */
17
+ export declare const formatCurrencyMarkingNegligible: (value: number | null | undefined, formatCurrencyOverride?: (value: number) => string) => string;
18
+ export declare const getPositionTone: (value: number | null | undefined) => PositionTone;
19
+ /** Token class for a P&L tone; mirrors position-row.tsx's mapping. */
20
+ export declare const toneClassName: (tone: PositionTone) => string;
@@ -0,0 +1,20 @@
1
+ export type PositionTone = "positive" | "negative" | "neutral";
2
+ export declare const MISSING_VALUE_LABEL = "\u2014";
3
+ export declare const isFiniteNumber: (value: number | null | undefined) => value is number;
4
+ export declare const formatCurrency: (value: number | null | undefined, formatCurrencyOverride?: (value: number) => string) => string;
5
+ /** Magnitudes below this render as "<$0.01" instead of a misleading "$0.00" when `markNegligible` is set. */
6
+ export declare const NEGLIGIBLE_CURRENCY_THRESHOLD = 0.005;
7
+ export interface SignedCurrencyOptions {
8
+ /**
9
+ * Render a non-zero value that would round to $0.00 as `+<$0.01` / `-<$0.01`
10
+ * so dust (fractional-share settlements, rounding residue) reads as
11
+ * negligible rather than as exactly zero. Exact 0 still renders `$0.00`.
12
+ */
13
+ markNegligible?: boolean;
14
+ }
15
+ export declare const formatSignedCurrency: (value: number | null | undefined, formatCurrencyOverride?: (value: number) => string, options?: SignedCurrencyOptions) => string;
16
+ /** Unsigned counterpart for volume: a positive value below half a cent reads `<$0.01`. */
17
+ export declare const formatCurrencyMarkingNegligible: (value: number | null | undefined, formatCurrencyOverride?: (value: number) => string) => string;
18
+ export declare const getPositionTone: (value: number | null | undefined) => PositionTone;
19
+ /** Token class for a P&L tone; mirrors position-row.tsx's mapping. */
20
+ export declare const toneClassName: (tone: PositionTone) => string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agg-build/ui",
3
- "version": "4.18.1",
3
+ "version": "4.19.0",
4
4
  "description": "Pre-built React component library for the AGG prediction market aggregator. Tailwind-based, themeable, with primitives, event surfaces, trading flows, full pages, and modals.",
5
5
  "sideEffects": false,
6
6
  "license": "MIT",
@@ -100,8 +100,8 @@
100
100
  "liveline": "^0.0.7",
101
101
  "react": "^18.0.0 || ^19.0.0",
102
102
  "react-dom": "^18.0.0 || ^19.0.0",
103
- "@agg-build/hooks": "^4.18.0",
104
- "@agg-build/sdk": "^4.18.0"
103
+ "@agg-build/hooks": "^4.19.0",
104
+ "@agg-build/sdk": "^4.19.0"
105
105
  },
106
106
  "dependencies": {
107
107
  "@number-flow/react": "^0.6.0",