@agg-build/ui 2.4.2 → 2.4.5

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 (38) hide show
  1. package/dist/{chunk-EOCHFD2U.mjs → chunk-CXSIXL7M.mjs} +38 -36
  2. package/dist/{chunk-3FLLEJFM.mjs → chunk-GWRFSQQK.mjs} +75 -9
  3. package/dist/{chunk-MDO3NMXP.mjs → chunk-I4X5UNCT.mjs} +343 -193
  4. package/dist/{chunk-G5BXCT5Y.mjs → chunk-JVRTJQPZ.mjs} +1 -1
  5. package/dist/{chunk-GUYFQP7L.mjs → chunk-P5CVJQPW.mjs} +288 -291
  6. package/dist/{chunk-2ET5CXOU.mjs → chunk-PTNFXXOV.mjs} +53 -21
  7. package/dist/{chunk-G5Y45GIA.mjs → chunk-UH3DUTMG.mjs} +352 -43
  8. package/dist/events.js +679 -194
  9. package/dist/events.mjs +3 -3
  10. package/dist/index.js +1097 -547
  11. package/dist/index.mjs +13 -7
  12. package/dist/modals.js +333 -297
  13. package/dist/modals.mjs +3 -3
  14. package/dist/pages.js +809 -262
  15. package/dist/pages.mjs +6 -6
  16. package/dist/primitives.js +53 -21
  17. package/dist/primitives.mjs +1 -1
  18. package/dist/styles.css +1 -1
  19. package/dist/tailwind.css +1 -1
  20. package/dist/trading.js +3265 -2765
  21. package/dist/trading.mjs +10 -4
  22. package/dist/types/events/item-details/event-list-item-details.constants.d.mts +1 -1
  23. package/dist/types/events/item-details/event-list-item-details.constants.d.ts +1 -1
  24. package/dist/types/events/item-details/settlement-summary.d.mts +3 -1
  25. package/dist/types/events/item-details/settlement-summary.d.ts +3 -1
  26. package/dist/types/onboarding/index.d.mts +1 -1
  27. package/dist/types/onboarding/index.d.ts +1 -1
  28. package/dist/types/onboarding/steps/connect-accounts.d.mts +1 -1
  29. package/dist/types/onboarding/steps/connect-accounts.d.ts +1 -1
  30. package/dist/types/primitives/icon/icon.constants.d.mts +1 -0
  31. package/dist/types/primitives/icon/icon.constants.d.ts +1 -0
  32. package/dist/types/shared/use-horizontal-scroll-state.d.mts +3 -0
  33. package/dist/types/shared/use-horizontal-scroll-state.d.ts +3 -0
  34. package/dist/types/trading/place-order/index.place-order.utils.d.mts +1 -0
  35. package/dist/types/trading/place-order/index.place-order.utils.d.ts +1 -0
  36. package/dist/types/trading/settlement/index.d.mts +19 -1
  37. package/dist/types/trading/settlement/index.d.ts +19 -1
  38. package/package.json +2 -2
@@ -1643,6 +1643,12 @@ var iconSizeClasses = {
1643
1643
  medium: "h-6 w-6",
1644
1644
  large: "h-8 w-8"
1645
1645
  };
1646
+ var iconSizePixels = {
1647
+ xs: 12,
1648
+ small: 16,
1649
+ medium: 24,
1650
+ large: 32
1651
+ };
1646
1652
 
1647
1653
  // src/primitives/search/search-empty-icon.tsx
1648
1654
  import { jsx as jsx40, jsxs as jsxs40 } from "react/jsx-runtime";
@@ -3244,6 +3250,8 @@ var Icon = (_a) => {
3244
3250
  __spreadValues({
3245
3251
  color,
3246
3252
  className: cn("group/agg-icon", resolvedClassName),
3253
+ width: iconSizePixels[size],
3254
+ height: iconSizePixels[size],
3247
3255
  style: resolvedStyle
3248
3256
  }, props)
3249
3257
  );
@@ -5575,7 +5583,7 @@ EventListSkeletonView.displayName = "EventListSkeletonView";
5575
5583
  import { useLabels as useLabels5 } from "@agg-build/hooks";
5576
5584
 
5577
5585
  // src/events/item-details/event-list-item-details.constants.ts
5578
- var detailsBaseCardClassName = "w-full gap-6 p-5 md:gap-8";
5586
+ var detailsBaseCardClassName = "w-full gap-6 p-4 md:p-5 md:gap-8";
5579
5587
 
5580
5588
  // src/primitives/skeleton/views/event-list-item-details-skeleton-view.tsx
5581
5589
  import { jsx as jsx101, jsxs as jsxs98 } from "react/jsx-runtime";
@@ -5886,17 +5894,10 @@ var SettlementSkeletonView = ({
5886
5894
  children: [
5887
5895
  /* @__PURE__ */ jsxs102("div", { className: "flex w-full items-center justify-between gap-4", children: [
5888
5896
  /* @__PURE__ */ jsx105(SkeletonBlock, { className: "h-4 w-[81px] rounded-agg-sm" }),
5889
- /* @__PURE__ */ jsx105(SkeletonBlock, { className: "h-5 w-full max-w-[240px] rounded-agg-sm" })
5890
- ] }),
5891
- /* @__PURE__ */ jsxs102("div", { className: "flex w-full flex-col gap-3", children: [
5892
- /* @__PURE__ */ jsx105(SkeletonBlock, { className: "h-5 w-[200px] rounded-agg-sm" }),
5893
- /* @__PURE__ */ jsxs102("div", { className: "flex flex-col gap-2", children: [
5894
- /* @__PURE__ */ jsx105(SkeletonBlock, { className: "h-4 w-full max-w-[320px] rounded-agg-sm" }),
5895
- /* @__PURE__ */ jsx105(SkeletonBlock, { className: "h-4 w-full max-w-[280px] rounded-agg-sm" })
5896
- ] })
5897
+ /* @__PURE__ */ jsx105(SkeletonBlock, { className: "h-5 w-[240px] max-w-[60%] rounded-agg-sm" })
5897
5898
  ] }),
5898
- /* @__PURE__ */ jsx105("div", { className: "h-px w-full bg-agg-separator" }),
5899
- /* @__PURE__ */ jsxs102("div", { className: "flex w-full flex-col gap-3", children: [
5899
+ /* @__PURE__ */ jsx105(SkeletonBlock, { className: "h-5 w-[200px] rounded-agg-sm" }),
5900
+ /* @__PURE__ */ jsxs102("div", { className: "flex w-full flex-col gap-4", children: [
5900
5901
  /* @__PURE__ */ jsxs102("div", { className: "flex items-center gap-2", children: [
5901
5902
  /* @__PURE__ */ jsx105(SkeletonBlock, { className: "size-4 rounded-agg-sm" }),
5902
5903
  /* @__PURE__ */ jsx105(SkeletonBlock, { className: "h-5 w-[100px] rounded-agg-sm" })
@@ -8853,14 +8854,23 @@ import { useCallback as useCallback6, useEffect as useEffect9, useLayoutEffect a
8853
8854
  import { useCallback as useCallback5, useEffect as useEffect8, useRef as useRef8, useState as useState9 } from "react";
8854
8855
  var useHorizontalScrollState = () => {
8855
8856
  const containerRef = useRef8(null);
8857
+ const [hasOverflow, setHasOverflow] = useState9(false);
8858
+ const [isAtStart, setIsAtStart] = useState9(true);
8859
+ const [isAtEnd, setIsAtEnd] = useState9(true);
8856
8860
  const [canScrollLeft, setCanScrollLeft] = useState9(false);
8857
8861
  const [canScrollRight, setCanScrollRight] = useState9(false);
8858
8862
  const update = useCallback5(() => {
8859
8863
  const el = containerRef.current;
8860
8864
  if (!el) return;
8861
- const maxScroll = el.scrollWidth - el.clientWidth;
8862
- setCanScrollLeft(el.scrollLeft > 4);
8863
- setCanScrollRight(maxScroll - el.scrollLeft > 4);
8865
+ const epsilon = 2;
8866
+ const nextHasOverflow = el.scrollWidth > el.clientWidth + epsilon;
8867
+ const nextIsAtStart = el.scrollLeft <= epsilon;
8868
+ const nextIsAtEnd = el.scrollLeft + el.clientWidth >= el.scrollWidth - epsilon;
8869
+ setHasOverflow(nextHasOverflow);
8870
+ setIsAtStart(nextIsAtStart);
8871
+ setIsAtEnd(nextIsAtEnd);
8872
+ setCanScrollLeft(nextHasOverflow && !nextIsAtStart);
8873
+ setCanScrollRight(nextHasOverflow && !nextIsAtEnd);
8864
8874
  }, []);
8865
8875
  useEffect8(() => {
8866
8876
  const el = containerRef.current;
@@ -8876,7 +8886,15 @@ var useHorizontalScrollState = () => {
8876
8886
  ro.observe(el);
8877
8887
  return () => ro.disconnect();
8878
8888
  }, [update]);
8879
- return { containerRef, canScrollLeft, canScrollRight, update };
8889
+ return {
8890
+ containerRef,
8891
+ hasOverflow,
8892
+ isAtStart,
8893
+ isAtEnd,
8894
+ canScrollLeft,
8895
+ canScrollRight,
8896
+ update
8897
+ };
8880
8898
  };
8881
8899
 
8882
8900
  // src/primitives/tabs/tabs.constants.ts
@@ -8971,6 +8989,9 @@ var Tabs = ({
8971
8989
  });
8972
8990
  const {
8973
8991
  containerRef: tabListRef,
8992
+ hasOverflow,
8993
+ isAtStart,
8994
+ isAtEnd,
8974
8995
  canScrollLeft,
8975
8996
  canScrollRight,
8976
8997
  update: updateScrollState
@@ -9059,7 +9080,7 @@ var Tabs = ({
9059
9080
  "overflow-x-auto [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
9060
9081
  getMotionClassName(enableAnimations, "scroll-smooth")
9061
9082
  ) : "overflow-x-auto",
9062
- isBarVariant ? "items-start rounded-agg-lg border border-agg-separator p-1.5" : "h-15 border-b border-agg-separator -mb-[1px]",
9083
+ isBarVariant ? "items-start rounded-agg-lg border border-agg-separator p-1.5" : "h-14 md:h-15 border-b border-agg-separator -mb-[1px]",
9063
9084
  shouldUseOverflowScroll && "select-none",
9064
9085
  shouldUseOverflowScroll && !isBarVariant && "snap-x snap-mandatory",
9065
9086
  shouldUseOverflowScroll && (isDraggingTabs ? "cursor-grabbing" : "cursor-grab")
@@ -9217,7 +9238,10 @@ var Tabs = ({
9217
9238
  left: Math.max(0, nextScrollLeft),
9218
9239
  behavior: getScrollBehavior(enableAnimations)
9219
9240
  });
9220
- }, [enableAnimations, renderedItems, shouldUseOverflowScroll, value]);
9241
+ requestAnimationFrame(() => {
9242
+ updateScrollState();
9243
+ });
9244
+ }, [enableAnimations, renderedItems, shouldUseOverflowScroll, updateScrollState, value]);
9221
9245
  if (shouldUseOverflowSelect) {
9222
9246
  return /* @__PURE__ */ jsx128("div", { className: cn("group/agg-tabs w-full", className, classNames == null ? void 0 : classNames.root), children: /* @__PURE__ */ jsx128(
9223
9247
  Select,
@@ -9256,6 +9280,13 @@ var Tabs = ({
9256
9280
  onPointerUp: handleEndTabListDrag,
9257
9281
  onWheel: handleTabListWheel,
9258
9282
  children: [
9283
+ shouldUseOverflowScroll && !isBarVariant && hasOverflow ? /* @__PURE__ */ jsx128(
9284
+ "span",
9285
+ {
9286
+ "aria-hidden": true,
9287
+ className: "agg-tab-scroll-start-spacer h-full w-4 shrink-0 snap-start"
9288
+ }
9289
+ ) : null,
9259
9290
  renderedItems.map((item, index) => {
9260
9291
  var _a;
9261
9292
  const isActive = item.value === value;
@@ -9290,6 +9321,7 @@ var Tabs = ({
9290
9321
  isDisabled: !!item.disabled,
9291
9322
  size
9292
9323
  }),
9324
+ !isBarVariant && (size === "s" ? "px-3 md:px-4" : "h-14 px-3 md:h-15 md:px-4"),
9293
9325
  shouldUseOverflowScroll && !isBarVariant && "snap-start",
9294
9326
  classNames == null ? void 0 : classNames.tabTrigger
9295
9327
  ),
@@ -9339,9 +9371,9 @@ var Tabs = ({
9339
9371
  "aria-hidden": true,
9340
9372
  className: cn(
9341
9373
  "agg-tab-scroll-start",
9342
- "pointer-events-none absolute top-0 bottom-0 left-0 z-10 w-12 md:w-18 bg-linear-to-r from-agg-secondary via-agg-secondary to-transparent",
9374
+ "pointer-events-none absolute inset-y-0 left-0 z-10 w-6 md:w-[60px] bg-linear-to-r from-agg-secondary to-transparent",
9343
9375
  getMotionClassName(enableAnimations, "transition-opacity duration-200"),
9344
- canScrollLeft ? "opacity-100" : "opacity-0"
9376
+ hasOverflow && canScrollLeft && !isAtStart ? "opacity-100" : "opacity-0"
9345
9377
  )
9346
9378
  }
9347
9379
  ),
@@ -9351,9 +9383,9 @@ var Tabs = ({
9351
9383
  "aria-hidden": true,
9352
9384
  className: cn(
9353
9385
  "agg-tab-scroll-end",
9354
- "pointer-events-none absolute top-0 right-0 bottom-0 z-10 w-12 md:w-18 bg-linear-to-l from-agg-secondary via-agg-secondary to-transparent",
9386
+ "pointer-events-none absolute inset-y-0 right-0 z-10 w-6 md:w-[60px] bg-linear-to-l from-agg-secondary to-transparent",
9355
9387
  getMotionClassName(enableAnimations, "transition-opacity duration-200"),
9356
- canScrollRight ? "opacity-100" : "opacity-0"
9388
+ hasOverflow && canScrollRight && !isAtEnd ? "opacity-100" : "opacity-0"
9357
9389
  )
9358
9390
  }
9359
9391
  )
@@ -3,6 +3,7 @@ import {
3
3
  Card,
4
4
  DEFAULT_VENUE_COLOR,
5
5
  Skeleton,
6
+ VenueLogo,
6
7
  __spreadProps,
7
8
  __spreadValues,
8
9
  cn,
@@ -18,7 +19,7 @@ import {
18
19
  selectPrimaryVenueMarket,
19
20
  skeletonViews,
20
21
  sortOutcomes
21
- } from "./chunk-2ET5CXOU.mjs";
22
+ } from "./chunk-PTNFXXOV.mjs";
22
23
 
23
24
  // src/trading/trading-context/index.tsx
24
25
  import { useEventTradingContext } from "@agg-build/hooks";
@@ -166,8 +167,10 @@ var getTradingSlippageLabel = (value) => {
166
167
  };
167
168
 
168
169
  // src/trading/settlement/index.tsx
169
- import { useLabels } from "@agg-build/hooks";
170
- import { useMemo } from "react";
170
+ import {
171
+ useLabels
172
+ } from "@agg-build/hooks";
173
+ import { useEffect, useMemo, useState } from "react";
171
174
 
172
175
  // src/trading/settlement/settlement-text-renderer.tsx
173
176
  import { Fragment } from "react";
@@ -194,13 +197,6 @@ var parseSettlementBlocks = (input) => {
194
197
  }
195
198
  return blocks;
196
199
  };
197
- var getFirstSettlementParagraph = (input) => {
198
- if (!input) return "";
199
- const blocks = parseSettlementBlocks(input);
200
- const firstParagraph = blocks.find((block) => block.kind === "paragraph");
201
- if (!firstParagraph || firstParagraph.kind !== "paragraph") return "";
202
- return firstParagraph.lines.join(" ").trim();
203
- };
204
200
  var normalizeSettlementForCompare = (input) => {
205
201
  return stripHtmlFragments(input).replace(/\s+/g, " ").trim().toLowerCase();
206
202
  };
@@ -367,10 +363,206 @@ var SettlementTextRenderer = ({
367
363
  SettlementTextRenderer.displayName = "SettlementTextRenderer";
368
364
 
369
365
  // src/trading/settlement/index.tsx
370
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
366
+ import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
371
367
  var SETTLEMENT_SECTION_ID = "agg-settlement-section";
372
- var getSettlementHeaderClassName = () => {
373
- return "flex items-center justify-between gap-4";
368
+ var getSettlementDifferenceId = (sectionId, canonicalKey) => {
369
+ return `${sectionId}-difference-${canonicalKey}`;
370
+ };
371
+ var dateOnlyRegex = /^(\d{4})-(\d{2})-(\d{2})$/;
372
+ var isoTimestampWithTimezoneRegex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(?::\d{2}(?:\.\d{1,9})?)?(?:Z|[+-]\d{2}:?\d{2})$/i;
373
+ var normalizeDifferenceText = (value) => {
374
+ return value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
375
+ };
376
+ var resolveCanonicalDifferenceKey = (difference) => {
377
+ const normalizedType = normalizeDifferenceText(difference.type);
378
+ const combined = normalizeDifferenceText(`${difference.type} ${difference.title}`);
379
+ if (combined.includes("start_date") || combined.includes("open_date")) return "start_date";
380
+ if (combined.includes("end_date") || combined.includes("close_date") || combined.includes("closing_date") || combined.includes("expiration_date") || combined.includes("expiry_date")) {
381
+ return "end_date";
382
+ }
383
+ if (combined.includes("resolution_timing") || combined.includes("resolution_date") || combined.includes("resolution_deadline") || combined.includes("settlement_date") || combined.includes("settlement_deadline") || combined.includes("settlement_timing")) {
384
+ return "resolution_timing";
385
+ }
386
+ return normalizedType || "other";
387
+ };
388
+ var parseSettlementDateMs = (value) => {
389
+ const trimmed = value.trim();
390
+ const dateOnlyMatch = dateOnlyRegex.exec(trimmed);
391
+ if (dateOnlyMatch) {
392
+ const [, year, month, day] = dateOnlyMatch;
393
+ return Date.UTC(Number(year), Number(month) - 1, Number(day));
394
+ }
395
+ if (!isoTimestampWithTimezoneRegex.test(trimmed)) return null;
396
+ const ms = Date.parse(trimmed);
397
+ return Number.isNaN(ms) ? null : ms;
398
+ };
399
+ var isDateLikeDifference = (canonicalKey) => {
400
+ return canonicalKey === "resolution_timing" || canonicalKey === "start_date" || canonicalKey === "end_date";
401
+ };
402
+ var hasEqualNormalizedDateValues = (difference, canonicalKey) => {
403
+ if (!isDateLikeDifference(canonicalKey)) return false;
404
+ const values = Object.values(difference.perVenue);
405
+ if (values.length < 2) return false;
406
+ const timestamps = values.map(parseSettlementDateMs);
407
+ if (timestamps.some((timestamp) => timestamp === null)) return false;
408
+ return new Set(timestamps).size === 1;
409
+ };
410
+ var resolveDifferenceSeverity = (difference, canonicalKey) => {
411
+ var _a;
412
+ const combined = normalizeDifferenceText(
413
+ `${difference.type} ${difference.title} ${(_a = difference.summary) != null ? _a : ""}`
414
+ );
415
+ if (isDateLikeDifference(canonicalKey)) return "critical";
416
+ if (canonicalKey === "scope" || canonicalKey === "threshold" || canonicalKey === "edge_cases") {
417
+ return "critical";
418
+ }
419
+ if (combined.includes("conflict") || combined.includes("void") || combined.includes("cancel") || combined.includes("postpone") || combined.includes("recount") || combined.includes("overtime") || combined.includes("extra_time")) {
420
+ return "critical";
421
+ }
422
+ return "informational";
423
+ };
424
+ var mergePerVenueValues = (current, next) => {
425
+ return Object.entries(next).reduce(
426
+ (merged, [venue, value]) => {
427
+ if (merged[venue] === void 0) merged[venue] = value;
428
+ return merged;
429
+ },
430
+ __spreadValues({}, current)
431
+ );
432
+ };
433
+ var prepareSettlementDifferences = (differences) => {
434
+ const byCanonicalKey = /* @__PURE__ */ new Map();
435
+ for (const [originalIndex, rawDifference] of (differences != null ? differences : []).entries()) {
436
+ const title = rawDifference.title.trim();
437
+ const perVenue = Object.fromEntries(
438
+ Object.entries(rawDifference.perVenue).map(([venue, value]) => [venue.trim(), value.trim()]).filter(([venue, value]) => venue.length > 0 && value.length > 0)
439
+ );
440
+ if (!title || Object.keys(perVenue).length === 0) continue;
441
+ const difference = __spreadProps(__spreadValues({}, rawDifference), { title, perVenue });
442
+ const canonicalKey = resolveCanonicalDifferenceKey(difference);
443
+ if (hasEqualNormalizedDateValues(difference, canonicalKey)) continue;
444
+ const existing = byCanonicalKey.get(canonicalKey);
445
+ if (existing) {
446
+ byCanonicalKey.set(canonicalKey, __spreadProps(__spreadValues({}, existing), {
447
+ perVenue: mergePerVenueValues(existing.perVenue, difference.perVenue)
448
+ }));
449
+ continue;
450
+ }
451
+ byCanonicalKey.set(canonicalKey, __spreadProps(__spreadValues({}, difference), {
452
+ canonicalKey,
453
+ severity: resolveDifferenceSeverity(difference, canonicalKey),
454
+ originalIndex
455
+ }));
456
+ }
457
+ return Array.from(byCanonicalKey.values()).sort((left, right) => {
458
+ const severityDelta = Number(right.severity === "critical") - Number(left.severity === "critical");
459
+ if (severityDelta !== 0) return severityDelta;
460
+ return left.originalIndex - right.originalIndex;
461
+ });
462
+ };
463
+ var formatVenueFallbackLabel = (venue) => {
464
+ return venue.split(/[-_\s]+/).filter(Boolean).map((part) => `${part.slice(0, 1).toUpperCase()}${part.slice(1)}`).join(" ");
465
+ };
466
+ var resolveSettlementVenueLabel = (venue, labels) => {
467
+ var _a;
468
+ return (_a = labels.venues[venue]) != null ? _a : formatVenueFallbackLabel(venue);
469
+ };
470
+ var resolveDifferenceVenueKeys = (difference, settlementVenues) => {
471
+ const explicitVenues = Object.keys(difference.perVenue);
472
+ if (!isDateLikeDifference(difference.canonicalKey)) return explicitVenues;
473
+ const allVenues = [...settlementVenues != null ? settlementVenues : [], ...explicitVenues];
474
+ return Array.from(new Set(allVenues.filter((venue) => venue.trim().length > 0)));
475
+ };
476
+ var resolveDifferenceIconClassName = (canonicalKey) => {
477
+ if (canonicalKey.includes("source") || canonicalKey.includes("url")) return "fi-rr-world";
478
+ if (canonicalKey === "resolution_timing" || canonicalKey.includes("timing")) {
479
+ return "fi-rr-clock";
480
+ }
481
+ if (canonicalKey === "start_date" || canonicalKey.includes("start"))
482
+ return "fi-rr-calendar-clock";
483
+ if (canonicalKey === "end_date" || canonicalKey.includes("end")) return "fi-rr-calendar-clock";
484
+ if (canonicalKey.includes("cancel") || canonicalKey.includes("void") || canonicalKey.includes("postpone")) {
485
+ return "fi-rr-ban";
486
+ }
487
+ if (canonicalKey === "edge_cases" || canonicalKey.includes("edge")) {
488
+ return "fi-rr-triangle-warning";
489
+ }
490
+ if (canonicalKey === "scope") return "fi-rr-layers";
491
+ if (canonicalKey === "threshold") return "fi-rr-tachometer-alt-fastest";
492
+ if (canonicalKey.includes("wording")) return "fi-rr-document";
493
+ return "fi-rr-info";
494
+ };
495
+ var buildSettlementVenueRules = ({
496
+ marketBlock,
497
+ primaryRulesBlock,
498
+ settlementVenues,
499
+ settlementVenueRules
500
+ }) => {
501
+ var _a, _b;
502
+ if (settlementVenueRules) {
503
+ const rulesByVenue = /* @__PURE__ */ new Map();
504
+ for (const rule of settlementVenueRules) {
505
+ const venue2 = rule.venue.trim();
506
+ const content2 = rule.content.trim();
507
+ if (!venue2 || !content2) continue;
508
+ const venueRules = (_a = rulesByVenue.get(venue2)) != null ? _a : [];
509
+ if (!venueRules.includes(content2)) venueRules.push(content2);
510
+ rulesByVenue.set(venue2, venueRules);
511
+ }
512
+ return Array.from(rulesByVenue, ([venue2, contents]) => ({
513
+ venue: venue2,
514
+ content: contents.join("\n\n")
515
+ }));
516
+ }
517
+ const content = [marketBlock == null ? void 0 : marketBlock.content, primaryRulesBlock == null ? void 0 : primaryRulesBlock.content].filter((value) => typeof value === "string" && value.trim().length > 0).join("\n\n");
518
+ const venue = (_b = settlementVenues == null ? void 0 : settlementVenues.find((candidate) => candidate.trim().length > 0)) == null ? void 0 : _b.trim();
519
+ return content && venue ? [{ venue, content }] : [];
520
+ };
521
+ var isDuplicatedByVenueRules = (content, venueRules) => {
522
+ const normalizedContent = normalizeSettlementForCompare(content);
523
+ if (!normalizedContent) return false;
524
+ return venueRules.some((rule) => {
525
+ const normalizedRule = normalizeSettlementForCompare(rule.content);
526
+ return normalizedRule.includes(normalizedContent);
527
+ });
528
+ };
529
+ var SettlementVenueRules = ({
530
+ rules,
531
+ labels
532
+ }) => {
533
+ return /* @__PURE__ */ jsxs2("div", { className: "agg-settlement-venue-rules flex w-full flex-col items-start gap-4", children: [
534
+ /* @__PURE__ */ jsx2("p", { className: "text-agg-sm font-agg-bold leading-agg-5 text-agg-foreground", children: labels.trading.settlementFullRulesTitle }),
535
+ /* @__PURE__ */ jsx2("div", { className: "flex w-full flex-col items-start gap-4", children: rules.map((rule) => {
536
+ const venueLabel = resolveSettlementVenueLabel(rule.venue, labels);
537
+ return /* @__PURE__ */ jsxs2("details", { className: "group/agg-settlement-rule w-full", children: [
538
+ /* @__PURE__ */ jsxs2("summary", { className: "flex cursor-pointer list-none items-center gap-2 text-agg-sm font-agg-normal leading-agg-5 text-agg-foreground group-hover/agg-settlement-rule:text-agg-muted-foreground transition-colors marker:hidden", children: [
539
+ /* @__PURE__ */ jsx2(
540
+ VenueLogo,
541
+ {
542
+ venue: rule.venue,
543
+ size: "small",
544
+ className: "size-4",
545
+ ariaLabel: venueLabel
546
+ }
547
+ ),
548
+ /* @__PURE__ */ jsx2("span", { className: "text-agg-foreground group-hover/agg-settlement-rule:text-agg-muted-foreground transition-colors", children: venueLabel }),
549
+ /* @__PURE__ */ jsx2(
550
+ "i",
551
+ {
552
+ className: cn(
553
+ "fi fi-rr-angle-small-down text-[14px]!",
554
+ "group-open/agg-settlement-rule:rotate-180",
555
+ "size-3.5! shrink-0 text-agg-foreground group-hover/agg-settlement-rule:text-agg-muted-foreground transition-[colors,transform]"
556
+ ),
557
+ style: { fontSize: 14 },
558
+ "aria-hidden": "true"
559
+ }
560
+ )
561
+ ] }),
562
+ /* @__PURE__ */ jsx2("div", { className: "mt-3 pl-6", children: /* @__PURE__ */ jsx2(SettlementTextRenderer, { content: rule.content }) })
563
+ ] }, rule.venue);
564
+ }) })
565
+ ] });
374
566
  };
375
567
  var Settlement = ({
376
568
  className,
@@ -380,9 +572,12 @@ var Settlement = ({
380
572
  eventDescription,
381
573
  marketDescription,
382
574
  primaryRules,
575
+ settlementDiff,
576
+ settlementVenues,
577
+ settlementVenueRules,
383
578
  isLoading = false
384
579
  }) => {
385
- var _a, _b, _c;
580
+ var _a, _b, _c, _d, _e;
386
581
  const labels = useLabels();
387
582
  const blocks = useMemo(
388
583
  () => dedupeSettlementSources({
@@ -392,9 +587,41 @@ var Settlement = ({
392
587
  }),
393
588
  [eventDescription, marketDescription, primaryRules]
394
589
  );
590
+ const settlementDifferences = useMemo(
591
+ () => prepareSettlementDifferences(settlementDiff == null ? void 0 : settlementDiff.differences),
592
+ [settlementDiff == null ? void 0 : settlementDiff.differences]
593
+ );
395
594
  const eventBlock = (_a = blocks.find((block) => block.key === "eventDescription")) != null ? _a : null;
396
595
  const marketBlock = (_b = blocks.find((block) => block.key === "marketDescription")) != null ? _b : null;
397
596
  const primaryRulesBlock = (_c = blocks.find((block) => block.key === "primaryRules")) != null ? _c : null;
597
+ const venueRuleBlocks = useMemo(
598
+ () => buildSettlementVenueRules({
599
+ marketBlock,
600
+ primaryRulesBlock,
601
+ settlementVenues,
602
+ settlementVenueRules
603
+ }),
604
+ [marketBlock, primaryRulesBlock, settlementVenues, settlementVenueRules]
605
+ );
606
+ const hasSettlementDifferences = settlementDifferences.length > 0;
607
+ const hasVenueSettlementRules = venueRuleBlocks.length > 0;
608
+ const standaloneEventBlock = eventBlock && !isDuplicatedByVenueRules(eventBlock.content, venueRuleBlocks) ? eventBlock : null;
609
+ const standaloneMarketBlock = hasVenueSettlementRules ? null : marketBlock;
610
+ const standalonePrimaryRulesBlock = hasVenueSettlementRules ? null : primaryRulesBlock;
611
+ const hasStandaloneSettlementText = hasVenueSettlementRules ? standaloneEventBlock !== null : blocks.length > 0;
612
+ const hasSettlementContent = hasSettlementDifferences || hasVenueSettlementRules || hasStandaloneSettlementText;
613
+ const defaultOpenDifferenceKey = (_e = (_d = settlementDifferences[0]) == null ? void 0 : _d.canonicalKey) != null ? _e : null;
614
+ const [openDifferenceKeys, setOpenDifferenceKeys] = useState(
615
+ () => defaultOpenDifferenceKey ? [defaultOpenDifferenceKey] : []
616
+ );
617
+ useEffect(() => {
618
+ setOpenDifferenceKeys(defaultOpenDifferenceKey ? [defaultOpenDifferenceKey] : []);
619
+ }, [defaultOpenDifferenceKey]);
620
+ const handleToggleDifference = (canonicalKey) => {
621
+ setOpenDifferenceKeys(
622
+ (currentKeys) => currentKeys.includes(canonicalKey) ? currentKeys.filter((currentKey) => currentKey !== canonicalKey) : [...currentKeys, canonicalKey]
623
+ );
624
+ };
398
625
  if (isLoading) {
399
626
  return /* @__PURE__ */ jsx2(
400
627
  Skeleton,
@@ -405,6 +632,7 @@ var Settlement = ({
405
632
  }
406
633
  );
407
634
  }
635
+ if (!hasSettlementContent) return null;
408
636
  const resolvedSectionLabel = sectionLabel === defaultSettlementSectionLabel ? labels.trading.settlementSection : sectionLabel;
409
637
  return /* @__PURE__ */ jsxs2(
410
638
  Card,
@@ -412,38 +640,117 @@ var Settlement = ({
412
640
  id,
413
641
  className: cn(
414
642
  "group/agg-settlement-card",
415
- "flex flex-col w-full gap-5 rounded-agg-xl border border-agg-separator bg-agg-secondary p-5 shadow-none hover:shadow-none",
643
+ "flex w-full flex-col items-start gap-4 rounded-agg-xl border border-agg-separator bg-agg-secondary p-5 shadow-none hover:shadow-none sm:gap-5",
416
644
  className
417
645
  ),
418
646
  children: [
419
- /* @__PURE__ */ jsxs2("div", { className: cn("agg-settlement-header", getSettlementHeaderClassName()), children: [
420
- /* @__PURE__ */ jsx2("p", { className: "text-agg-xs font-agg-bold leading-agg-4 uppercase text-agg-muted-foreground", children: resolvedSectionLabel }),
421
- question ? /* @__PURE__ */ jsx2("p", { className: "agg-settlement-question text-agg-sm font-agg-bold leading-agg-5 text-agg-foreground", children: question }) : null
647
+ /* @__PURE__ */ jsxs2("div", { className: "agg-settlement-header flex w-full flex-col items-start gap-1 text-agg-muted-foreground sm:flex-row sm:items-center sm:justify-between sm:gap-4", children: [
648
+ /* @__PURE__ */ jsx2("p", { className: "shrink-0 text-agg-xs font-agg-bold leading-agg-4 uppercase", children: resolvedSectionLabel }),
649
+ question ? /* @__PURE__ */ jsx2("p", { className: "agg-settlement-question min-w-0 text-agg-sm font-agg-normal leading-agg-5 sm:max-w-[314px] sm:truncate", children: question }) : null
422
650
  ] }),
423
- blocks.length === 0 ? /* @__PURE__ */ jsx2("p", { className: "agg-settlement-empty text-agg-sm leading-agg-5 text-agg-muted-foreground", children: labels.trading.settlementEmpty }) : /* @__PURE__ */ jsxs2("div", { className: "agg-settlement-sections flex flex-col gap-4", children: [
424
- eventBlock || marketBlock ? /* @__PURE__ */ jsxs2(
425
- "div",
426
- {
427
- className: "agg-settlement-section agg-settlement-section-description",
428
- "data-source": "description",
429
- children: [
430
- eventBlock ? /* @__PURE__ */ jsx2("div", { "data-source": "eventDescription", children: /* @__PURE__ */ jsx2(SettlementTextRenderer, { content: eventBlock.content }) }) : null,
431
- eventBlock && marketBlock ? /* @__PURE__ */ jsx2("hr", { className: "agg-settlement-divider my-4 border-0 border-t border-agg-separator" }) : null,
432
- marketBlock ? /* @__PURE__ */ jsx2("div", { "data-source": "marketDescription", children: /* @__PURE__ */ jsx2(SettlementTextRenderer, { content: marketBlock.content }) }) : null
433
- ]
434
- }
435
- ) : null,
436
- primaryRulesBlock ? /* @__PURE__ */ jsxs2(
437
- "div",
438
- {
439
- className: "agg-settlement-section agg-settlement-section-primaryRules",
440
- "data-source": "primaryRules",
441
- children: [
442
- /* @__PURE__ */ jsx2("p", { className: "agg-settlement-section-label text-agg-xs font-agg-bold leading-agg-4 uppercase text-agg-muted-foreground mb-2", children: labels.trading.settlementPrimaryRulesLabel }),
443
- /* @__PURE__ */ jsx2(SettlementTextRenderer, { content: primaryRulesBlock.content })
444
- ]
445
- }
446
- ) : null
651
+ /* @__PURE__ */ jsxs2("div", { className: "agg-settlement-sections flex w-full flex-col items-start gap-5", children: [
652
+ hasStandaloneSettlementText ? /* @__PURE__ */ jsxs2("div", { className: "w-full", children: [
653
+ standaloneEventBlock || standaloneMarketBlock ? /* @__PURE__ */ jsxs2(
654
+ "div",
655
+ {
656
+ className: "agg-settlement-section agg-settlement-section-description",
657
+ "data-source": "description",
658
+ children: [
659
+ standaloneEventBlock ? /* @__PURE__ */ jsx2("div", { "data-source": "eventDescription", children: /* @__PURE__ */ jsx2(SettlementTextRenderer, { content: standaloneEventBlock.content }) }) : null,
660
+ standaloneEventBlock && standaloneMarketBlock ? /* @__PURE__ */ jsx2("hr", { className: "agg-settlement-divider my-4 border-0 border-t border-agg-separator" }) : null,
661
+ standaloneMarketBlock ? /* @__PURE__ */ jsx2("div", { "data-source": "marketDescription", children: /* @__PURE__ */ jsx2(SettlementTextRenderer, { content: standaloneMarketBlock.content }) }) : null
662
+ ]
663
+ }
664
+ ) : null,
665
+ standalonePrimaryRulesBlock ? /* @__PURE__ */ jsxs2(
666
+ "div",
667
+ {
668
+ className: "agg-settlement-section agg-settlement-section-primaryRules",
669
+ "data-source": "primaryRules",
670
+ children: [
671
+ /* @__PURE__ */ jsx2("p", { className: "agg-settlement-section-label text-agg-xs font-agg-bold leading-agg-4 uppercase text-agg-muted-foreground mb-2", children: labels.trading.settlementPrimaryRulesLabel }),
672
+ /* @__PURE__ */ jsx2(SettlementTextRenderer, { content: standalonePrimaryRulesBlock.content })
673
+ ]
674
+ }
675
+ ) : null
676
+ ] }) : null,
677
+ hasSettlementDifferences ? /* @__PURE__ */ jsxs2("div", { className: "agg-settlement-differences flex w-full flex-col items-start gap-5", children: [
678
+ /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2", children: [
679
+ /* @__PURE__ */ jsx2("p", { className: "text-agg-sm font-agg-bold leading-agg-5 text-agg-foreground", children: labels.trading.settlementDifferencesTitle }),
680
+ /* @__PURE__ */ jsx2("span", { className: "flex size-4 shrink-0 items-center justify-center rounded-agg-full bg-agg-primary text-[10px] font-agg-bold leading-[14px] text-agg-on-primary", children: settlementDifferences.length })
681
+ ] }),
682
+ /* @__PURE__ */ jsx2("div", { className: "flex w-full flex-col items-start gap-5", children: settlementDifferences.map((difference) => {
683
+ const venueKeys = resolveDifferenceVenueKeys(difference, settlementVenues);
684
+ const isExpanded = openDifferenceKeys.includes(difference.canonicalKey) && venueKeys.length > 0;
685
+ return /* @__PURE__ */ jsxs2(
686
+ "div",
687
+ {
688
+ id: getSettlementDifferenceId(id, difference.canonicalKey),
689
+ className: "agg-settlement-difference flex w-full flex-col items-start gap-2 rounded-agg-lg",
690
+ children: [
691
+ /* @__PURE__ */ jsxs2(
692
+ "button",
693
+ {
694
+ type: "button",
695
+ className: "flex w-full cursor-pointer items-center gap-2 text-left group/agg-settlement-difference",
696
+ "aria-expanded": isExpanded,
697
+ onClick: () => handleToggleDifference(difference.canonicalKey),
698
+ children: [
699
+ /* @__PURE__ */ jsx2(
700
+ "i",
701
+ {
702
+ className: cn(
703
+ "fi",
704
+ resolveDifferenceIconClassName(difference.canonicalKey),
705
+ "inline-flex size-4! shrink-0 items-center justify-center text-[16px] leading-none text-agg-muted-foreground"
706
+ ),
707
+ "aria-hidden": "true"
708
+ }
709
+ ),
710
+ /* @__PURE__ */ jsx2("p", { className: "min-w-0 text-agg-sm font-agg-normal leading-agg-5 text-agg-foreground group-hover/agg-settlement-difference:text-agg-muted-foreground transition-colors break-words [overflow-wrap:anywhere]", children: difference.title }),
711
+ /* @__PURE__ */ jsx2(
712
+ "i",
713
+ {
714
+ className: cn(
715
+ "fi fi-rr-angle-small-down text-[14px]!",
716
+ isExpanded && "rotate-180",
717
+ "size-3.5! shrink-0 text-agg-foreground group-hover/agg-settlement-difference:text-agg-muted-foreground transition-[colors,transform]"
718
+ ),
719
+ style: { fontSize: 14 },
720
+ "aria-hidden": "true"
721
+ }
722
+ )
723
+ ]
724
+ }
725
+ ),
726
+ isExpanded ? /* @__PURE__ */ jsx2("dl", { className: "flex w-full flex-col items-start gap-1 px-6", children: venueKeys.map((venue) => {
727
+ var _a2;
728
+ const venueValue = (_a2 = difference.perVenue[venue]) != null ? _a2 : labels.trading.settlementValueUnavailable;
729
+ const venueLabel = resolveSettlementVenueLabel(venue, labels);
730
+ return /* @__PURE__ */ jsxs2("div", { className: "flex w-full items-start gap-2", children: [
731
+ /* @__PURE__ */ jsx2(
732
+ VenueLogo,
733
+ {
734
+ venue,
735
+ size: "small",
736
+ className: "mt-0.5 size-4",
737
+ ariaLabel: venueLabel
738
+ }
739
+ ),
740
+ /* @__PURE__ */ jsx2("dt", { className: "w-[88px] shrink-0 text-agg-sm font-agg-normal leading-agg-5 text-agg-foreground", children: venueLabel }),
741
+ /* @__PURE__ */ jsx2("dd", { className: "min-w-0 flex-1 text-agg-sm font-agg-normal leading-agg-5 text-agg-muted-foreground break-words [overflow-wrap:anywhere]", children: venueValue })
742
+ ] }, venue);
743
+ }) }) : null
744
+ ]
745
+ },
746
+ difference.canonicalKey
747
+ );
748
+ }) })
749
+ ] }) : null,
750
+ hasVenueSettlementRules ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
751
+ hasSettlementDifferences || hasStandaloneSettlementText ? /* @__PURE__ */ jsx2("div", { className: "h-px w-full bg-agg-separator" }) : null,
752
+ /* @__PURE__ */ jsx2(SettlementVenueRules, { rules: venueRuleBlocks, labels })
753
+ ] }) : null
447
754
  ] })
448
755
  ]
449
756
  }
@@ -1318,8 +1625,10 @@ export {
1318
1625
  getTradingBalanceLabel,
1319
1626
  getTradingSharesLabel,
1320
1627
  getTradingSlippageLabel,
1321
- getFirstSettlementParagraph,
1322
1628
  SETTLEMENT_SECTION_ID,
1629
+ getSettlementDifferenceId,
1630
+ prepareSettlementDifferences,
1631
+ resolveDifferenceIconClassName,
1323
1632
  Settlement,
1324
1633
  resolveTradingStatePresentation,
1325
1634
  resolveTradingStateBadgeClassName,