@lifi/widget 4.1.0 → 4.2.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 (204) hide show
  1. package/dist/esm/AppDefault.js +14 -0
  2. package/dist/esm/AppDefault.js.map +1 -1
  3. package/dist/esm/components/AmountInput/AmountInput.js +2 -1
  4. package/dist/esm/components/AmountInput/AmountInput.js.map +1 -1
  5. package/dist/esm/components/AmountInput/AmountInputEndAdornment.js +4 -2
  6. package/dist/esm/components/AmountInput/AmountInputEndAdornment.js.map +1 -1
  7. package/dist/esm/components/AmountInput/AmountInputEndAdornment.style.js +1 -1
  8. package/dist/esm/components/AmountInput/AmountInputEndAdornment.style.js.map +1 -1
  9. package/dist/esm/components/AmountInput/PriceFormHelperText.js +4 -2
  10. package/dist/esm/components/AmountInput/PriceFormHelperText.js.map +1 -1
  11. package/dist/esm/components/AmountInputCard/AmountInputCard.style.js +98 -0
  12. package/dist/esm/components/AmountInputCard/AmountInputCard.style.js.map +1 -0
  13. package/dist/esm/components/AmountInputCard/AmountInputCardPair.js +25 -0
  14. package/dist/esm/components/AmountInputCard/AmountInputCardPair.js.map +1 -0
  15. package/dist/esm/components/AmountInputCard/BalanceDisplay.js +35 -0
  16. package/dist/esm/components/AmountInputCard/BalanceDisplay.js.map +1 -0
  17. package/dist/esm/components/AmountInputCard/BalanceDisplay.style.js +11 -0
  18. package/dist/esm/components/AmountInputCard/BalanceDisplay.style.js.map +1 -0
  19. package/dist/esm/components/AmountInputCard/FiatValueToggle.js +41 -0
  20. package/dist/esm/components/AmountInputCard/FiatValueToggle.js.map +1 -0
  21. package/dist/esm/components/AmountInputCard/PercentageChips.js +80 -0
  22. package/dist/esm/components/AmountInputCard/PercentageChips.js.map +1 -0
  23. package/dist/esm/components/AmountInputCard/PercentageChips.style.js +43 -0
  24. package/dist/esm/components/AmountInputCard/PercentageChips.style.js.map +1 -0
  25. package/dist/esm/components/AmountInputCard/ReceiveAmountCard.js +137 -0
  26. package/dist/esm/components/AmountInputCard/ReceiveAmountCard.js.map +1 -0
  27. package/dist/esm/components/AmountInputCard/SendAmountCard.js +102 -0
  28. package/dist/esm/components/AmountInputCard/SendAmountCard.js.map +1 -0
  29. package/dist/esm/components/Avatar/Avatar.js +12 -3
  30. package/dist/esm/components/Avatar/Avatar.js.map +1 -1
  31. package/dist/esm/components/Chains/VirtualizedChainList.js +2 -1
  32. package/dist/esm/components/Chains/VirtualizedChainList.js.map +1 -1
  33. package/dist/esm/components/Header/HeaderNavigationTabs.js +14 -1
  34. package/dist/esm/components/Header/HeaderNavigationTabs.js.map +1 -1
  35. package/dist/esm/components/IconCircle/IconCircle.style.js +1 -1
  36. package/dist/esm/components/LimitOrderSettings/LimitOrderSettings.js +99 -0
  37. package/dist/esm/components/LimitOrderSettings/LimitOrderSettings.js.map +1 -0
  38. package/dist/esm/components/LimitOrderSettings/LimitOrderSettings.style.js +52 -0
  39. package/dist/esm/components/LimitOrderSettings/LimitOrderSettings.style.js.map +1 -0
  40. package/dist/esm/components/LimitPriceCard/LimitPriceCard.js +115 -0
  41. package/dist/esm/components/LimitPriceCard/LimitPriceCard.js.map +1 -0
  42. package/dist/esm/components/LimitPriceCard/LimitPriceCard.style.js +89 -0
  43. package/dist/esm/components/LimitPriceCard/LimitPriceCard.style.js.map +1 -0
  44. package/dist/esm/components/LimitPriceCard/LimitPricePresets.js +91 -0
  45. package/dist/esm/components/LimitPriceCard/LimitPricePresets.js.map +1 -0
  46. package/dist/esm/components/RouteCard/RouteProviderCard.js +118 -0
  47. package/dist/esm/components/RouteCard/RouteProviderCard.js.map +1 -0
  48. package/dist/esm/components/Routes/LimitOrderRoutes.js +34 -0
  49. package/dist/esm/components/Routes/LimitOrderRoutes.js.map +1 -0
  50. package/dist/esm/components/Routes/Routes.js +2 -2
  51. package/dist/esm/components/Routes/Routes.js.map +1 -1
  52. package/dist/esm/components/SettingsPanel/SettingsPanel.js +51 -0
  53. package/dist/esm/components/SettingsPanel/SettingsPanel.js.map +1 -0
  54. package/dist/esm/components/SettingsPanel/SettingsPanel.style.js +33 -0
  55. package/dist/esm/components/SettingsPanel/SettingsPanel.style.js.map +1 -0
  56. package/dist/esm/components/SettingsPanel/utils.js +14 -0
  57. package/dist/esm/components/SettingsPanel/utils.js.map +1 -0
  58. package/dist/esm/components/SwapButton/SwapButton.js +50 -0
  59. package/dist/esm/components/SwapButton/SwapButton.js.map +1 -0
  60. package/dist/esm/components/SwapButton/SwapButton.style.js +24 -0
  61. package/dist/esm/components/SwapButton/SwapButton.style.js.map +1 -0
  62. package/dist/esm/components/TokenPillButton/TokenPillButton.js +52 -0
  63. package/dist/esm/components/TokenPillButton/TokenPillButton.js.map +1 -0
  64. package/dist/esm/components/TokenPillButton/TokenPillButton.style.js +39 -0
  65. package/dist/esm/components/TokenPillButton/TokenPillButton.style.js.map +1 -0
  66. package/dist/esm/config/version.d.ts +1 -1
  67. package/dist/esm/config/version.js +1 -1
  68. package/dist/esm/config/version.js.map +1 -1
  69. package/dist/esm/hooks/useChainSearch.js +2 -1
  70. package/dist/esm/hooks/useChainSearch.js.map +1 -1
  71. package/dist/esm/hooks/useLimitMarketRate.js +24 -0
  72. package/dist/esm/hooks/useLimitMarketRate.js.map +1 -0
  73. package/dist/esm/hooks/useLinkedLimitFields.js +49 -0
  74. package/dist/esm/hooks/useLinkedLimitFields.js.map +1 -0
  75. package/dist/esm/hooks/useRoutes.js +23 -6
  76. package/dist/esm/hooks/useRoutes.js.map +1 -1
  77. package/dist/esm/hooks/useTokens.js +16 -14
  78. package/dist/esm/hooks/useTokens.js.map +1 -1
  79. package/dist/esm/hooks/useWideVariant.js +5 -2
  80. package/dist/esm/hooks/useWideVariant.js.map +1 -1
  81. package/dist/esm/i18n/en.json +22 -0
  82. package/dist/esm/index.d.ts +2 -2
  83. package/dist/esm/pages/MainPage/LimitPageContent.js +23 -0
  84. package/dist/esm/pages/MainPage/LimitPageContent.js.map +1 -0
  85. package/dist/esm/pages/MainPage/MainPage.js +19 -22
  86. package/dist/esm/pages/MainPage/MainPage.js.map +1 -1
  87. package/dist/esm/pages/MainPage/MainPageActions.js +28 -0
  88. package/dist/esm/pages/MainPage/MainPageActions.js.map +1 -0
  89. package/dist/esm/pages/MainPage/ReviewButton.js +9 -2
  90. package/dist/esm/pages/MainPage/ReviewButton.js.map +1 -1
  91. package/dist/esm/pages/RoutePriorityPage.js +48 -0
  92. package/dist/esm/pages/RoutePriorityPage.js.map +1 -0
  93. package/dist/esm/pages/SettingsPage/BridgeAndExchangeSettings.js +2 -2
  94. package/dist/esm/pages/SettingsPage/BridgeAndExchangeSettings.js.map +1 -1
  95. package/dist/esm/pages/SettingsPage/RoutePrioritySettings.js +12 -27
  96. package/dist/esm/pages/SettingsPage/RoutePrioritySettings.js.map +1 -1
  97. package/dist/esm/pages/SettingsPage/SlippageSettings/SlippagePage.js +133 -0
  98. package/dist/esm/pages/SettingsPage/SlippageSettings/SlippagePage.js.map +1 -0
  99. package/dist/esm/pages/SettingsPage/SlippageSettings/SlippageSettings.js +14 -72
  100. package/dist/esm/pages/SettingsPage/SlippageSettings/SlippageSettings.js.map +1 -1
  101. package/dist/esm/pages/SettingsPage/SlippageSettings/SlippageSettings.style.js +26 -14
  102. package/dist/esm/pages/SettingsPage/SlippageSettings/SlippageSettings.style.js.map +1 -1
  103. package/dist/esm/pages/SettingsPage/ThemeSettings.js +4 -0
  104. package/dist/esm/pages/SettingsPage/ThemeSettings.js.map +1 -1
  105. package/dist/esm/pages/TransactionPage/TransactionReview.js +4 -1
  106. package/dist/esm/pages/TransactionPage/TransactionReview.js.map +1 -1
  107. package/dist/esm/providers/I18nProvider/I18nProvider.js +1 -1
  108. package/dist/esm/providers/I18nProvider/enResource.d.ts +1 -1
  109. package/dist/esm/providers/I18nProvider/enResource.js +1 -1
  110. package/dist/esm/providers/I18nProvider/types.d.ts +2 -2
  111. package/dist/esm/providers/SDKClientProvider.js +25 -24
  112. package/dist/esm/providers/SDKClientProvider.js.map +1 -1
  113. package/dist/esm/providers/WidgetProvider/WidgetProvider.js +22 -21
  114. package/dist/esm/providers/WidgetProvider/WidgetProvider.js.map +1 -1
  115. package/dist/esm/stores/form/URLSearchParamsBuilder.js +14 -3
  116. package/dist/esm/stores/form/URLSearchParamsBuilder.js.map +1 -1
  117. package/dist/esm/stores/form/createFormStore.js +6 -2
  118. package/dist/esm/stores/form/createFormStore.js.map +1 -1
  119. package/dist/esm/stores/form/getDefaultValuesFromQueryString.js +3 -0
  120. package/dist/esm/stores/form/getDefaultValuesFromQueryString.js.map +1 -1
  121. package/dist/esm/stores/form/types.d.ts +9 -1
  122. package/dist/esm/stores/form/types.d.ts.map +1 -1
  123. package/dist/esm/stores/form/types.js.map +1 -1
  124. package/dist/esm/stores/form/useClearAmountFields.js +1 -0
  125. package/dist/esm/stores/form/useClearAmountFields.js.map +1 -1
  126. package/dist/esm/stores/navigationTabs/useNavigationTabsStore.js +4 -2
  127. package/dist/esm/stores/navigationTabs/useNavigationTabsStore.js.map +1 -1
  128. package/dist/esm/stores/navigationTabs/utils.js +38 -8
  129. package/dist/esm/stores/navigationTabs/utils.js.map +1 -1
  130. package/dist/esm/types/events.d.ts +10 -1
  131. package/dist/esm/types/events.d.ts.map +1 -1
  132. package/dist/esm/types/events.js +2 -0
  133. package/dist/esm/types/events.js.map +1 -1
  134. package/dist/esm/types/widget.d.ts +9 -0
  135. package/dist/esm/types/widget.d.ts.map +1 -1
  136. package/dist/esm/types/widget.js.map +1 -1
  137. package/dist/esm/utils/format.d.ts +1 -1
  138. package/dist/esm/utils/format.d.ts.map +1 -1
  139. package/dist/esm/utils/format.js +2 -2
  140. package/dist/esm/utils/format.js.map +1 -1
  141. package/dist/esm/utils/limitOrder.js +61 -0
  142. package/dist/esm/utils/limitOrder.js.map +1 -0
  143. package/dist/esm/utils/navigationRoutes.d.ts +2 -0
  144. package/dist/esm/utils/navigationRoutes.d.ts.map +1 -1
  145. package/dist/esm/utils/navigationRoutes.js +6 -0
  146. package/dist/esm/utils/navigationRoutes.js.map +1 -1
  147. package/package.json +11 -11
  148. package/src/AppDefault.tsx +16 -0
  149. package/src/components/AmountInput/AmountInputEndAdornment.style.ts +1 -1
  150. package/src/components/AmountInput/AmountInputEndAdornment.tsx +5 -2
  151. package/src/components/AmountInputCard/AmountInputCard.style.tsx +157 -0
  152. package/src/components/AmountInputCard/AmountInputCardPair.tsx +25 -0
  153. package/src/components/AmountInputCard/BalanceDisplay.style.tsx +9 -0
  154. package/src/components/AmountInputCard/BalanceDisplay.tsx +46 -0
  155. package/src/components/AmountInputCard/FiatValueToggle.tsx +55 -0
  156. package/src/components/AmountInputCard/PercentageChips.style.tsx +60 -0
  157. package/src/components/AmountInputCard/PercentageChips.tsx +100 -0
  158. package/src/components/AmountInputCard/ReceiveAmountCard.tsx +219 -0
  159. package/src/components/AmountInputCard/SendAmountCard.tsx +179 -0
  160. package/src/components/Avatar/Avatar.tsx +8 -3
  161. package/src/components/Header/HeaderNavigationTabs.tsx +19 -2
  162. package/src/components/LimitOrderSettings/LimitOrderSettings.style.tsx +69 -0
  163. package/src/components/LimitOrderSettings/LimitOrderSettings.tsx +124 -0
  164. package/src/components/LimitPriceCard/LimitPriceCard.style.tsx +103 -0
  165. package/src/components/LimitPriceCard/LimitPriceCard.tsx +153 -0
  166. package/src/components/LimitPriceCard/LimitPricePresets.tsx +139 -0
  167. package/src/components/RouteCard/RouteProviderCard.tsx +113 -0
  168. package/src/components/Routes/LimitOrderRoutes.tsx +64 -0
  169. package/src/components/Routes/Routes.tsx +3 -2
  170. package/src/components/SettingsPanel/SettingsPanel.style.tsx +41 -0
  171. package/src/components/SettingsPanel/SettingsPanel.tsx +73 -0
  172. package/src/components/SettingsPanel/utils.ts +27 -0
  173. package/src/components/SwapButton/SwapButton.style.tsx +28 -0
  174. package/src/components/SwapButton/SwapButton.tsx +71 -0
  175. package/src/components/TokenPillButton/TokenPillButton.style.tsx +50 -0
  176. package/src/components/TokenPillButton/TokenPillButton.tsx +81 -0
  177. package/src/config/version.ts +1 -1
  178. package/src/hooks/useLimitMarketRate.ts +39 -0
  179. package/src/hooks/useLinkedLimitFields.ts +74 -0
  180. package/src/hooks/useRoutes.ts +45 -4
  181. package/src/hooks/useWideVariant.ts +8 -2
  182. package/src/pages/MainPage/LimitPageContent.tsx +18 -0
  183. package/src/pages/MainPage/MainPage.tsx +43 -30
  184. package/src/pages/MainPage/MainPageActions.tsx +35 -0
  185. package/src/pages/MainPage/ReviewButton.tsx +13 -1
  186. package/src/pages/RoutePriorityPage.tsx +55 -0
  187. package/src/pages/SettingsPage/RoutePrioritySettings.tsx +14 -38
  188. package/src/pages/SettingsPage/SlippageSettings/SlippagePage.tsx +176 -0
  189. package/src/pages/SettingsPage/SlippageSettings/SlippageSettings.style.tsx +32 -25
  190. package/src/pages/SettingsPage/SlippageSettings/SlippageSettings.tsx +14 -128
  191. package/src/pages/SettingsPage/ThemeSettings.tsx +4 -0
  192. package/src/stores/form/URLSearchParamsBuilder.tsx +25 -3
  193. package/src/stores/form/createFormStore.ts +7 -3
  194. package/src/stores/form/getDefaultValuesFromQueryString.ts +11 -0
  195. package/src/stores/form/types.ts +14 -1
  196. package/src/stores/form/useClearAmountFields.ts +1 -0
  197. package/src/stores/navigationTabs/types.ts +6 -0
  198. package/src/stores/navigationTabs/useNavigationTabsStore.tsx +8 -3
  199. package/src/stores/navigationTabs/utils.ts +67 -5
  200. package/src/types/events.ts +12 -0
  201. package/src/types/widget.ts +9 -0
  202. package/src/utils/format.ts +6 -2
  203. package/src/utils/limitOrder.ts +88 -0
  204. package/src/utils/navigationRoutes.ts +6 -0
@@ -0,0 +1,34 @@
1
+ import { useFieldActions } from "../../stores/form/useFieldActions.js";
2
+ import { useFieldValues } from "../../stores/form/useFieldValues.js";
3
+ import { useRoutes } from "../../hooks/useRoutes.js";
4
+ import { useToAddressRequirements } from "../../hooks/useToAddressRequirements.js";
5
+ import { RouteNotFoundCard } from "../RouteCard/RouteNotFoundCard.js";
6
+ import { RouteProviderCard, RouteProviderCardSkeleton } from "../RouteCard/RouteProviderCard.js";
7
+ import { Stack } from "@mui/material";
8
+ import { jsx } from "react/jsx-runtime";
9
+ //#region src/components/Routes/LimitOrderRoutes.tsx
10
+ const LimitOrderRoutes = (props) => {
11
+ const { routes, isLoading, isFetching, isFetched } = useRoutes();
12
+ const [toAddress, selectedRouteId] = useFieldValues("toAddress", "selectedRouteId");
13
+ const { setFieldValue } = useFieldActions();
14
+ const { requiredToAddress } = useToAddressRequirements();
15
+ const currentRoute = routes?.[0];
16
+ if (!currentRoute && !isLoading && !isFetching && !isFetched) return null;
17
+ const allowInteraction = !(currentRoute && requiredToAddress && !toAddress);
18
+ const activeRouteId = routes?.find((route) => route.id === selectedRouteId)?.id ?? currentRoute?.id;
19
+ return /* @__PURE__ */ jsx(Stack, {
20
+ direction: "column",
21
+ spacing: 1,
22
+ sx: props.sx,
23
+ className: props.className,
24
+ children: isLoading && !currentRoute ? Array.from({ length: 2 }).map((_, index) => /* @__PURE__ */ jsx(RouteProviderCardSkeleton, {}, index)) : !currentRoute ? /* @__PURE__ */ jsx(RouteNotFoundCard, {}) : routes?.map((route) => /* @__PURE__ */ jsx(RouteProviderCard, {
25
+ route,
26
+ active: route.id === activeRouteId,
27
+ onClick: allowInteraction ? () => setFieldValue("selectedRouteId", route.id) : void 0
28
+ }, route.id))
29
+ });
30
+ };
31
+ //#endregion
32
+ export { LimitOrderRoutes };
33
+
34
+ //# sourceMappingURL=LimitOrderRoutes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LimitOrderRoutes.js","names":[],"sources":["../../../../src/components/Routes/LimitOrderRoutes.tsx"],"sourcesContent":["import { Stack } from '@mui/material'\nimport { useRoutes } from '../../hooks/useRoutes.js'\nimport { useToAddressRequirements } from '../../hooks/useToAddressRequirements.js'\nimport { useFieldActions } from '../../stores/form/useFieldActions.js'\nimport { useFieldValues } from '../../stores/form/useFieldValues.js'\nimport type { CardProps } from '../Card/Card.js'\nimport { RouteNotFoundCard } from '../RouteCard/RouteNotFoundCard.js'\nimport {\n RouteProviderCard,\n RouteProviderCardSkeleton,\n} from '../RouteCard/RouteProviderCard.js'\n\nexport const LimitOrderRoutes: React.FC<CardProps> = (props) => {\n const { routes, isLoading, isFetching, isFetched } = useRoutes()\n const [toAddress, selectedRouteId] = useFieldValues(\n 'toAddress',\n 'selectedRouteId'\n )\n const { setFieldValue } = useFieldActions()\n const { requiredToAddress } = useToAddressRequirements()\n\n const currentRoute = routes?.[0]\n\n if (!currentRoute && !isLoading && !isFetching && !isFetched) {\n return null\n }\n\n const toAddressUnsatisfied = currentRoute && requiredToAddress && !toAddress\n const allowInteraction = !toAddressUnsatisfied\n\n const activeRouteId =\n routes?.find((route) => route.id === selectedRouteId)?.id ??\n currentRoute?.id\n\n return (\n <Stack\n direction=\"column\"\n spacing={1}\n sx={props.sx}\n className={props.className}\n >\n {isLoading && !currentRoute ? (\n Array.from({ length: 2 }).map((_, index) => (\n <RouteProviderCardSkeleton key={index} />\n ))\n ) : !currentRoute ? (\n <RouteNotFoundCard />\n ) : (\n routes?.map((route) => (\n <RouteProviderCard\n key={route.id}\n route={route}\n active={route.id === activeRouteId}\n onClick={\n allowInteraction\n ? () => setFieldValue('selectedRouteId', route.id)\n : undefined\n }\n />\n ))\n )}\n </Stack>\n )\n}\n"],"mappings":";;;;;;;;;AAYA,MAAa,oBAAyC,UAAU;CAC9D,MAAM,EAAE,QAAQ,WAAW,YAAY,cAAc,UAAU;CAC/D,MAAM,CAAC,WAAW,mBAAmB,eACnC,aACA,iBACF;CACA,MAAM,EAAE,kBAAkB,gBAAgB;CAC1C,MAAM,EAAE,sBAAsB,yBAAyB;CAEvD,MAAM,eAAe,SAAS;CAE9B,IAAI,CAAC,gBAAgB,CAAC,aAAa,CAAC,cAAc,CAAC,WACjD,OAAO;CAIT,MAAM,mBAAmB,EADI,gBAAgB,qBAAqB,CAAC;CAGnE,MAAM,gBACJ,QAAQ,MAAM,UAAU,MAAM,OAAO,eAAe,CAAC,EAAE,MACvD,cAAc;CAEhB,OACE,oBAAC,OAAD;EACE,WAAU;EACV,SAAS;EACT,IAAI,MAAM;EACV,WAAW,MAAM;YAEhB,aAAa,CAAC,eACb,MAAM,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,UAChC,oBAAC,2BAAD,CAAwC,GAAR,KAAQ,CACzC,IACC,CAAC,eACH,oBAAC,mBAAD,CAAoB,CAAA,IAEpB,QAAQ,KAAK,UACX,oBAAC,mBAAD;GAES;GACP,QAAQ,MAAM,OAAO;GACrB,SACE,yBACU,cAAc,mBAAmB,MAAM,EAAE,IAC/C,KAAA;EAEP,GARM,MAAM,EAQZ,CACF;CAEE,CAAA;AAEX"}
@@ -16,7 +16,7 @@ import { useTranslation } from "react-i18next";
16
16
  const Routes = (props) => {
17
17
  const { t } = useTranslation();
18
18
  const navigate = useNavigate();
19
- const { mode, modeOptions, showSingleRoute } = useWidgetConfig();
19
+ const { mode, modeOptions, showSingleRoute, defaultUI } = useWidgetConfig();
20
20
  const { routes, isLoading, isFetching, isFetched, dataUpdatedAt, refetchTime, refetch } = useRoutes();
21
21
  const currentRoute = routes?.[0];
22
22
  if (!currentRoute && !isLoading && !isFetching && !isFetched) return null;
@@ -28,7 +28,7 @@ const Routes = (props) => {
28
28
  return /* @__PURE__ */ jsxs(Card$1, {
29
29
  ...props,
30
30
  children: [
31
- /* @__PURE__ */ jsx(CardTitle, { children: title }),
31
+ defaultUI?.layout === "cards" ? null : /* @__PURE__ */ jsx(CardTitle, { children: title }),
32
32
  /* @__PURE__ */ jsx(ProgressToNextUpdate, {
33
33
  updatedAt: dataUpdatedAt || Date.now(),
34
34
  timeToUpdate: refetchTime,
@@ -1 +1 @@
1
- {"version":3,"file":"Routes.js","names":["Card"],"sources":["../../../../src/components/Routes/Routes.tsx"],"sourcesContent":["import { Box, Collapse } from '@mui/material'\nimport { useNavigate } from '@tanstack/react-router'\nimport { useTranslation } from 'react-i18next'\nimport { useRoutes } from '../../hooks/useRoutes.js'\nimport { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'\nimport { navigationRoutes } from '../../utils/navigationRoutes.js'\nimport { ButtonTertiary } from '../ButtonTertiary.js'\nimport type { CardProps } from '../Card/Card.js'\nimport { Card } from '../Card/Card.js'\nimport { CardTitle } from '../Card/CardTitle.js'\nimport { ProgressToNextUpdate } from '../ProgressToNextUpdate.js'\nimport { RouteCard } from '../RouteCard/RouteCard.js'\nimport { RouteCardSkeleton } from '../RouteCard/RouteCardSkeleton.js'\nimport { RouteNotFoundCard } from '../RouteCard/RouteNotFoundCard.js'\n\nexport const Routes: React.FC<CardProps> = (props) => {\n const { t } = useTranslation()\n const navigate = useNavigate()\n const { mode, modeOptions, showSingleRoute } = useWidgetConfig()\n const {\n routes,\n isLoading,\n isFetching,\n isFetched,\n dataUpdatedAt,\n refetchTime,\n refetch,\n } = useRoutes()\n\n const currentRoute = routes?.[0]\n\n if (!currentRoute && !isLoading && !isFetching && !isFetched) {\n return null\n }\n\n const handleCardClick = () => {\n navigate({ to: navigationRoutes.routes })\n }\n\n const routeNotFound = !currentRoute && !isLoading && !isFetching\n const onlySingleRoute = mode === 'refuel' || showSingleRoute\n const showAll =\n !onlySingleRoute && !routeNotFound && (routes?.length ?? 0) > 1\n\n const title =\n mode === 'custom'\n ? modeOptions?.custom?.type === 'deposit'\n ? t('header.receive')\n : t('header.youPay')\n : t('header.receive')\n\n return (\n <Card {...props}>\n <CardTitle>{title}</CardTitle>\n <ProgressToNextUpdate\n updatedAt={dataUpdatedAt || Date.now()}\n timeToUpdate={refetchTime}\n isLoading={isFetching}\n onClick={() => refetch()}\n sx={{\n position: 'absolute',\n top: 8,\n right: 8,\n }}\n />\n <Box\n sx={{\n p: 2,\n }}\n >\n {isLoading && !currentRoute ? (\n <RouteCardSkeleton variant=\"cardless\" />\n ) : !currentRoute ? (\n <RouteNotFoundCard />\n ) : (\n <RouteCard route={currentRoute} variant=\"cardless\" active />\n )}\n\n <Collapse timeout={225} in={showAll} unmountOnExit mountOnEnter>\n <Box\n sx={{\n mt: 2,\n }}\n >\n <ButtonTertiary onClick={handleCardClick} fullWidth>\n {t('button.showAll')}\n </ButtonTertiary>\n </Box>\n </Collapse>\n </Box>\n </Card>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;AAeA,MAAa,UAA+B,UAAU;CACpD,MAAM,EAAE,MAAM,eAAe;CAC7B,MAAM,WAAW,YAAY;CAC7B,MAAM,EAAE,MAAM,aAAa,oBAAoB,gBAAgB;CAC/D,MAAM,EACJ,QACA,WACA,YACA,WACA,eACA,aACA,YACE,UAAU;CAEd,MAAM,eAAe,SAAS;CAE9B,IAAI,CAAC,gBAAgB,CAAC,aAAa,CAAC,cAAc,CAAC,WACjD,OAAO;CAGT,MAAM,wBAAwB;EAC5B,SAAS,EAAE,IAAI,iBAAiB,OAAO,CAAC;CAC1C;CAIA,MAAM,UACJ,EAFsB,SAAS,YAAY,oBAEvB,EAHA,CAAC,gBAAgB,CAAC,aAAa,CAAC,gBAGb,QAAQ,UAAU,KAAK;CAEhE,MAAM,QACJ,SAAS,WACL,aAAa,QAAQ,SAAS,YAC5B,EAAE,gBAAgB,IAClB,EAAE,eAAe,IACnB,EAAE,gBAAgB;CAExB,OACE,qBAACA,QAAD;EAAM,GAAI;YAAV;GACE,oBAAC,WAAD,EAAA,UAAY,MAAiB,CAAA;GAC7B,oBAAC,sBAAD;IACE,WAAW,iBAAiB,KAAK,IAAI;IACrC,cAAc;IACd,WAAW;IACX,eAAe,QAAQ;IACvB,IAAI;KACF,UAAU;KACV,KAAK;KACL,OAAO;IACT;GACD,CAAA;GACD,qBAAC,KAAD;IACE,IAAI,EACF,GAAG,EACL;cAHF,CAKG,aAAa,CAAC,eACb,oBAAC,mBAAD,EAAmB,SAAQ,WAAY,CAAA,IACrC,CAAC,eACH,oBAAC,mBAAD,CAAoB,CAAA,IAEpB,oBAAC,WAAD;KAAW,OAAO;KAAc,SAAQ;KAAW,QAAA;IAAQ,CAAA,GAG7D,oBAAC,UAAD;KAAU,SAAS;KAAK,IAAI;KAAS,eAAA;KAAc,cAAA;eACjD,oBAAC,KAAD;MACE,IAAI,EACF,IAAI,EACN;gBAEA,oBAAC,gBAAD;OAAgB,SAAS;OAAiB,WAAA;iBACvC,EAAE,gBAAgB;MACL,CAAA;KACb,CAAA;IACG,CAAA,CACP;;EACD;;AAEV"}
1
+ {"version":3,"file":"Routes.js","names":["Card"],"sources":["../../../../src/components/Routes/Routes.tsx"],"sourcesContent":["import { Box, Collapse } from '@mui/material'\nimport { useNavigate } from '@tanstack/react-router'\nimport { useTranslation } from 'react-i18next'\nimport { useRoutes } from '../../hooks/useRoutes.js'\nimport { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'\nimport { navigationRoutes } from '../../utils/navigationRoutes.js'\nimport { ButtonTertiary } from '../ButtonTertiary.js'\nimport type { CardProps } from '../Card/Card.js'\nimport { Card } from '../Card/Card.js'\nimport { CardTitle } from '../Card/CardTitle.js'\nimport { ProgressToNextUpdate } from '../ProgressToNextUpdate.js'\nimport { RouteCard } from '../RouteCard/RouteCard.js'\nimport { RouteCardSkeleton } from '../RouteCard/RouteCardSkeleton.js'\nimport { RouteNotFoundCard } from '../RouteCard/RouteNotFoundCard.js'\n\nexport const Routes: React.FC<CardProps> = (props) => {\n const { t } = useTranslation()\n const navigate = useNavigate()\n const { mode, modeOptions, showSingleRoute, defaultUI } = useWidgetConfig()\n const {\n routes,\n isLoading,\n isFetching,\n isFetched,\n dataUpdatedAt,\n refetchTime,\n refetch,\n } = useRoutes()\n\n const currentRoute = routes?.[0]\n\n if (!currentRoute && !isLoading && !isFetching && !isFetched) {\n return null\n }\n\n const handleCardClick = () => {\n navigate({ to: navigationRoutes.routes })\n }\n\n const routeNotFound = !currentRoute && !isLoading && !isFetching\n const onlySingleRoute = mode === 'refuel' || showSingleRoute\n const showAll =\n !onlySingleRoute && !routeNotFound && (routes?.length ?? 0) > 1\n\n const title =\n mode === 'custom'\n ? modeOptions?.custom?.type === 'deposit'\n ? t('header.receive')\n : t('header.youPay')\n : t('header.receive')\n\n return (\n <Card {...props}>\n {/* The cards layout's Receive card already carries this header. */}\n {defaultUI?.layout === 'cards' ? null : <CardTitle>{title}</CardTitle>}\n <ProgressToNextUpdate\n updatedAt={dataUpdatedAt || Date.now()}\n timeToUpdate={refetchTime}\n isLoading={isFetching}\n onClick={() => refetch()}\n sx={{\n position: 'absolute',\n top: 8,\n right: 8,\n }}\n />\n <Box\n sx={{\n p: 2,\n }}\n >\n {isLoading && !currentRoute ? (\n <RouteCardSkeleton variant=\"cardless\" />\n ) : !currentRoute ? (\n <RouteNotFoundCard />\n ) : (\n <RouteCard route={currentRoute} variant=\"cardless\" active />\n )}\n\n <Collapse timeout={225} in={showAll} unmountOnExit mountOnEnter>\n <Box\n sx={{\n mt: 2,\n }}\n >\n <ButtonTertiary onClick={handleCardClick} fullWidth>\n {t('button.showAll')}\n </ButtonTertiary>\n </Box>\n </Collapse>\n </Box>\n </Card>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;AAeA,MAAa,UAA+B,UAAU;CACpD,MAAM,EAAE,MAAM,eAAe;CAC7B,MAAM,WAAW,YAAY;CAC7B,MAAM,EAAE,MAAM,aAAa,iBAAiB,cAAc,gBAAgB;CAC1E,MAAM,EACJ,QACA,WACA,YACA,WACA,eACA,aACA,YACE,UAAU;CAEd,MAAM,eAAe,SAAS;CAE9B,IAAI,CAAC,gBAAgB,CAAC,aAAa,CAAC,cAAc,CAAC,WACjD,OAAO;CAGT,MAAM,wBAAwB;EAC5B,SAAS,EAAE,IAAI,iBAAiB,OAAO,CAAC;CAC1C;CAIA,MAAM,UACJ,EAFsB,SAAS,YAAY,oBAEvB,EAHA,CAAC,gBAAgB,CAAC,aAAa,CAAC,gBAGb,QAAQ,UAAU,KAAK;CAEhE,MAAM,QACJ,SAAS,WACL,aAAa,QAAQ,SAAS,YAC5B,EAAE,gBAAgB,IAClB,EAAE,eAAe,IACnB,EAAE,gBAAgB;CAExB,OACE,qBAACA,QAAD;EAAM,GAAI;YAAV;GAEG,WAAW,WAAW,UAAU,OAAO,oBAAC,WAAD,EAAA,UAAY,MAAiB,CAAA;GACrE,oBAAC,sBAAD;IACE,WAAW,iBAAiB,KAAK,IAAI;IACrC,cAAc;IACd,WAAW;IACX,eAAe,QAAQ;IACvB,IAAI;KACF,UAAU;KACV,KAAK;KACL,OAAO;IACT;GACD,CAAA;GACD,qBAAC,KAAD;IACE,IAAI,EACF,GAAG,EACL;cAHF,CAKG,aAAa,CAAC,eACb,oBAAC,mBAAD,EAAmB,SAAQ,WAAY,CAAA,IACrC,CAAC,eACH,oBAAC,mBAAD,CAAoB,CAAA,IAEpB,oBAAC,WAAD;KAAW,OAAO;KAAc,SAAQ;KAAW,QAAA;IAAQ,CAAA,GAG7D,oBAAC,UAAD;KAAU,SAAS;KAAK,IAAI;KAAS,eAAA;KAAc,cAAA;eACjD,oBAAC,KAAD;MACE,IAAI,EACF,IAAI,EACN;gBAEA,oBAAC,gBAAD;OAAgB,SAAS;OAAiB,WAAA;iBACvC,EAAE,gBAAgB;MACL,CAAA;KACb,CAAA;IACG,CAAA,CACP;;EACD;;AAEV"}
@@ -0,0 +1,51 @@
1
+ import { useSettingsStore } from "../../stores/settings/SettingsStore.js";
2
+ import { navigationRoutes } from "../../utils/navigationRoutes.js";
3
+ import { useSplitMode } from "../../stores/navigationTabs/useNavigationTabsStore.js";
4
+ import { Card } from "../Card/Card.js";
5
+ import { useSettings } from "../../stores/settings/useSettings.js";
6
+ import { SettingsPanelButton, SettingsPanelContainer, SettingsPanelTitle, SettingsPanelValue } from "./SettingsPanel.style.js";
7
+ import { bridgeSettingsPanelKeys, swapSettingsPanelKeys } from "./utils.js";
8
+ import { useNavigate } from "@tanstack/react-router";
9
+ import { jsx, jsxs } from "react/jsx-runtime";
10
+ import { useTranslation } from "react-i18next";
11
+ //#region src/components/SettingsPanel/SettingsPanel.tsx
12
+ const SettingsPanel = (props) => {
13
+ const { t } = useTranslation();
14
+ const navigate = useNavigate();
15
+ const splitMode = useSplitMode();
16
+ const { slippage, routePriority } = useSettings(["slippage", "routePriority"]);
17
+ const [enabledBridges, totalBridges, enabledExchanges, totalExchanges] = useSettingsStore((state) => [
18
+ Object.values(state._enabledBridges).filter(Boolean).length,
19
+ Object.values(state._enabledBridges).length,
20
+ Object.values(state._enabledExchanges).filter(Boolean).length,
21
+ Object.values(state._enabledExchanges).length
22
+ ]);
23
+ const rows = splitMode === "bridge" ? bridgeSettingsPanelKeys : swapSettingsPanelKeys;
24
+ const labelByKey = {
25
+ routePriority: t("settings.routePriority"),
26
+ exchanges: t("settings.enabledExchanges"),
27
+ bridges: t("settings.enabledBridges"),
28
+ slippage: t("settings.slippage")
29
+ };
30
+ const valueByKey = {
31
+ routePriority: routePriority === "FASTEST" ? t("settings.routePriorityOptions.fastest.title") : t("settings.routePriorityOptions.cheapest.title"),
32
+ exchanges: `${enabledExchanges}/${totalExchanges}`,
33
+ bridges: `${enabledBridges}/${totalBridges}`,
34
+ slippage: slippage ? `${slippage}%` : t("button.auto")
35
+ };
36
+ const handleClick = (key) => {
37
+ navigate({ to: `/${navigationRoutes.settings}/${navigationRoutes[key]}` });
38
+ };
39
+ return /* @__PURE__ */ jsx(SettingsPanelContainer, {
40
+ ...props,
41
+ children: rows.map((key) => /* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsxs(SettingsPanelButton, {
42
+ onClick: () => handleClick(key),
43
+ disableRipple: true,
44
+ children: [/* @__PURE__ */ jsx(SettingsPanelTitle, { children: labelByKey[key] }), /* @__PURE__ */ jsx(SettingsPanelValue, { children: valueByKey[key] })]
45
+ }) }, key))
46
+ });
47
+ };
48
+ //#endregion
49
+ export { SettingsPanel };
50
+
51
+ //# sourceMappingURL=SettingsPanel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SettingsPanel.js","names":[],"sources":["../../../../src/components/SettingsPanel/SettingsPanel.tsx"],"sourcesContent":["import type { BoxProps } from '@mui/material'\nimport { useNavigate } from '@tanstack/react-router'\nimport type { JSX } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { useSplitMode } from '../../stores/navigationTabs/useNavigationTabsStore.js'\nimport { useSettingsStore } from '../../stores/settings/SettingsStore.js'\nimport { useSettings } from '../../stores/settings/useSettings.js'\nimport { navigationRoutes } from '../../utils/navigationRoutes.js'\nimport { Card } from '../Card/Card.js'\nimport {\n SettingsPanelButton,\n SettingsPanelContainer,\n SettingsPanelTitle,\n SettingsPanelValue,\n} from './SettingsPanel.style.js'\nimport {\n bridgeSettingsPanelKeys,\n type SettingsPanelKey,\n swapSettingsPanelKeys,\n} from './utils.js'\n\nexport const SettingsPanel: React.FC<BoxProps> = (props): JSX.Element => {\n const { t } = useTranslation()\n const navigate = useNavigate()\n const splitMode = useSplitMode()\n const { slippage, routePriority } = useSettings(['slippage', 'routePriority'])\n const [enabledBridges, totalBridges, enabledExchanges, totalExchanges] =\n useSettingsStore((state) => [\n Object.values(state._enabledBridges).filter(Boolean).length,\n Object.values(state._enabledBridges).length,\n Object.values(state._enabledExchanges).filter(Boolean).length,\n Object.values(state._enabledExchanges).length,\n ])\n\n const rows =\n splitMode === 'bridge' ? bridgeSettingsPanelKeys : swapSettingsPanelKeys\n\n const labelByKey: Record<SettingsPanelKey, string> = {\n routePriority: t('settings.routePriority'),\n exchanges: t('settings.enabledExchanges'),\n bridges: t('settings.enabledBridges'),\n slippage: t('settings.slippage'),\n }\n\n const valueByKey: Record<SettingsPanelKey, string> = {\n routePriority:\n routePriority === 'FASTEST'\n ? t('settings.routePriorityOptions.fastest.title')\n : t('settings.routePriorityOptions.cheapest.title'),\n exchanges: `${enabledExchanges}/${totalExchanges}`,\n bridges: `${enabledBridges}/${totalBridges}`,\n slippage: slippage ? `${slippage}%` : t('button.auto'),\n }\n\n const handleClick = (key: SettingsPanelKey) => {\n navigate({\n to: `/${navigationRoutes.settings}/${navigationRoutes[key]}`,\n })\n }\n\n return (\n <SettingsPanelContainer {...props}>\n {rows.map((key) => (\n <Card key={key}>\n <SettingsPanelButton onClick={() => handleClick(key)} disableRipple>\n <SettingsPanelTitle>{labelByKey[key]}</SettingsPanelTitle>\n <SettingsPanelValue>{valueByKey[key]}</SettingsPanelValue>\n </SettingsPanelButton>\n </Card>\n ))}\n </SettingsPanelContainer>\n )\n}\n"],"mappings":";;;;;;;;;;;AAqBA,MAAa,iBAAqC,UAAuB;CACvE,MAAM,EAAE,MAAM,eAAe;CAC7B,MAAM,WAAW,YAAY;CAC7B,MAAM,YAAY,aAAa;CAC/B,MAAM,EAAE,UAAU,kBAAkB,YAAY,CAAC,YAAY,eAAe,CAAC;CAC7E,MAAM,CAAC,gBAAgB,cAAc,kBAAkB,kBACrD,kBAAkB,UAAU;EAC1B,OAAO,OAAO,MAAM,eAAe,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC;EACrD,OAAO,OAAO,MAAM,eAAe,CAAC,CAAC;EACrC,OAAO,OAAO,MAAM,iBAAiB,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC;EACvD,OAAO,OAAO,MAAM,iBAAiB,CAAC,CAAC;CACzC,CAAC;CAEH,MAAM,OACJ,cAAc,WAAW,0BAA0B;CAErD,MAAM,aAA+C;EACnD,eAAe,EAAE,wBAAwB;EACzC,WAAW,EAAE,2BAA2B;EACxC,SAAS,EAAE,yBAAyB;EACpC,UAAU,EAAE,mBAAmB;CACjC;CAEA,MAAM,aAA+C;EACnD,eACE,kBAAkB,YACd,EAAE,6CAA6C,IAC/C,EAAE,8CAA8C;EACtD,WAAW,GAAG,iBAAiB,GAAG;EAClC,SAAS,GAAG,eAAe,GAAG;EAC9B,UAAU,WAAW,GAAG,SAAS,KAAK,EAAE,aAAa;CACvD;CAEA,MAAM,eAAe,QAA0B;EAC7C,SAAS,EACP,IAAI,IAAI,iBAAiB,SAAS,GAAG,iBAAiB,OACxD,CAAC;CACH;CAEA,OACE,oBAAC,wBAAD;EAAwB,GAAI;YACzB,KAAK,KAAK,QACT,oBAAC,MAAD,EAAA,UACE,qBAAC,qBAAD;GAAqB,eAAe,YAAY,GAAG;GAAG,eAAA;aAAtD,CACE,oBAAC,oBAAD,EAAA,UAAqB,WAAW,KAAyB,CAAA,GACzD,oBAAC,oBAAD,EAAA,UAAqB,WAAW,KAAyB,CAAA,CACtC;KACjB,GALK,GAKL,CACP;CACqB,CAAA;AAE5B"}
@@ -0,0 +1,33 @@
1
+ import { Box, ButtonBase, Typography, styled } from "@mui/material";
2
+ //#region src/components/SettingsPanel/SettingsPanel.style.tsx
3
+ const SettingsPanelContainer = styled(Box)(({ theme }) => ({
4
+ display: "flex",
5
+ flexDirection: "column",
6
+ gap: theme.spacing(1)
7
+ }));
8
+ const SettingsPanelButton = styled(ButtonBase)(({ theme }) => ({
9
+ display: "flex",
10
+ width: "100%",
11
+ justifyContent: "space-between",
12
+ alignItems: "center",
13
+ gap: theme.spacing(1),
14
+ padding: theme.spacing(2),
15
+ borderRadius: theme.vars.shape.borderRadius
16
+ }));
17
+ const SettingsPanelTitle = styled(Typography)(({ theme }) => ({
18
+ fontSize: 14,
19
+ lineHeight: 1,
20
+ fontWeight: 700,
21
+ color: theme.vars.palette.text.primary
22
+ }));
23
+ const SettingsPanelValue = styled(Typography)(({ theme }) => ({
24
+ fontSize: 14,
25
+ lineHeight: 1,
26
+ fontWeight: 500,
27
+ color: theme.vars.palette.text.secondary,
28
+ whiteSpace: "nowrap"
29
+ }));
30
+ //#endregion
31
+ export { SettingsPanelButton, SettingsPanelContainer, SettingsPanelTitle, SettingsPanelValue };
32
+
33
+ //# sourceMappingURL=SettingsPanel.style.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SettingsPanel.style.js","names":[],"sources":["../../../../src/components/SettingsPanel/SettingsPanel.style.tsx"],"sourcesContent":["import { Box, ButtonBase, styled, Typography } from '@mui/material'\nimport type React from 'react'\n\nexport const SettingsPanelContainer: React.FC<\n React.ComponentProps<typeof Box>\n> = styled(Box)(({ theme }) => ({\n display: 'flex',\n flexDirection: 'column',\n gap: theme.spacing(1),\n}))\n\nexport const SettingsPanelButton: React.FC<\n React.ComponentProps<typeof ButtonBase>\n> = styled(ButtonBase)(({ theme }) => ({\n display: 'flex',\n width: '100%',\n justifyContent: 'space-between',\n alignItems: 'center',\n gap: theme.spacing(1),\n padding: theme.spacing(2),\n borderRadius: theme.vars.shape.borderRadius,\n}))\n\nexport const SettingsPanelTitle: React.FC<\n React.ComponentProps<typeof Typography>\n> = styled(Typography)(({ theme }) => ({\n fontSize: 14,\n lineHeight: 1,\n fontWeight: 700,\n color: theme.vars.palette.text.primary,\n}))\n\nexport const SettingsPanelValue: React.FC<\n React.ComponentProps<typeof Typography>\n> = styled(Typography)(({ theme }) => ({\n fontSize: 14,\n lineHeight: 1,\n fontWeight: 500,\n color: theme.vars.palette.text.secondary,\n whiteSpace: 'nowrap',\n}))\n"],"mappings":";;AAGA,MAAa,yBAET,OAAO,GAAG,CAAC,EAAE,EAAE,aAAa;CAC9B,SAAS;CACT,eAAe;CACf,KAAK,MAAM,QAAQ,CAAC;AACtB,EAAE;AAEF,MAAa,sBAET,OAAO,UAAU,CAAC,EAAE,EAAE,aAAa;CACrC,SAAS;CACT,OAAO;CACP,gBAAgB;CAChB,YAAY;CACZ,KAAK,MAAM,QAAQ,CAAC;CACpB,SAAS,MAAM,QAAQ,CAAC;CACxB,cAAc,MAAM,KAAK,MAAM;AACjC,EAAE;AAEF,MAAa,qBAET,OAAO,UAAU,CAAC,EAAE,EAAE,aAAa;CACrC,UAAU;CACV,YAAY;CACZ,YAAY;CACZ,OAAO,MAAM,KAAK,QAAQ,KAAK;AACjC,EAAE;AAEF,MAAa,qBAET,OAAO,UAAU,CAAC,EAAE,EAAE,aAAa;CACrC,UAAU;CACV,YAAY;CACZ,YAAY;CACZ,OAAO,MAAM,KAAK,QAAQ,KAAK;CAC/B,YAAY;AACd,EAAE"}
@@ -0,0 +1,14 @@
1
+ //#region src/components/SettingsPanel/utils.ts
2
+ /** Navigation tabs that surface the settings panel on the main page. */
3
+ const advancedNavigationTabKeys = ["swap-advanced", "bridge-advanced"];
4
+ const swapSettingsPanelKeys = ["slippage", "exchanges"];
5
+ const bridgeSettingsPanelKeys = [
6
+ "routePriority",
7
+ "slippage",
8
+ "bridges",
9
+ "exchanges"
10
+ ];
11
+ //#endregion
12
+ export { advancedNavigationTabKeys, bridgeSettingsPanelKeys, swapSettingsPanelKeys };
13
+
14
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","names":[],"sources":["../../../../src/components/SettingsPanel/utils.ts"],"sourcesContent":["import type { NavigationTabKey } from '../../types/widget.js'\n\nexport type SettingsPanelKey =\n | 'routePriority'\n | 'exchanges'\n | 'bridges'\n | 'slippage'\n\n/** Navigation tabs that surface the settings panel on the main page. */\nexport const advancedNavigationTabKeys: NavigationTabKey[] = [\n 'swap-advanced',\n 'bridge-advanced',\n]\n\n// Keys are ordered to match the settings page layout.\n// Swap is same-chain, so route priority and bridges are not relevant.\nexport const swapSettingsPanelKeys: SettingsPanelKey[] = [\n 'slippage',\n 'exchanges',\n]\n\nexport const bridgeSettingsPanelKeys: SettingsPanelKey[] = [\n 'routePriority',\n 'slippage',\n 'bridges',\n 'exchanges',\n]\n"],"mappings":";;AASA,MAAa,4BAAgD,CAC3D,iBACA,iBACF;AAIA,MAAa,wBAA4C,CACvD,YACA,WACF;AAEA,MAAa,0BAA8C;CACzD;CACA;CACA;CACA;AACF"}
@@ -0,0 +1,50 @@
1
+ import { useWidgetConfig } from "../../providers/WidgetProvider/WidgetProvider.js";
2
+ import { useAvailableChains } from "../../hooks/useAvailableChains.js";
3
+ import { useFieldActions } from "../../stores/form/useFieldActions.js";
4
+ import { useToAddressReset } from "../../hooks/useToAddressReset.js";
5
+ import { useToAddressAutoPopulate } from "../../hooks/useToAddressAutoPopulate.js";
6
+ import { SwapButtonContainer, SwapIconCard } from "./SwapButton.style.js";
7
+ import { jsx } from "react/jsx-runtime";
8
+ import { useTranslation } from "react-i18next";
9
+ import ArrowDownwardIcon from "@mui/icons-material/ArrowDownward";
10
+ //#region src/components/SwapButton/SwapButton.tsx
11
+ const SwapButton = ({ sx, ...props }) => {
12
+ const { t } = useTranslation();
13
+ const { mode } = useWidgetConfig();
14
+ const { setFieldValue, getFieldValues } = useFieldActions();
15
+ const { getChainById } = useAvailableChains();
16
+ const { tryResetToAddress } = useToAddressReset();
17
+ const autoPopulateToAddress = useToAddressAutoPopulate();
18
+ const handleClick = () => {
19
+ const [fromChainId, fromToken, toChainId, toToken, toAddress, toAmount] = getFieldValues("fromChain", "fromToken", "toChain", "toToken", "toAddress", "toAmount");
20
+ setFieldValue("fromAmount", mode === "limit" && toAmount ? toAmount : "", { isTouched: true });
21
+ setFieldValue("fromChain", toChainId, { isTouched: true });
22
+ setFieldValue("fromToken", toToken, { isTouched: true });
23
+ setFieldValue("toChain", fromChainId, { isTouched: true });
24
+ setFieldValue("toToken", fromToken, { isTouched: true });
25
+ if (autoPopulateToAddress({
26
+ formType: "from",
27
+ selectedToAddress: toAddress,
28
+ selectedChainId: toChainId,
29
+ selectedOppositeChainId: fromChainId,
30
+ selectedOppositeTokenAddress: fromToken
31
+ })) return;
32
+ const toChain = getChainById(fromChainId);
33
+ if (toChain) tryResetToAddress(toChain);
34
+ };
35
+ return /* @__PURE__ */ jsx(SwapButtonContainer, {
36
+ sx,
37
+ ...props,
38
+ children: /* @__PURE__ */ jsx(SwapIconCard, {
39
+ component: "button",
40
+ onClick: handleClick,
41
+ "aria-label": t("button.swap"),
42
+ "data-testid": "widget-swap-tokens-button",
43
+ children: /* @__PURE__ */ jsx(ArrowDownwardIcon, { fontSize: "inherit" })
44
+ })
45
+ });
46
+ };
47
+ //#endregion
48
+ export { SwapButton };
49
+
50
+ //# sourceMappingURL=SwapButton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SwapButton.js","names":["ArrowDownward"],"sources":["../../../../src/components/SwapButton/SwapButton.tsx"],"sourcesContent":["import ArrowDownward from '@mui/icons-material/ArrowDownward'\nimport type { BoxProps } from '@mui/material'\nimport type { JSX } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { useAvailableChains } from '../../hooks/useAvailableChains.js'\nimport { useToAddressAutoPopulate } from '../../hooks/useToAddressAutoPopulate.js'\nimport { useToAddressReset } from '../../hooks/useToAddressReset.js'\nimport { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'\nimport { useFieldActions } from '../../stores/form/useFieldActions.js'\nimport { SwapButtonContainer, SwapIconCard } from './SwapButton.style.js'\n\nexport const SwapButton: React.FC<BoxProps> = ({\n sx,\n ...props\n}): JSX.Element => {\n const { t } = useTranslation()\n const { mode } = useWidgetConfig()\n const { setFieldValue, getFieldValues } = useFieldActions()\n const { getChainById } = useAvailableChains()\n const { tryResetToAddress } = useToAddressReset()\n const autoPopulateToAddress = useToAddressAutoPopulate()\n\n const handleClick = (): void => {\n const [fromChainId, fromToken, toChainId, toToken, toAddress, toAmount] =\n getFieldValues(\n 'fromChain',\n 'fromToken',\n 'toChain',\n 'toToken',\n 'toAddress',\n 'toAmount'\n )\n const newFromAmount =\n mode === 'limit' && toAmount ? (toAmount as string) : ''\n setFieldValue('fromAmount', newFromAmount, { isTouched: true })\n setFieldValue('fromChain', toChainId, { isTouched: true })\n setFieldValue('fromToken', toToken, { isTouched: true })\n setFieldValue('toChain', fromChainId, { isTouched: true })\n setFieldValue('toToken', fromToken, { isTouched: true })\n\n const autoPopulatedToAddress = autoPopulateToAddress({\n formType: 'from',\n selectedToAddress: toAddress,\n selectedChainId: toChainId,\n selectedOppositeChainId: fromChainId,\n selectedOppositeTokenAddress: fromToken,\n })\n\n if (autoPopulatedToAddress) {\n return\n }\n\n const toChain = getChainById(fromChainId)\n if (toChain) {\n tryResetToAddress(toChain)\n }\n }\n\n return (\n <SwapButtonContainer sx={sx} {...props}>\n <SwapIconCard\n component=\"button\"\n onClick={handleClick}\n aria-label={t('button.swap')}\n data-testid=\"widget-swap-tokens-button\"\n >\n <ArrowDownward fontSize=\"inherit\" />\n </SwapIconCard>\n </SwapButtonContainer>\n )\n}\n"],"mappings":";;;;;;;;;;AAWA,MAAa,cAAkC,EAC7C,IACA,GAAG,YACc;CACjB,MAAM,EAAE,MAAM,eAAe;CAC7B,MAAM,EAAE,SAAS,gBAAgB;CACjC,MAAM,EAAE,eAAe,mBAAmB,gBAAgB;CAC1D,MAAM,EAAE,iBAAiB,mBAAmB;CAC5C,MAAM,EAAE,sBAAsB,kBAAkB;CAChD,MAAM,wBAAwB,yBAAyB;CAEvD,MAAM,oBAA0B;EAC9B,MAAM,CAAC,aAAa,WAAW,WAAW,SAAS,WAAW,YAC5D,eACE,aACA,aACA,WACA,WACA,aACA,UACF;EAGF,cAAc,cADZ,SAAS,WAAW,WAAY,WAAsB,IACb,EAAE,WAAW,KAAK,CAAC;EAC9D,cAAc,aAAa,WAAW,EAAE,WAAW,KAAK,CAAC;EACzD,cAAc,aAAa,SAAS,EAAE,WAAW,KAAK,CAAC;EACvD,cAAc,WAAW,aAAa,EAAE,WAAW,KAAK,CAAC;EACzD,cAAc,WAAW,WAAW,EAAE,WAAW,KAAK,CAAC;EAUvD,IAR+B,sBAAsB;GACnD,UAAU;GACV,mBAAmB;GACnB,iBAAiB;GACjB,yBAAyB;GACzB,8BAA8B;EAChC,CAEyB,GACvB;EAGF,MAAM,UAAU,aAAa,WAAW;EACxC,IAAI,SACF,kBAAkB,OAAO;CAE7B;CAEA,OACE,oBAAC,qBAAD;EAAyB;EAAI,GAAI;YAC/B,oBAAC,cAAD;GACE,WAAU;GACV,SAAS;GACT,cAAY,EAAE,aAAa;GAC3B,eAAY;aAEZ,oBAACA,mBAAD,EAAe,UAAS,UAAW,CAAA;EACvB,CAAA;CACK,CAAA;AAEzB"}
@@ -0,0 +1,24 @@
1
+ import { Card as Card$1 } from "../Card/Card.js";
2
+ import { Box, styled } from "@mui/material";
3
+ //#region src/components/SwapButton/SwapButton.style.tsx
4
+ const swapButtonZIndex = 1110;
5
+ const SwapIconCard = styled(Card$1)(({ theme }) => ({
6
+ height: 32,
7
+ width: 32,
8
+ fontSize: 16,
9
+ display: "flex",
10
+ alignItems: "center",
11
+ justifyContent: "center",
12
+ borderRadius: theme.vars.shape.borderRadiusTertiary,
13
+ zIndex: swapButtonZIndex
14
+ }));
15
+ const SwapButtonContainer = styled(Box)(({ theme }) => ({
16
+ display: "flex",
17
+ justifyContent: "center",
18
+ alignItems: "center",
19
+ margin: theme.spacing(-1.5)
20
+ }));
21
+ //#endregion
22
+ export { SwapButtonContainer, SwapIconCard };
23
+
24
+ //# sourceMappingURL=SwapButton.style.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SwapButton.style.js","names":["Card"],"sources":["../../../../src/components/SwapButton/SwapButton.style.tsx"],"sourcesContent":["import { Box, styled } from '@mui/material'\nimport type React from 'react'\nimport { Card } from '../Card/Card.js'\n\n// Sits just above MUI's appBar layer (1100) so the swap icon stays on top of the\n// two overlapping amount cards it bridges.\nconst swapButtonZIndex = 1110\n\nexport const SwapIconCard: React.FC<React.ComponentProps<typeof Card>> = styled(\n Card\n)(({ theme }) => ({\n height: 32,\n width: 32,\n fontSize: 16,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: theme.vars.shape.borderRadiusTertiary,\n zIndex: swapButtonZIndex,\n}))\n\nexport const SwapButtonContainer: React.FC<React.ComponentProps<typeof Box>> =\n styled(Box)(({ theme }) => ({\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n margin: theme.spacing(-1.5),\n }))\n"],"mappings":";;;AAMA,MAAM,mBAAmB;AAEzB,MAAa,eAA4D,OACvEA,MACF,CAAC,EAAE,EAAE,aAAa;CAChB,QAAQ;CACR,OAAO;CACP,UAAU;CACV,SAAS;CACT,YAAY;CACZ,gBAAgB;CAChB,cAAc,MAAM,KAAK,MAAM;CAC/B,QAAQ;AACV,EAAE;AAEF,MAAa,sBACX,OAAO,GAAG,CAAC,EAAE,EAAE,aAAa;CAC1B,SAAS;CACT,gBAAgB;CAChB,YAAY;CACZ,QAAQ,MAAM,QAAQ,IAAI;AAC5B,EAAE"}
@@ -0,0 +1,52 @@
1
+ import { useWidgetConfig } from "../../providers/WidgetProvider/WidgetProvider.js";
2
+ import { navigationRoutes } from "../../utils/navigationRoutes.js";
3
+ import { FormKeyHelper } from "../../stores/form/types.js";
4
+ import { useFieldValues } from "../../stores/form/useFieldValues.js";
5
+ import { useChain } from "../../hooks/useChain.js";
6
+ import { useToken } from "../../hooks/useToken.js";
7
+ import { AvatarBadgedDefault } from "../Avatar/Avatar.js";
8
+ import { TokenAvatar } from "../Avatar/TokenAvatar.js";
9
+ import { TokenPill, TokenPillLabel, TokenPillSymbol, TokenSelectPill } from "./TokenPillButton.style.js";
10
+ import { useNavigate } from "@tanstack/react-router";
11
+ import { jsx, jsxs } from "react/jsx-runtime";
12
+ import { useTranslation } from "react-i18next";
13
+ //#region src/components/TokenPillButton/TokenPillButton.tsx
14
+ const TokenPillButton = ({ formType }) => {
15
+ const { t } = useTranslation();
16
+ const navigate = useNavigate();
17
+ const { disabledUI, mode } = useWidgetConfig();
18
+ const tokenKey = FormKeyHelper.getTokenKey(formType);
19
+ const [chainId, tokenAddress] = useFieldValues(FormKeyHelper.getChainKey(formType), tokenKey);
20
+ const { chain } = useChain(chainId);
21
+ const { token } = useToken(chainId, tokenAddress);
22
+ const isSelected = !!(chain && token);
23
+ const handleClick = () => {
24
+ navigate({ to: formType === "from" ? navigationRoutes.fromToken : mode === "refuel" ? navigationRoutes.toTokenNative : navigationRoutes.toToken });
25
+ };
26
+ const isDisabled = !!disabledUI?.[tokenKey];
27
+ const testId = `widget-${formType}-token-button`;
28
+ if (isSelected) return /* @__PURE__ */ jsxs(TokenPill, {
29
+ onClick: isDisabled ? void 0 : handleClick,
30
+ disabled: isDisabled,
31
+ "data-testid": testId,
32
+ children: [/* @__PURE__ */ jsx(TokenAvatar, {
33
+ token,
34
+ chain,
35
+ tokenAvatarSize: 24,
36
+ chainAvatarSize: 12
37
+ }), /* @__PURE__ */ jsx(TokenPillSymbol, { children: token.symbol })]
38
+ });
39
+ return /* @__PURE__ */ jsxs(TokenSelectPill, {
40
+ onClick: isDisabled ? void 0 : handleClick,
41
+ "data-testid": testId,
42
+ children: [/* @__PURE__ */ jsx(AvatarBadgedDefault, {
43
+ chain,
44
+ avatarSize: 24,
45
+ badgeSize: 12
46
+ }), /* @__PURE__ */ jsx(TokenPillLabel, { children: t("main.select") })]
47
+ });
48
+ };
49
+ //#endregion
50
+ export { TokenPillButton };
51
+
52
+ //# sourceMappingURL=TokenPillButton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TokenPillButton.js","names":[],"sources":["../../../../src/components/TokenPillButton/TokenPillButton.tsx"],"sourcesContent":["import { useNavigate } from '@tanstack/react-router'\nimport type { JSX } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { useChain } from '../../hooks/useChain.js'\nimport { useToken } from '../../hooks/useToken.js'\nimport { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'\nimport type { FormTypeProps } from '../../stores/form/types.js'\nimport { FormKeyHelper } from '../../stores/form/types.js'\nimport { useFieldValues } from '../../stores/form/useFieldValues.js'\nimport type { DisabledUIConfig } from '../../types/widget.js'\nimport { navigationRoutes } from '../../utils/navigationRoutes.js'\nimport { AvatarBadgedDefault } from '../Avatar/Avatar.js'\nimport { TokenAvatar } from '../Avatar/TokenAvatar.js'\nimport {\n TokenPill,\n TokenPillLabel,\n TokenPillSymbol,\n TokenSelectPill,\n} from './TokenPillButton.style.js'\n\nexport const TokenPillButton: React.FC<FormTypeProps> = ({\n formType,\n}): JSX.Element => {\n const { t } = useTranslation()\n const navigate = useNavigate()\n const { disabledUI, mode } = useWidgetConfig()\n\n const tokenKey = FormKeyHelper.getTokenKey(formType)\n const [chainId, tokenAddress] = useFieldValues(\n FormKeyHelper.getChainKey(formType),\n tokenKey\n )\n\n const { chain } = useChain(chainId)\n const { token } = useToken(chainId, tokenAddress)\n\n const isSelected = !!(chain && token)\n\n const handleClick = (): void => {\n navigate({\n to:\n formType === 'from'\n ? navigationRoutes.fromToken\n : mode === 'refuel'\n ? navigationRoutes.toTokenNative\n : navigationRoutes.toToken,\n })\n }\n\n const isDisabled = !!disabledUI?.[tokenKey as keyof DisabledUIConfig]\n\n const testId = `widget-${formType}-token-button`\n\n if (isSelected) {\n return (\n <TokenPill\n onClick={isDisabled ? undefined : handleClick}\n disabled={isDisabled}\n data-testid={testId}\n >\n <TokenAvatar\n token={token}\n chain={chain}\n tokenAvatarSize={24}\n chainAvatarSize={12}\n />\n <TokenPillSymbol>{token.symbol}</TokenPillSymbol>\n </TokenPill>\n )\n }\n\n return (\n <TokenSelectPill\n onClick={isDisabled ? undefined : handleClick}\n data-testid={testId}\n >\n <AvatarBadgedDefault chain={chain} avatarSize={24} badgeSize={12} />\n <TokenPillLabel>{t('main.select')}</TokenPillLabel>\n </TokenSelectPill>\n )\n}\n"],"mappings":";;;;;;;;;;;;;AAoBA,MAAa,mBAA4C,EACvD,eACiB;CACjB,MAAM,EAAE,MAAM,eAAe;CAC7B,MAAM,WAAW,YAAY;CAC7B,MAAM,EAAE,YAAY,SAAS,gBAAgB;CAE7C,MAAM,WAAW,cAAc,YAAY,QAAQ;CACnD,MAAM,CAAC,SAAS,gBAAgB,eAC9B,cAAc,YAAY,QAAQ,GAClC,QACF;CAEA,MAAM,EAAE,UAAU,SAAS,OAAO;CAClC,MAAM,EAAE,UAAU,SAAS,SAAS,YAAY;CAEhD,MAAM,aAAa,CAAC,EAAE,SAAS;CAE/B,MAAM,oBAA0B;EAC9B,SAAS,EACP,IACE,aAAa,SACT,iBAAiB,YACjB,SAAS,WACP,iBAAiB,gBACjB,iBAAiB,QAC3B,CAAC;CACH;CAEA,MAAM,aAAa,CAAC,CAAC,aAAa;CAElC,MAAM,SAAS,UAAU,SAAS;CAElC,IAAI,YACF,OACE,qBAAC,WAAD;EACE,SAAS,aAAa,KAAA,IAAY;EAClC,UAAU;EACV,eAAa;YAHf,CAKE,oBAAC,aAAD;GACS;GACA;GACP,iBAAiB;GACjB,iBAAiB;EAClB,CAAA,GACD,oBAAC,iBAAD,EAAA,UAAkB,MAAM,OAAwB,CAAA,CACvC;;CAIf,OACE,qBAAC,iBAAD;EACE,SAAS,aAAa,KAAA,IAAY;EAClC,eAAa;YAFf,CAIE,oBAAC,qBAAD;GAA4B;GAAO,YAAY;GAAI,WAAW;EAAK,CAAA,GACnE,oBAAC,gBAAD,EAAA,UAAiB,EAAE,aAAa,EAAkB,CAAA,CACnC;;AAErB"}
@@ -0,0 +1,39 @@
1
+ import { Button, Typography, styled } from "@mui/material";
2
+ //#region src/components/TokenPillButton/TokenPillButton.style.tsx
3
+ const pillLayout = (theme) => ({
4
+ height: 36,
5
+ borderRadius: theme.vars.shape.borderRadiusSecondary,
6
+ padding: theme.spacing(.5, 1),
7
+ display: "flex",
8
+ alignItems: "center",
9
+ gap: theme.spacing(1),
10
+ whiteSpace: "nowrap",
11
+ flexShrink: 0
12
+ });
13
+ const TokenPill = styled(Button)(({ theme }) => ({
14
+ ...pillLayout(theme),
15
+ backgroundColor: `color-mix(in srgb, ${theme.vars.palette.common.onBackground} 4%, transparent)`,
16
+ border: "1px solid transparent",
17
+ transition: theme.transitions.create(["background-color"], { duration: theme.transitions.duration.short }),
18
+ "&:hover": { backgroundColor: `color-mix(in srgb, ${theme.vars.palette.common.onBackground} 8%, transparent)` }
19
+ }));
20
+ const TokenSelectPill = styled(TokenPill)({ minWidth: 0 });
21
+ const TokenPillSymbol = styled(Typography)(({ theme }) => ({
22
+ fontSize: 14,
23
+ fontWeight: 700,
24
+ lineHeight: "18px",
25
+ overflow: "hidden",
26
+ textOverflow: "ellipsis",
27
+ whiteSpace: "nowrap",
28
+ color: theme.vars.palette.text.primary
29
+ }));
30
+ const TokenPillLabel = styled(Typography)(({ theme }) => ({
31
+ fontSize: 16,
32
+ fontWeight: 700,
33
+ lineHeight: "20px",
34
+ color: theme.vars.palette.text.secondary
35
+ }));
36
+ //#endregion
37
+ export { TokenPill, TokenPillLabel, TokenPillSymbol, TokenSelectPill };
38
+
39
+ //# sourceMappingURL=TokenPillButton.style.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TokenPillButton.style.js","names":[],"sources":["../../../../src/components/TokenPillButton/TokenPillButton.style.tsx"],"sourcesContent":["import { Button, styled, type Theme, Typography } from '@mui/material'\nimport type React from 'react'\n\nconst pillLayout = (theme: Theme) => ({\n height: 36,\n borderRadius: theme.vars.shape.borderRadiusSecondary,\n padding: theme.spacing(0.5, 1),\n display: 'flex',\n alignItems: 'center',\n gap: theme.spacing(1),\n whiteSpace: 'nowrap',\n flexShrink: 0,\n})\n\nexport const TokenPill: React.FC<React.ComponentProps<typeof Button>> = styled(\n Button\n)(({ theme }) => ({\n ...pillLayout(theme),\n backgroundColor: `color-mix(in srgb, ${theme.vars.palette.common.onBackground} 4%, transparent)`,\n border: '1px solid transparent',\n transition: theme.transitions.create(['background-color'], {\n duration: theme.transitions.duration.short,\n }),\n '&:hover': {\n backgroundColor: `color-mix(in srgb, ${theme.vars.palette.common.onBackground} 8%, transparent)`,\n },\n}))\n\nexport const TokenSelectPill: React.FC<React.ComponentProps<typeof Button>> =\n styled(TokenPill)({ minWidth: 0 })\n\nexport const TokenPillSymbol: React.FC<\n React.ComponentProps<typeof Typography>\n> = styled(Typography)(({ theme }) => ({\n fontSize: 14,\n fontWeight: 700,\n lineHeight: '18px',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n color: theme.vars.palette.text.primary,\n}))\n\nexport const TokenPillLabel: React.FC<React.ComponentProps<typeof Typography>> =\n styled(Typography)(({ theme }) => ({\n fontSize: 16,\n fontWeight: 700,\n lineHeight: '20px',\n color: theme.vars.palette.text.secondary,\n }))\n"],"mappings":";;AAGA,MAAM,cAAc,WAAkB;CACpC,QAAQ;CACR,cAAc,MAAM,KAAK,MAAM;CAC/B,SAAS,MAAM,QAAQ,IAAK,CAAC;CAC7B,SAAS;CACT,YAAY;CACZ,KAAK,MAAM,QAAQ,CAAC;CACpB,YAAY;CACZ,YAAY;AACd;AAEA,MAAa,YAA2D,OACtE,MACF,CAAC,EAAE,EAAE,aAAa;CAChB,GAAG,WAAW,KAAK;CACnB,iBAAiB,sBAAsB,MAAM,KAAK,QAAQ,OAAO,aAAa;CAC9E,QAAQ;CACR,YAAY,MAAM,YAAY,OAAO,CAAC,kBAAkB,GAAG,EACzD,UAAU,MAAM,YAAY,SAAS,MACvC,CAAC;CACD,WAAW,EACT,iBAAiB,sBAAsB,MAAM,KAAK,QAAQ,OAAO,aAAa,mBAChF;AACF,EAAE;AAEF,MAAa,kBACX,OAAO,SAAS,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC;AAEnC,MAAa,kBAET,OAAO,UAAU,CAAC,EAAE,EAAE,aAAa;CACrC,UAAU;CACV,YAAY;CACZ,YAAY;CACZ,UAAU;CACV,cAAc;CACd,YAAY;CACZ,OAAO,MAAM,KAAK,QAAQ,KAAK;AACjC,EAAE;AAEF,MAAa,iBACX,OAAO,UAAU,CAAC,EAAE,EAAE,aAAa;CACjC,UAAU;CACV,YAAY;CACZ,YAAY;CACZ,OAAO,MAAM,KAAK,QAAQ,KAAK;AACjC,EAAE"}
@@ -1,6 +1,6 @@
1
1
  //#region src/config/version.d.ts
2
2
  declare const name = "@lifi/widget";
3
- declare const version = "4.1.0";
3
+ declare const version = "4.2.0";
4
4
  //#endregion
5
5
  export { name, version };
6
6
  //# sourceMappingURL=version.d.ts.map
@@ -1,6 +1,6 @@
1
1
  //#region src/config/version.ts
2
2
  const name = "@lifi/widget";
3
- const version = "4.1.0";
3
+ const version = "4.2.0";
4
4
  //#endregion
5
5
  export { name, version };
6
6
 
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","names":[],"sources":["../../../src/config/version.ts"],"sourcesContent":["export const name = '@lifi/widget'\nexport const version = '4.1.0'\n"],"mappings":";AAAA,MAAa,OAAO;AACpB,MAAa,UAAU"}
1
+ {"version":3,"file":"version.js","names":[],"sources":["../../../src/config/version.ts"],"sourcesContent":["export const name = '@lifi/widget'\nexport const version = '4.2.0'\n"],"mappings":";AAAA,MAAa,OAAO;AACpB,MAAa,UAAU"}
@@ -24,7 +24,8 @@ function useChainSearch(formType, listRef, inputRef) {
24
24
  setCurrentChain(chain.id);
25
25
  }, [setCurrentChain]),
26
26
  onChange: useCallback(() => {
27
- debouncedFilterChains(inputRef.current?.value || "");
27
+ const value = inputRef.current?.value || "";
28
+ debouncedFilterChains(value);
28
29
  }, [debouncedFilterChains, inputRef]),
29
30
  onClear: useCallback(() => {
30
31
  if (inputRef.current) inputRef.current.value = "";
@@ -1 +1 @@
1
- {"version":3,"file":"useChainSearch.js","names":[],"sources":["../../../src/hooks/useChainSearch.ts"],"sourcesContent":["import type { ExtendedChain } from '@lifi/sdk'\nimport { debounce } from '@mui/material'\nimport type { RefObject } from 'react'\nimport { useCallback, useMemo, useState } from 'react'\nimport { useChainSelect } from '../components/ChainSelect/useChainSelect.js'\nimport { FormKeyHelper, type FormType } from '../stores/form/types.js'\nimport { useFieldValues } from '../stores/form/useFieldValues.js'\n\nexport function useChainSearch(\n formType: FormType,\n listRef: RefObject<HTMLDivElement | null>,\n inputRef: RefObject<HTMLInputElement | null>\n): {\n filteredChains: ExtendedChain[]\n isLoading: boolean\n selectedChainId: number | undefined\n onSelectChainFallback: (chain: ExtendedChain) => void\n onChange: () => void\n onClear: () => void\n} {\n const { chains, isLoading, setCurrentChain } = useChainSelect(formType)\n const [selectedChainId] = useFieldValues(FormKeyHelper.getChainKey(formType))\n const [debouncedSearchValue, setDebouncedSearchValue] = useState('')\n\n const filteredChains = useMemo(() => {\n const value = debouncedSearchValue.toLowerCase()\n return value\n ? (chains?.filter((chain) => chain.name.toLowerCase().includes(value)) ??\n [])\n : (chains ?? [])\n }, [chains, debouncedSearchValue])\n\n const debouncedFilterChains = useMemo(\n () =>\n debounce((value: string) => {\n setDebouncedSearchValue(value)\n listRef.current?.scrollTo(0, 0)\n }, 250),\n [listRef]\n )\n\n const onSelectChainFallback = useCallback(\n (chain: ExtendedChain) => {\n setCurrentChain(chain.id)\n },\n [setCurrentChain]\n )\n\n const onChange = useCallback(() => {\n const value = inputRef.current?.value || ''\n debouncedFilterChains(value)\n }, [debouncedFilterChains, inputRef])\n\n const onClear = useCallback(() => {\n if (inputRef.current) {\n inputRef.current.value = ''\n }\n setDebouncedSearchValue('')\n listRef.current?.scrollTo(0, 0)\n }, [inputRef, listRef])\n\n return {\n filteredChains,\n isLoading,\n selectedChainId,\n onSelectChainFallback,\n onChange,\n onClear,\n }\n}\n"],"mappings":";;;;;;AAQA,SAAgB,eACd,UACA,SACA,UAQA;CACA,MAAM,EAAE,QAAQ,WAAW,oBAAoB,eAAe,QAAQ;CACtE,MAAM,CAAC,mBAAmB,eAAe,cAAc,YAAY,QAAQ,CAAC;CAC5E,MAAM,CAAC,sBAAsB,2BAA2B,SAAS,EAAE;CAEnE,MAAM,iBAAiB,cAAc;EACnC,MAAM,QAAQ,qBAAqB,YAAY;EAC/C,OAAO,QACF,QAAQ,QAAQ,UAAU,MAAM,KAAK,YAAY,CAAC,CAAC,SAAS,KAAK,CAAC,KACjE,CAAC,IACF,UAAU,CAAC;CAClB,GAAG,CAAC,QAAQ,oBAAoB,CAAC;CAEjC,MAAM,wBAAwB,cAE1B,UAAU,UAAkB;EAC1B,wBAAwB,KAAK;EAC7B,QAAQ,SAAS,SAAS,GAAG,CAAC;CAChC,GAAG,GAAG,GACR,CAAC,OAAO,CACV;CAsBA,OAAO;EACL;EACA;EACA;EACA,uBAxB4B,aAC3B,UAAyB;GACxB,gBAAgB,MAAM,EAAE;EAC1B,GACA,CAAC,eAAe,CAoBI;EACpB,UAlBe,kBAAkB;GAEjC,sBADc,SAAS,SAAS,SAAS,EACd;EAC7B,GAAG,CAAC,uBAAuB,QAAQ,CAe1B;EACP,SAdc,kBAAkB;GAChC,IAAI,SAAS,SACX,SAAS,QAAQ,QAAQ;GAE3B,wBAAwB,EAAE;GAC1B,QAAQ,SAAS,SAAS,GAAG,CAAC;EAChC,GAAG,CAAC,UAAU,OAAO,CAQb;CACR;AACF"}
1
+ {"version":3,"file":"useChainSearch.js","names":[],"sources":["../../../src/hooks/useChainSearch.ts"],"sourcesContent":["import type { ExtendedChain } from '@lifi/sdk'\nimport { debounce } from '@mui/material'\nimport type { RefObject } from 'react'\nimport { useCallback, useMemo, useState } from 'react'\nimport { useChainSelect } from '../components/ChainSelect/useChainSelect.js'\nimport { FormKeyHelper, type FormType } from '../stores/form/types.js'\nimport { useFieldValues } from '../stores/form/useFieldValues.js'\n\nexport function useChainSearch(\n formType: FormType,\n listRef: RefObject<HTMLDivElement | null>,\n inputRef: RefObject<HTMLInputElement | null>\n): {\n filteredChains: ExtendedChain[]\n isLoading: boolean\n selectedChainId: number | undefined\n onSelectChainFallback: (chain: ExtendedChain) => void\n onChange: () => void\n onClear: () => void\n} {\n const { chains, isLoading, setCurrentChain } = useChainSelect(formType)\n const [selectedChainId] = useFieldValues(FormKeyHelper.getChainKey(formType))\n const [debouncedSearchValue, setDebouncedSearchValue] = useState('')\n\n const filteredChains = useMemo(() => {\n const value = debouncedSearchValue.toLowerCase()\n return value\n ? (chains?.filter((chain) => chain.name.toLowerCase().includes(value)) ??\n [])\n : (chains ?? [])\n }, [chains, debouncedSearchValue])\n\n const debouncedFilterChains = useMemo(\n () =>\n debounce((value: string) => {\n setDebouncedSearchValue(value)\n listRef.current?.scrollTo(0, 0)\n }, 250),\n [listRef]\n )\n\n const onSelectChainFallback = useCallback(\n (chain: ExtendedChain) => {\n setCurrentChain(chain.id)\n },\n [setCurrentChain]\n )\n\n const onChange = useCallback(() => {\n const value = inputRef.current?.value || ''\n debouncedFilterChains(value)\n }, [debouncedFilterChains, inputRef])\n\n const onClear = useCallback(() => {\n if (inputRef.current) {\n inputRef.current.value = ''\n }\n setDebouncedSearchValue('')\n listRef.current?.scrollTo(0, 0)\n }, [inputRef, listRef])\n\n return {\n filteredChains,\n isLoading,\n selectedChainId,\n onSelectChainFallback,\n onChange,\n onClear,\n }\n}\n"],"mappings":";;;;;;AAQA,SAAgB,eACd,UACA,SACA,UAQA;CACA,MAAM,EAAE,QAAQ,WAAW,oBAAoB,eAAe,QAAQ;CACtE,MAAM,CAAC,mBAAmB,eAAe,cAAc,YAAY,QAAQ,CAAC;CAC5E,MAAM,CAAC,sBAAsB,2BAA2B,SAAS,EAAE;CAEnE,MAAM,iBAAiB,cAAc;EACnC,MAAM,QAAQ,qBAAqB,YAAY;EAC/C,OAAO,QACF,QAAQ,QAAQ,UAAU,MAAM,KAAK,YAAY,CAAC,CAAC,SAAS,KAAK,CAAC,KACjE,CAAC,IACF,UAAU,CAAC;CAClB,GAAG,CAAC,QAAQ,oBAAoB,CAAC;CAEjC,MAAM,wBAAwB,cAE1B,UAAU,UAAkB;EAC1B,wBAAwB,KAAK;EAC7B,QAAQ,SAAS,SAAS,GAAG,CAAC;CAChC,GAAG,GAAG,GACR,CAAC,OAAO,CACV;CAsBA,OAAO;EACL;EACA;EACA;EACA,uBAxB4B,aAC3B,UAAyB;GACxB,gBAAgB,MAAM,EAAE;EAC1B,GACA,CAAC,eAAe,CAoBI;EACpB,UAlBe,kBAAkB;GACjC,MAAM,QAAQ,SAAS,SAAS,SAAS;GACzC,sBAAsB,KAAK;EAC7B,GAAG,CAAC,uBAAuB,QAAQ,CAe1B;EACP,SAdc,kBAAkB;GAChC,IAAI,SAAS,SACX,SAAS,QAAQ,QAAQ;GAE3B,wBAAwB,EAAE;GAC1B,QAAQ,SAAS,SAAS,GAAG,CAAC;EAChC,GAAG,CAAC,UAAU,OAAO,CAQb;CACR;AACF"}
@@ -0,0 +1,24 @@
1
+ import { FormKeyHelper } from "../stores/form/types.js";
2
+ import { useFieldValues } from "../stores/form/useFieldValues.js";
3
+ import { useToken } from "./useToken.js";
4
+ //#region src/hooks/useLimitMarketRate.ts
5
+ /**
6
+ * Canonical limit-order market rate (receive token per send token), derived
7
+ * from the tokens' USD prices: 1 send token ≈ sendPrice / receivePrice receive
8
+ * tokens. This is the spot ratio — what the price card's "Market" reference and
9
+ * proximity indicator compare against. Returns `undefined` until both token
10
+ * prices are known.
11
+ */
12
+ const useLimitMarketRate = () => {
13
+ const [fromChainId, fromTokenAddress, toChainId, toTokenAddress] = useFieldValues(FormKeyHelper.getChainKey("from"), FormKeyHelper.getTokenKey("from"), FormKeyHelper.getChainKey("to"), FormKeyHelper.getTokenKey("to"));
14
+ const { token: fromToken } = useToken(fromChainId, fromTokenAddress);
15
+ const { token: toToken } = useToken(toChainId, toTokenAddress);
16
+ const fromPrice = Number(fromToken?.priceUSD);
17
+ const toPrice = Number(toToken?.priceUSD);
18
+ if (!fromPrice || !toPrice || Number.isNaN(fromPrice) || Number.isNaN(toPrice)) return;
19
+ return fromPrice / toPrice;
20
+ };
21
+ //#endregion
22
+ export { useLimitMarketRate };
23
+
24
+ //# sourceMappingURL=useLimitMarketRate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useLimitMarketRate.js","names":[],"sources":["../../../src/hooks/useLimitMarketRate.ts"],"sourcesContent":["import { FormKeyHelper } from '../stores/form/types.js'\nimport { useFieldValues } from '../stores/form/useFieldValues.js'\nimport { useToken } from './useToken.js'\n\n/**\n * Canonical limit-order market rate (receive token per send token), derived\n * from the tokens' USD prices: 1 send token ≈ sendPrice / receivePrice receive\n * tokens. This is the spot ratio — what the price card's \"Market\" reference and\n * proximity indicator compare against. Returns `undefined` until both token\n * prices are known.\n */\nexport const useLimitMarketRate = (): number | undefined => {\n const [fromChainId, fromTokenAddress, toChainId, toTokenAddress] =\n useFieldValues(\n FormKeyHelper.getChainKey('from'),\n FormKeyHelper.getTokenKey('from'),\n FormKeyHelper.getChainKey('to'),\n FormKeyHelper.getTokenKey('to')\n )\n const { token: fromToken } = useToken(fromChainId, fromTokenAddress)\n const { token: toToken } = useToken(toChainId, toTokenAddress)\n\n const fromPrice = Number(fromToken?.priceUSD)\n const toPrice = Number(toToken?.priceUSD)\n\n // A `priceUSD` of `\"0\"` (or missing) means the price is unknown — there's no\n // meaningful spot ratio to derive, and dividing by a zero `toPrice` would be\n // `Infinity`, so the falsy guard intentionally suppresses the rate here.\n if (\n !fromPrice ||\n !toPrice ||\n Number.isNaN(fromPrice) ||\n Number.isNaN(toPrice)\n ) {\n return undefined\n }\n\n return fromPrice / toPrice\n}\n"],"mappings":";;;;;;;;;;;AAWA,MAAa,2BAA+C;CAC1D,MAAM,CAAC,aAAa,kBAAkB,WAAW,kBAC/C,eACE,cAAc,YAAY,MAAM,GAChC,cAAc,YAAY,MAAM,GAChC,cAAc,YAAY,IAAI,GAC9B,cAAc,YAAY,IAAI,CAChC;CACF,MAAM,EAAE,OAAO,cAAc,SAAS,aAAa,gBAAgB;CACnE,MAAM,EAAE,OAAO,YAAY,SAAS,WAAW,cAAc;CAE7D,MAAM,YAAY,OAAO,WAAW,QAAQ;CAC5C,MAAM,UAAU,OAAO,SAAS,QAAQ;CAKxC,IACE,CAAC,aACD,CAAC,WACD,OAAO,MAAM,SAAS,KACtB,OAAO,MAAM,OAAO,GAEpB;CAGF,OAAO,YAAY;AACrB"}
@@ -0,0 +1,49 @@
1
+ import { useFieldActions } from "../stores/form/useFieldActions.js";
2
+ import { FormKeyHelper } from "../stores/form/types.js";
3
+ import { useFieldValues } from "../stores/form/useFieldValues.js";
4
+ import { useToken } from "./useToken.js";
5
+ import { deriveLimitPrice, deriveReceiveAmount } from "../utils/limitOrder.js";
6
+ //#region src/hooks/useLinkedLimitFields.ts
7
+ /**
8
+ * Implements the linked-field derivation for limit orders:
9
+ * - `limitPrice = receiveAmount / sendAmount`
10
+ * - editing sendAmount recomputes receiveAmount, holding the current price
11
+ * - editing limitPrice (with a send amount set) recomputes receiveAmount
12
+ * - sendAmount never changes without an explicit user edit
13
+ *
14
+ * The receive amount (`toAmount`) is read-only in the UI — it is derived here
15
+ * from the send amount and limit price, then sent to the routes request; the
16
+ * receive card only displays the resulting quote.
17
+ *
18
+ * The limit price is NOT stored: it is purely a function of the `fromAmount`
19
+ * and `toAmount` form fields (canonical receive-per-send). The UI layer handles
20
+ * base/quote display inversion. Because it's derived, editing the send amount
21
+ * only has to preserve the pre-edit price.
22
+ */
23
+ const useLinkedLimitFields = () => {
24
+ const { setFieldValue } = useFieldActions();
25
+ const [toChainId, toTokenAddress, sendAmount, receiveAmount] = useFieldValues(FormKeyHelper.getChainKey("to"), FormKeyHelper.getTokenKey("to"), FormKeyHelper.getAmountKey("from"), FormKeyHelper.getAmountKey("to"));
26
+ const { token: toToken } = useToken(toChainId, toTokenAddress);
27
+ const limitPrice = deriveLimitPrice(sendAmount, receiveAmount);
28
+ const setSendAmount = (value) => {
29
+ setFieldValue("fromAmount", value, {
30
+ isDirty: true,
31
+ isTouched: true
32
+ });
33
+ const nextReceive = deriveReceiveAmount(value, limitPrice, toToken?.decimals);
34
+ if (nextReceive) setFieldValue("toAmount", nextReceive, { isDirty: true });
35
+ };
36
+ const setLimitPrice = (value) => {
37
+ const nextReceive = deriveReceiveAmount(sendAmount, value, toToken?.decimals);
38
+ setFieldValue("toAmount", nextReceive, { isDirty: true });
39
+ };
40
+ return {
41
+ limitPrice,
42
+ setSendAmount,
43
+ setLimitPrice
44
+ };
45
+ };
46
+ //#endregion
47
+ export { useLinkedLimitFields };
48
+
49
+ //# sourceMappingURL=useLinkedLimitFields.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useLinkedLimitFields.js","names":[],"sources":["../../../src/hooks/useLinkedLimitFields.ts"],"sourcesContent":["import { FormKeyHelper } from '../stores/form/types.js'\nimport { useFieldActions } from '../stores/form/useFieldActions.js'\nimport { useFieldValues } from '../stores/form/useFieldValues.js'\nimport { deriveLimitPrice, deriveReceiveAmount } from '../utils/limitOrder.js'\nimport { useToken } from './useToken.js'\n\nexport interface LinkedLimitFields {\n limitPrice: string\n /** Set the send amount (explicit user edit); derives receiveAmount when a price is set. */\n setSendAmount: (value: string) => void\n /** Set the limit price (canonical: receive per send); derives receiveAmount when a send amount is set. */\n setLimitPrice: (value: string) => void\n}\n\n/**\n * Implements the linked-field derivation for limit orders:\n * - `limitPrice = receiveAmount / sendAmount`\n * - editing sendAmount recomputes receiveAmount, holding the current price\n * - editing limitPrice (with a send amount set) recomputes receiveAmount\n * - sendAmount never changes without an explicit user edit\n *\n * The receive amount (`toAmount`) is read-only in the UI — it is derived here\n * from the send amount and limit price, then sent to the routes request; the\n * receive card only displays the resulting quote.\n *\n * The limit price is NOT stored: it is purely a function of the `fromAmount`\n * and `toAmount` form fields (canonical receive-per-send). The UI layer handles\n * base/quote display inversion. Because it's derived, editing the send amount\n * only has to preserve the pre-edit price.\n */\nexport const useLinkedLimitFields = (): LinkedLimitFields => {\n const { setFieldValue } = useFieldActions()\n const [toChainId, toTokenAddress, sendAmount, receiveAmount] = useFieldValues(\n FormKeyHelper.getChainKey('to'),\n FormKeyHelper.getTokenKey('to'),\n FormKeyHelper.getAmountKey('from'),\n FormKeyHelper.getAmountKey('to')\n )\n const { token: toToken } = useToken(toChainId, toTokenAddress)\n\n const limitPrice = deriveLimitPrice(sendAmount, receiveAmount)\n\n const setSendAmount = (value: string): void => {\n // Hold the pre-edit price (derived from the current fields) so changing the\n // send amount rescales the receive amount instead of moving the price.\n setFieldValue('fromAmount', value, { isDirty: true, isTouched: true })\n const nextReceive = deriveReceiveAmount(\n value,\n limitPrice,\n toToken?.decimals\n )\n if (nextReceive) {\n setFieldValue('toAmount', nextReceive, { isDirty: true })\n }\n }\n\n const setLimitPrice = (value: string): void => {\n // Write unconditionally (including '') so the receive amount tracks the\n // price both ways — clearing the price clears the derived receive amount\n // instead of leaving a stale value that re-derives the old price.\n const nextReceive = deriveReceiveAmount(\n sendAmount,\n value,\n toToken?.decimals\n )\n setFieldValue('toAmount', nextReceive, { isDirty: true })\n }\n\n return {\n limitPrice,\n setSendAmount,\n setLimitPrice,\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA8BA,MAAa,6BAAgD;CAC3D,MAAM,EAAE,kBAAkB,gBAAgB;CAC1C,MAAM,CAAC,WAAW,gBAAgB,YAAY,iBAAiB,eAC7D,cAAc,YAAY,IAAI,GAC9B,cAAc,YAAY,IAAI,GAC9B,cAAc,aAAa,MAAM,GACjC,cAAc,aAAa,IAAI,CACjC;CACA,MAAM,EAAE,OAAO,YAAY,SAAS,WAAW,cAAc;CAE7D,MAAM,aAAa,iBAAiB,YAAY,aAAa;CAE7D,MAAM,iBAAiB,UAAwB;EAG7C,cAAc,cAAc,OAAO;GAAE,SAAS;GAAM,WAAW;EAAK,CAAC;EACrE,MAAM,cAAc,oBAClB,OACA,YACA,SAAS,QACX;EACA,IAAI,aACF,cAAc,YAAY,aAAa,EAAE,SAAS,KAAK,CAAC;CAE5D;CAEA,MAAM,iBAAiB,UAAwB;EAI7C,MAAM,cAAc,oBAClB,YACA,OACA,SAAS,QACX;EACA,cAAc,YAAY,aAAa,EAAE,SAAS,KAAK,CAAC;CAC1D;CAEA,OAAO;EACL;EACA;EACA;CACF;AACF"}