@agg-build/ui 4.4.0 → 4.7.1

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.
package/dist/events.js CHANGED
@@ -4289,6 +4289,19 @@ var resolveCategoryIdsFromPath = (path, fallbackCategoryIds) => {
4289
4289
  if (deepest) return [deepest];
4290
4290
  return fallbackCategoryIds;
4291
4291
  };
4292
+ var validateSubcategoryPath = (requestedPath, rootCategoryId, childrenByParentId) => {
4293
+ var _a;
4294
+ if (!rootCategoryId) return [];
4295
+ const validPath = [];
4296
+ let parentId = rootCategoryId;
4297
+ for (const categoryId of requestedPath) {
4298
+ const category = (_a = childrenByParentId.get(parentId)) == null ? void 0 : _a.find((child) => child.id === categoryId);
4299
+ if (!category) break;
4300
+ validPath.push(category.id);
4301
+ parentId = category.id;
4302
+ }
4303
+ return validPath;
4304
+ };
4292
4305
  var resolveTabVenus = (tab, visibleVenues) => {
4293
4306
  const applyAllowList = (venues) => {
4294
4307
  if (!venues) {
@@ -14624,6 +14637,7 @@ var import_react22 = require("react");
14624
14637
  // src/events/list/event-list.constants.ts
14625
14638
  var import_sdk14 = require("@agg-build/sdk");
14626
14639
  var DEFAULT_EVENTS_LIMIT = 50;
14640
+ var DEFAULT_EVENT_LIST_SORT = "volume24hr";
14627
14641
  var getDefaultEventListTabs = (labels) => {
14628
14642
  return [
14629
14643
  {
@@ -14693,6 +14707,7 @@ var getDefaultEventListTabs = (labels) => {
14693
14707
 
14694
14708
  // src/events/list/event-list-tabs.tsx
14695
14709
  var import_jsx_runtime138 = require("react/jsx-runtime");
14710
+ var DEFAULT_HIDDEN_VENUES = new Set((0, import_sdk15.getEffectiveDisabledVenues)(void 0));
14696
14711
  var renderTabIcon = (tab, isActive) => {
14697
14712
  if (tab.iconName === "warning-filled") {
14698
14713
  return /* @__PURE__ */ (0, import_jsx_runtime138.jsx)(Icon, { name: "warning-filled", size: "small", color: "currentColor" });
@@ -14721,15 +14736,11 @@ var useEventListTabs = (tabs) => {
14721
14736
  const availabilityState = (0, import_hooks48.getVenueAvailabilityState)({
14722
14737
  venueId: tab.venueLogo,
14723
14738
  disabledVenues,
14724
- // A compile-time-inactive venue (novig today) is hidden by default and
14725
- // un-hidden per-environment by NOVIG_DATA_VISIBLE, so its
14726
- // disabled-ness is only known once `/app/config` resolves — treating
14727
- // it as hidden while that request is in flight stops its tab flashing
14728
- // in and out where the flag is unset. Active venues must NOT be
14729
- // withheld, or they pop in late. Keyed off the shared inactive-venue
14730
- // helper rather than a venue name, so launching or retiring one needs
14731
- // no change here.
14732
- isConfigLoading: isAppConfigLoading && (0, import_sdk15.isVenueInactive)(tab.venueLogo),
14739
+ // A globally inactive or default-disabled venue is hidden until
14740
+ // `/app/config` resolves. That prevents partner-opt-in venues such as
14741
+ // Novig from flashing briefly for apps that still disable them, while
14742
+ // ordinary active venues continue rendering immediately.
14743
+ isConfigLoading: isAppConfigLoading && ((0, import_sdk15.isVenueInactive)(tab.venueLogo) || DEFAULT_HIDDEN_VENUES.has(tab.venueLogo)),
14733
14744
  isLocationBlocked
14734
14745
  });
14735
14746
  if (availabilityState === "hidden") return [];
@@ -14836,10 +14847,16 @@ var EventList = ({
14836
14847
  getMarketHref,
14837
14848
  getEventHref,
14838
14849
  initialVenueTab,
14850
+ activeVenueTab: controlledActiveVenueTab,
14851
+ onActiveVenueTabChange,
14852
+ selectedSort: controlledSelectedSort,
14853
+ onSelectedSortChange,
14854
+ categoryPath: controlledCategoryPath,
14855
+ onCategoryPathChange,
14839
14856
  initialLoadedPageCount,
14840
14857
  stateRef
14841
14858
  }) => {
14842
- var _a, _b, _c, _d, _e;
14859
+ var _a, _b, _c, _d, _e, _f;
14843
14860
  const labels = (0, import_hooks49.useLabels)();
14844
14861
  const { disabledVenues } = (0, import_hooks49.useAppConfig)();
14845
14862
  const {
@@ -14851,13 +14868,37 @@ var EventList = ({
14851
14868
  () => disabledVenues.length === 0 ? void 0 : (0, import_hooks49.getVisibleVenueIdsByConfig)(import_sdk16.VENUES, disabledVenues),
14852
14869
  [disabledVenues]
14853
14870
  );
14854
- const [activeTabValue, setActiveTabValue] = (0, import_react23.useState)(
14871
+ const [internalActiveTabValue, setInternalActiveTabValue] = (0, import_react23.useState)(
14855
14872
  (_b = initialVenueTab != null ? initialVenueTab : (_a = resolvedTabs[0]) == null ? void 0 : _a.value) != null ? _b : "matched"
14856
14873
  );
14857
- const [selectedSort, setSelectedSort] = (0, import_react23.useState)("volume24hr");
14874
+ const activeTabValue = controlledActiveVenueTab != null ? controlledActiveVenueTab : internalActiveTabValue;
14875
+ const [internalSelectedSort, setInternalSelectedSort] = (0, import_react23.useState)(DEFAULT_EVENT_LIST_SORT);
14876
+ const selectedSort = controlledSelectedSort != null ? controlledSelectedSort : internalSelectedSort;
14858
14877
  const [isSubcategoriesModalOpen, setIsSubcategoriesModalOpen] = (0, import_react23.useState)(false);
14859
- const [categoryPath, setCategoryPath] = (0, import_react23.useState)([]);
14878
+ const [internalCategoryPath, setInternalCategoryPath] = (0, import_react23.useState)([]);
14879
+ const categoryPath = controlledCategoryPath != null ? controlledCategoryPath : internalCategoryPath;
14860
14880
  const [collapsedCategoryIds, setCollapsedCategoryIds] = (0, import_react23.useState)(() => /* @__PURE__ */ new Set());
14881
+ const handleActiveTabChange = (0, import_react23.useCallback)(
14882
+ (value) => {
14883
+ if (controlledActiveVenueTab == null) setInternalActiveTabValue(value);
14884
+ onActiveVenueTabChange == null ? void 0 : onActiveVenueTabChange(value, { history: "push" });
14885
+ },
14886
+ [controlledActiveVenueTab, onActiveVenueTabChange]
14887
+ );
14888
+ const handleSelectedSortChange = (0, import_react23.useCallback)(
14889
+ (value) => {
14890
+ if (controlledSelectedSort == null) setInternalSelectedSort(value);
14891
+ onSelectedSortChange == null ? void 0 : onSelectedSortChange(value, { history: "push" });
14892
+ },
14893
+ [controlledSelectedSort, onSelectedSortChange]
14894
+ );
14895
+ const handleCategoryPathChange = (0, import_react23.useCallback)(
14896
+ (value, options) => {
14897
+ if (controlledCategoryPath == null) setInternalCategoryPath(value);
14898
+ onCategoryPathChange == null ? void 0 : onCategoryPathChange(value, options);
14899
+ },
14900
+ [controlledCategoryPath, onCategoryPathChange]
14901
+ );
14861
14902
  const sortItems = (0, import_react23.useMemo)(() => {
14862
14903
  return [
14863
14904
  {
@@ -14890,9 +14931,9 @@ var EventList = ({
14890
14931
  const baseCategoryId = (_c = categoryIds == null ? void 0 : categoryIds[0]) != null ? _c : null;
14891
14932
  (0, import_react23.useEffect)(() => {
14892
14933
  if (!isDiscoveryFiltersEnabled) return;
14893
- setCategoryPath([]);
14934
+ if (controlledCategoryPath == null) setInternalCategoryPath([]);
14894
14935
  setCollapsedCategoryIds(/* @__PURE__ */ new Set());
14895
- }, [baseCategoryId, isDiscoveryFiltersEnabled]);
14936
+ }, [baseCategoryId, controlledCategoryPath, isDiscoveryFiltersEnabled]);
14896
14937
  const { categories: topLevelCategories } = (0, import_hooks49.useCategories)({
14897
14938
  queryKeyScope: "event-list-top-categories",
14898
14939
  enabled: isDiscoveryFiltersEnabled,
@@ -14904,12 +14945,13 @@ var EventList = ({
14904
14945
  const baseCategoryChildPrefetchIds = (0, import_react23.useMemo)(() => {
14905
14946
  return Array.from(
14906
14947
  /* @__PURE__ */ new Set([
14948
+ ...baseCategoryId ? [baseCategoryId] : [],
14907
14949
  ...sortedTopLevelCategories.map((category) => category.id),
14908
14950
  ...categoryPath.map((category) => category.id)
14909
14951
  ])
14910
14952
  );
14911
- }, [categoryPath, sortedTopLevelCategories]);
14912
- const { childrenByParentId: baseChildrenByParentId } = (0, import_hooks49.useCategoryChildren)({
14953
+ }, [baseCategoryId, categoryPath, sortedTopLevelCategories]);
14954
+ const { childrenByParentId: baseChildrenByParentId, isLoading: isBaseCategoryChildrenLoading } = (0, import_hooks49.useCategoryChildren)({
14913
14955
  queryKeyScope: "event-list-category-children",
14914
14956
  enabled: isDiscoveryFiltersEnabled,
14915
14957
  parentIds: baseCategoryChildPrefetchIds,
@@ -14959,7 +15001,36 @@ var EventList = ({
14959
15001
  ...visibleGrandchildrenByParentId
14960
15002
  ]);
14961
15003
  }, [baseChildrenByParentId, visibleChildrenByParentId, visibleGrandchildrenByParentId]);
14962
- const shouldRenderSubcategoryFilters = isDiscoveryFiltersEnabled && baseCategoryId !== null && (((_e = (_d = childrenByParentId.get(baseCategoryId)) == null ? void 0 : _d.length) != null ? _e : 0) > 0 || categoryPath.length > 0);
15004
+ const controlledCategoryPathKey = (_d = controlledCategoryPath == null ? void 0 : controlledCategoryPath.map((entry) => entry.id).join(",")) != null ? _d : "";
15005
+ const controlledCategoryPathValidationKey = `${baseCategoryId != null ? baseCategoryId : ""}|${controlledCategoryPathKey}`;
15006
+ const [validatedCategoryPathKey, setValidatedCategoryPathKey] = (0, import_react23.useState)(
15007
+ () => controlledCategoryPath == null || controlledCategoryPath.length === 0 ? controlledCategoryPathValidationKey : ""
15008
+ );
15009
+ (0, import_react23.useEffect)(() => {
15010
+ if (controlledCategoryPath == null || controlledCategoryPath.length === 0) {
15011
+ setValidatedCategoryPathKey(controlledCategoryPathValidationKey);
15012
+ return;
15013
+ }
15014
+ if (isBaseCategoryChildrenLoading) return;
15015
+ const requestedIds = controlledCategoryPath.map((entry) => entry.id);
15016
+ const validIds = validateSubcategoryPath(requestedIds, baseCategoryId, baseChildrenByParentId);
15017
+ if (validIds.length !== requestedIds.length) {
15018
+ handleCategoryPathChange(controlledCategoryPath.slice(0, validIds.length), {
15019
+ history: "replace"
15020
+ });
15021
+ return;
15022
+ }
15023
+ setValidatedCategoryPathKey(controlledCategoryPathValidationKey);
15024
+ }, [
15025
+ baseCategoryId,
15026
+ baseChildrenByParentId,
15027
+ controlledCategoryPath,
15028
+ controlledCategoryPathKey,
15029
+ controlledCategoryPathValidationKey,
15030
+ handleCategoryPathChange,
15031
+ isBaseCategoryChildrenLoading
15032
+ ]);
15033
+ const shouldRenderSubcategoryFilters = isDiscoveryFiltersEnabled && baseCategoryId !== null && (((_f = (_e = childrenByParentId.get(baseCategoryId)) == null ? void 0 : _e.length) != null ? _f : 0) > 0 || categoryPath.length > 0);
14963
15034
  const baseCategoryEventCount = (0, import_react23.useMemo)(() => {
14964
15035
  var _a2, _b2;
14965
15036
  return (_b2 = (_a2 = sortedTopLevelCategories.find((c) => c.id === baseCategoryId)) == null ? void 0 : _a2.eventCount) != null ? _b2 : 0;
@@ -15017,7 +15088,8 @@ var EventList = ({
15017
15088
  // markets experience is enabled (the sports event-detail view loads the
15018
15089
  // folded companions via aggKey). Gated on the same flag as that view.
15019
15090
  grouped: showSportsMarkets,
15020
- initialPages: initialLoadedPageCount
15091
+ initialPages: initialLoadedPageCount,
15092
+ enabled: controlledCategoryPath == null || validatedCategoryPathKey === controlledCategoryPathValidationKey
15021
15093
  });
15022
15094
  (0, import_react23.useEffect)(() => {
15023
15095
  if (stateRef) {
@@ -15078,7 +15150,7 @@ var EventList = ({
15078
15150
  "grid grid-cols-[repeat(auto-fill,minmax(240px,1fr))] md:grid-cols-[repeat(auto-fill,minmax(360px,1fr))] gap-4"
15079
15151
  );
15080
15152
  const handleSelectAllCategories = () => {
15081
- setCategoryPath([]);
15153
+ handleCategoryPathChange([], { history: "push" });
15082
15154
  setCollapsedCategoryIds(/* @__PURE__ */ new Set());
15083
15155
  onCategoryRootChange == null ? void 0 : onCategoryRootChange(baseCategoryId != null ? baseCategoryId : void 0);
15084
15156
  setIsSubcategoriesModalOpen(false);
@@ -15090,7 +15162,7 @@ var EventList = ({
15090
15162
  isExpanded,
15091
15163
  isSelected
15092
15164
  }) => {
15093
- setCategoryPath((prev) => [...prev.slice(0, depth), entry]);
15165
+ handleCategoryPathChange([...categoryPath.slice(0, depth), entry], { history: "push" });
15094
15166
  setCollapsedCategoryIds((prev) => {
15095
15167
  const next = new Set(prev);
15096
15168
  if (hasKnownChildren && isExpanded && isSelected) {
@@ -15130,7 +15202,7 @@ var EventList = ({
15130
15202
  ariaLabel: labels.eventList.tabsAria(title2),
15131
15203
  className: "agg-event-list-tabs min-w-0 flex-1 max-w-[600px]!",
15132
15204
  activeTab: activeTabValue,
15133
- onTabChange: setActiveTabValue,
15205
+ onTabChange: handleActiveTabChange,
15134
15206
  overflowBehavior: "scroll"
15135
15207
  }
15136
15208
  ),
@@ -15140,7 +15212,7 @@ var EventList = ({
15140
15212
  ariaLabel: labels.eventList.sortByLabel,
15141
15213
  className: "min-w-[200px] w-auto! shrink-0 min-h-10.5",
15142
15214
  value: selectedSort,
15143
- onChange: setSelectedSort,
15215
+ onChange: handleSelectedSortChange,
15144
15216
  items: sortItems,
15145
15217
  contentClassName: "py-2",
15146
15218
  triggerClassName: "rounded-agg-lg!"
@@ -15157,7 +15229,7 @@ var EventList = ({
15157
15229
  ariaLabel: labels.eventList.tabsAria(title2),
15158
15230
  className: "agg-event-list-tabs min-w-0 flex-1",
15159
15231
  activeTab: activeTabValue,
15160
- onTabChange: setActiveTabValue,
15232
+ onTabChange: handleActiveTabChange,
15161
15233
  overflowBehavior: "select"
15162
15234
  }
15163
15235
  ),
@@ -15167,7 +15239,7 @@ var EventList = ({
15167
15239
  ariaLabel: labels.eventList.sortByLabel,
15168
15240
  className: "min-w-0 flex-1 md:min-w-[144px]",
15169
15241
  value: selectedSort,
15170
- onChange: setSelectedSort,
15242
+ onChange: handleSelectedSortChange,
15171
15243
  items: sortItems,
15172
15244
  contentClassName: "rounded-[12px] py-2 shadow-[0_8px_16px_rgba(0,0,0,0.1)]"
15173
15245
  }
package/dist/events.mjs CHANGED
@@ -17,13 +17,13 @@ import {
17
17
  orderbookRowLimitDefault,
18
18
  resolveEventDetailsSyncKey,
19
19
  useCenterOrderbookSpread
20
- } from "./chunk-V5CRUO6S.mjs";
20
+ } from "./chunk-C4GFVJ62.mjs";
21
21
  import {
22
22
  formatProbabilityCents,
23
23
  resolveOrderBookRows,
24
24
  resolveUnifiedOrderBookEntries
25
- } from "./chunk-6STRIKUA.mjs";
26
- import "./chunk-N7UPPT5J.mjs";
25
+ } from "./chunk-WYCSTAN7.mjs";
26
+ import "./chunk-RDBMHBR2.mjs";
27
27
  export {
28
28
  EventList,
29
29
  EventListItem,