rujira.ui 0.1.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 (303) hide show
  1. package/.eslintrc.cjs +21 -0
  2. package/.tool-versions +1 -0
  3. package/i18n/.github/workflows/validate.yml +13 -0
  4. package/i18n/README.md +7 -0
  5. package/i18n/translations/template.json +448 -0
  6. package/i18n/update-template.js +19 -0
  7. package/i18n/validate.js +10 -0
  8. package/lib/esm/i18n/translations/template.json +448 -0
  9. package/lib/esm/src/components/buttons/Button.js +37 -0
  10. package/lib/esm/src/components/buttons/Popout.js +56 -0
  11. package/lib/esm/src/components/buttons/TxButton.js +42 -0
  12. package/lib/esm/src/components/buttons/__Popout.js +34 -0
  13. package/lib/esm/src/components/cards/Card.js +8 -0
  14. package/lib/esm/src/components/cards/GradientCard.js +8 -0
  15. package/lib/esm/src/components/footer/Footer.js +11 -0
  16. package/lib/esm/src/components/header/Accounts.js +211 -0
  17. package/lib/esm/src/components/header/Header.js +69 -0
  18. package/lib/esm/src/components/header/QuickLauncher.js +10 -0
  19. package/lib/esm/src/components/header/ResolveLink.js +13 -0
  20. package/lib/esm/src/components/icons/IconDenom.js +358 -0
  21. package/lib/esm/src/components/icons/Icons.js +228 -0
  22. package/lib/esm/src/components/icons/Networks.js +32 -0
  23. package/lib/esm/src/components/icons/Wallets.js +62 -0
  24. package/lib/esm/src/components/inputs/Checkbox.js +12 -0
  25. package/lib/esm/src/components/inputs/DecimalInput.js +35 -0
  26. package/lib/esm/src/components/inputs/DenomInput.js +22 -0
  27. package/lib/esm/src/components/inputs/DenomSelect.js +66 -0
  28. package/lib/esm/src/components/inputs/Input.js +25 -0
  29. package/lib/esm/src/components/inputs/Numeric.js +18 -0
  30. package/lib/esm/src/components/inputs/Radio.js +12 -0
  31. package/lib/esm/src/components/inputs/Select.js +29 -0
  32. package/lib/esm/src/components/inputs/Textarea.js +25 -0
  33. package/lib/esm/src/components/inputs/Toggle.js +13 -0
  34. package/lib/esm/src/components/loader/Loader.js +3 -0
  35. package/lib/esm/src/components/logos/RujiraLogo.js +2 -0
  36. package/lib/esm/src/components/notices/Warning.js +10 -0
  37. package/lib/esm/src/components/numbers/Decimal.js +14 -0
  38. package/lib/esm/src/components/numbers/Fiat.js +19 -0
  39. package/lib/esm/src/components/progress/Progress.js +9 -0
  40. package/lib/esm/src/components/slider/Slider.js +5 -0
  41. package/lib/esm/src/context/Affiliate.js +34 -0
  42. package/lib/esm/src/context/GlobalModal.js +35 -0
  43. package/lib/esm/src/d.js +1 -0
  44. package/lib/esm/src/helpers/index.js +65 -0
  45. package/lib/esm/src/helpers/number.js +8 -0
  46. package/lib/esm/src/hooks/useClickOutside.js +19 -0
  47. package/lib/esm/src/hooks/useLocalStorage.js +12 -0
  48. package/lib/esm/src/hooks/useQueryParam.js +31 -0
  49. package/lib/esm/src/hooks/useWindowSize.js +19 -0
  50. package/lib/esm/src/i18n/i18n.js +90 -0
  51. package/lib/esm/src/i18n/index.js +1 -0
  52. package/lib/esm/src/index.js +38 -0
  53. package/lib/esm/src/services/account.js +42 -0
  54. package/lib/esm/tsconfig.tsbuildinfo +1 -0
  55. package/package.json +47 -0
  56. package/src/assets/ghost-tokens/akt.png +0 -0
  57. package/src/assets/ghost-tokens/ampkuji.png +0 -0
  58. package/src/assets/ghost-tokens/arb.png +0 -0
  59. package/src/assets/ghost-tokens/atom.png +0 -0
  60. package/src/assets/ghost-tokens/axlusdc.png +0 -0
  61. package/src/assets/ghost-tokens/cro.png +0 -0
  62. package/src/assets/ghost-tokens/dot.png +0 -0
  63. package/src/assets/ghost-tokens/fet.png +0 -0
  64. package/src/assets/ghost-tokens/fuzn.png +0 -0
  65. package/src/assets/ghost-tokens/glmr.png +0 -0
  66. package/src/assets/ghost-tokens/gpaxg.png +0 -0
  67. package/src/assets/ghost-tokens/inj.png +0 -0
  68. package/src/assets/ghost-tokens/juno.png +0 -0
  69. package/src/assets/ghost-tokens/kuji.png +0 -0
  70. package/src/assets/ghost-tokens/luna.png +0 -0
  71. package/src/assets/ghost-tokens/lunc.png +0 -0
  72. package/src/assets/ghost-tokens/mnta.png +0 -0
  73. package/src/assets/ghost-tokens/ntrn.png +0 -0
  74. package/src/assets/ghost-tokens/osmo.png +0 -0
  75. package/src/assets/ghost-tokens/scrt.png +0 -0
  76. package/src/assets/ghost-tokens/shd.png +0 -0
  77. package/src/assets/ghost-tokens/sol.png +0 -0
  78. package/src/assets/ghost-tokens/stars.png +0 -0
  79. package/src/assets/ghost-tokens/statom.png +0 -0
  80. package/src/assets/ghost-tokens/stosmo.png +0 -0
  81. package/src/assets/ghost-tokens/usdc.png +0 -0
  82. package/src/assets/ghost-tokens/usk.png +0 -0
  83. package/src/assets/ghost-tokens/wavax.png +0 -0
  84. package/src/assets/ghost-tokens/wbnb.png +0 -0
  85. package/src/assets/ghost-tokens/wbtc.png +0 -0
  86. package/src/assets/ghost-tokens/weth.png +0 -0
  87. package/src/assets/ghost-tokens/wftm.png +0 -0
  88. package/src/assets/ghost-tokens/wglmr.png +0 -0
  89. package/src/assets/ghost-tokens/wmatic.png +0 -0
  90. package/src/assets/mono.woff +0 -0
  91. package/src/assets/tokens/acre.png +0 -0
  92. package/src/assets/tokens/akt.png +0 -0
  93. package/src/assets/tokens/amber.png +0 -0
  94. package/src/assets/tokens/ampkuji.png +0 -0
  95. package/src/assets/tokens/ampluna.png +0 -0
  96. package/src/assets/tokens/ampmnta.png +0 -0
  97. package/src/assets/tokens/ampwhale.png +0 -0
  98. package/src/assets/tokens/andr.png +0 -0
  99. package/src/assets/tokens/aqla.png +0 -0
  100. package/src/assets/tokens/aqua.png +0 -0
  101. package/src/assets/tokens/arb.png +0 -0
  102. package/src/assets/tokens/arch.png +0 -0
  103. package/src/assets/tokens/astro.png +0 -0
  104. package/src/assets/tokens/atom.png +0 -0
  105. package/src/assets/tokens/auto.png +0 -0
  106. package/src/assets/tokens/avax.png +0 -0
  107. package/src/assets/tokens/axl.png +0 -0
  108. package/src/assets/tokens/axlusdc.png +0 -0
  109. package/src/assets/tokens/axlusdt.png +0 -0
  110. package/src/assets/tokens/bad.png +0 -0
  111. package/src/assets/tokens/bch.png +0 -0
  112. package/src/assets/tokens/bfit.png +0 -0
  113. package/src/assets/tokens/bnb.png +0 -0
  114. package/src/assets/tokens/btc.png +0 -0
  115. package/src/assets/tokens/cheq.png +0 -0
  116. package/src/assets/tokens/cmdx.png +0 -0
  117. package/src/assets/tokens/cmst.png +0 -0
  118. package/src/assets/tokens/cnto.png +0 -0
  119. package/src/assets/tokens/core.png +0 -0
  120. package/src/assets/tokens/crbrus.png +0 -0
  121. package/src/assets/tokens/cre.png +0 -0
  122. package/src/assets/tokens/cro.png +0 -0
  123. package/src/assets/tokens/cub.png +0 -0
  124. package/src/assets/tokens/dai.png +0 -0
  125. package/src/assets/tokens/default.png +0 -0
  126. package/src/assets/tokens/doge.png +0 -0
  127. package/src/assets/tokens/dot.png +0 -0
  128. package/src/assets/tokens/dvpn.png +0 -0
  129. package/src/assets/tokens/dydx.png +0 -0
  130. package/src/assets/tokens/dym.png +0 -0
  131. package/src/assets/tokens/eth.png +0 -0
  132. package/src/assets/tokens/evmos.png +0 -0
  133. package/src/assets/tokens/flix.png +0 -0
  134. package/src/assets/tokens/frnz.png +0 -0
  135. package/src/assets/tokens/fury.legacy.png +0 -0
  136. package/src/assets/tokens/fury.png +0 -0
  137. package/src/assets/tokens/fuzn.png +0 -0
  138. package/src/assets/tokens/glmr.png +0 -0
  139. package/src/assets/tokens/glto.png +0 -0
  140. package/src/assets/tokens/gpaxg.png +0 -0
  141. package/src/assets/tokens/grav.png +0 -0
  142. package/src/assets/tokens/inj.png +0 -0
  143. package/src/assets/tokens/jkl.png +0 -0
  144. package/src/assets/tokens/juno.png +0 -0
  145. package/src/assets/tokens/kart.png +0 -0
  146. package/src/assets/tokens/kuji.png +0 -0
  147. package/src/assets/tokens/kune.png +0 -0
  148. package/src/assets/tokens/link.png +0 -0
  149. package/src/assets/tokens/loop.png +0 -0
  150. package/src/assets/tokens/ltc.png +0 -0
  151. package/src/assets/tokens/luna.png +0 -0
  152. package/src/assets/tokens/lunc.png +0 -0
  153. package/src/assets/tokens/lvn.png +0 -0
  154. package/src/assets/tokens/mars.png +0 -0
  155. package/src/assets/tokens/mnta.png +0 -0
  156. package/src/assets/tokens/mntl.png +0 -0
  157. package/src/assets/tokens/nami.png +0 -0
  158. package/src/assets/tokens/nausd.png +0 -0
  159. package/src/assets/tokens/nbtc.png +0 -0
  160. package/src/assets/tokens/neok.png +0 -0
  161. package/src/assets/tokens/newt.png +0 -0
  162. package/src/assets/tokens/nstk.png +0 -0
  163. package/src/assets/tokens/ntrn.png +0 -0
  164. package/src/assets/tokens/odin.png +0 -0
  165. package/src/assets/tokens/osmo.png +0 -0
  166. package/src/assets/tokens/pepe.png +0 -0
  167. package/src/assets/tokens/plnk.png +0 -0
  168. package/src/assets/tokens/plq.png +0 -0
  169. package/src/assets/tokens/qcaqla.png +0 -0
  170. package/src/assets/tokens/qcatom.png +0 -0
  171. package/src/assets/tokens/qcfuzn.png +0 -0
  172. package/src/assets/tokens/qckuji.png +0 -0
  173. package/src/assets/tokens/qcmnta.png +0 -0
  174. package/src/assets/tokens/rac.legacy.png +0 -0
  175. package/src/assets/tokens/rac.png +0 -0
  176. package/src/assets/tokens/ratom.png +0 -0
  177. package/src/assets/tokens/regen.png +0 -0
  178. package/src/assets/tokens/rfuzn.png +0 -0
  179. package/src/assets/tokens/rio.png +0 -0
  180. package/src/assets/tokens/rkuji.png +0 -0
  181. package/src/assets/tokens/roar.png +0 -0
  182. package/src/assets/tokens/ruji.png +0 -0
  183. package/src/assets/tokens/rune.png +0 -0
  184. package/src/assets/tokens/sayve.png +0 -0
  185. package/src/assets/tokens/scrt.png +0 -0
  186. package/src/assets/tokens/shd.legacy.png +0 -0
  187. package/src/assets/tokens/shd.png +0 -0
  188. package/src/assets/tokens/silk.png +0 -0
  189. package/src/assets/tokens/sol.png +0 -0
  190. package/src/assets/tokens/somm.png +0 -0
  191. package/src/assets/tokens/stars.png +0 -0
  192. package/src/assets/tokens/statom.png +0 -0
  193. package/src/assets/tokens/stinj.png +0 -0
  194. package/src/assets/tokens/stluna.png +0 -0
  195. package/src/assets/tokens/stosmo.png +0 -0
  196. package/src/assets/tokens/strd.png +0 -0
  197. package/src/assets/tokens/swth.png +0 -0
  198. package/src/assets/tokens/tia.png +0 -0
  199. package/src/assets/tokens/tori.png +0 -0
  200. package/src/assets/tokens/umee.png +0 -0
  201. package/src/assets/tokens/uni.png +0 -0
  202. package/src/assets/tokens/usdc.png +0 -0
  203. package/src/assets/tokens/usk.png +0 -0
  204. package/src/assets/tokens/usk_black.png +0 -0
  205. package/src/assets/tokens/ustc.png +0 -0
  206. package/src/assets/tokens/wavax.png +0 -0
  207. package/src/assets/tokens/wbtc.png +0 -0
  208. package/src/assets/tokens/wftm.png +0 -0
  209. package/src/assets/tokens/whale.png +0 -0
  210. package/src/assets/tokens/whlocal.png +0 -0
  211. package/src/assets/tokens/wink.png +0 -0
  212. package/src/assets/tokens/wmatic.png +0 -0
  213. package/src/assets/tokens/wsteth.png +0 -0
  214. package/src/assets/tokens/wtao.png +0 -0
  215. package/src/assets/tokens/xastro.png +0 -0
  216. package/src/assets/tokens/yieldeth.png +0 -0
  217. package/src/assets/tokens/yum.png +0 -0
  218. package/src/components/buttons/Button.tsx +80 -0
  219. package/src/components/buttons/Popout.tsx +74 -0
  220. package/src/components/buttons/TxButton.tsx +103 -0
  221. package/src/components/buttons/__Popout.tsx +56 -0
  222. package/src/components/cards/Card.tsx +17 -0
  223. package/src/components/cards/GradientCard.tsx +17 -0
  224. package/src/components/footer/Footer.tsx +117 -0
  225. package/src/components/header/Accounts.tsx +1021 -0
  226. package/src/components/header/Header.tsx +745 -0
  227. package/src/components/header/QuickLauncher.tsx +67 -0
  228. package/src/components/header/ResolveLink.tsx +81 -0
  229. package/src/components/icons/IconDenom.tsx +400 -0
  230. package/src/components/icons/Icons.tsx +686 -0
  231. package/src/components/icons/Networks.tsx +687 -0
  232. package/src/components/icons/Wallets.tsx +947 -0
  233. package/src/components/inputs/Checkbox.tsx +35 -0
  234. package/src/components/inputs/DecimalInput.tsx +72 -0
  235. package/src/components/inputs/DenomInput.tsx +65 -0
  236. package/src/components/inputs/DenomSelect.tsx +178 -0
  237. package/src/components/inputs/Input.tsx +66 -0
  238. package/src/components/inputs/Numeric.tsx +49 -0
  239. package/src/components/inputs/Radio.tsx +33 -0
  240. package/src/components/inputs/Select.tsx +69 -0
  241. package/src/components/inputs/Textarea.tsx +65 -0
  242. package/src/components/inputs/Toggle.tsx +38 -0
  243. package/src/components/loader/Loader.tsx +103 -0
  244. package/src/components/logos/RujiraLogo.tsx +83 -0
  245. package/src/components/notices/Warning.tsx +42 -0
  246. package/src/components/numbers/Decimal.tsx +43 -0
  247. package/src/components/numbers/Fiat.tsx +56 -0
  248. package/src/components/progress/Progress.tsx +40 -0
  249. package/src/components/slider/Slider.tsx +12 -0
  250. package/src/context/Affiliate.tsx +65 -0
  251. package/src/context/GlobalModal.tsx +115 -0
  252. package/src/d.ts +4 -0
  253. package/src/helpers/index.ts +73 -0
  254. package/src/helpers/number.ts +12 -0
  255. package/src/hooks/useClickOutside.ts +27 -0
  256. package/src/hooks/useLocalStorage.ts +20 -0
  257. package/src/hooks/useQueryParam.ts +46 -0
  258. package/src/hooks/useWindowSize.ts +26 -0
  259. package/src/i18n/i18n.tsx +102 -0
  260. package/src/i18n/index.ts +1 -0
  261. package/src/index.ts +54 -0
  262. package/src/scss/base/_colors.scss +23 -0
  263. package/src/scss/base/_display.scss +85 -0
  264. package/src/scss/base/_filters.scss +20 -0
  265. package/src/scss/base/_flex.scss +612 -0
  266. package/src/scss/base/_important.scss +3 -0
  267. package/src/scss/base/_normalize.scss +351 -0
  268. package/src/scss/base/_spacing.scss +290 -0
  269. package/src/scss/base/_tooltip.scss +9 -0
  270. package/src/scss/base/_typography.scss +279 -0
  271. package/src/scss/base/_variables.scss +72 -0
  272. package/src/scss/components/_button-group.scss +61 -0
  273. package/src/scss/components/_button.scss +459 -0
  274. package/src/scss/components/_decimal.scss +40 -0
  275. package/src/scss/components/_denom-select.scss +270 -0
  276. package/src/scss/components/_fiat.scss +34 -0
  277. package/src/scss/components/_footer.scss +27 -0
  278. package/src/scss/components/_header.scss +665 -0
  279. package/src/scss/components/_input.scss +82 -0
  280. package/src/scss/components/_loader.scss +20 -0
  281. package/src/scss/components/_modal.scss +138 -0
  282. package/src/scss/components/_numeric-input.scss +98 -0
  283. package/src/scss/components/_popout.scss +63 -0
  284. package/src/scss/components/_progress.scss +62 -0
  285. package/src/scss/components/_radio-checkbox.scss +79 -0
  286. package/src/scss/components/_select.scss +106 -0
  287. package/src/scss/components/_slider.scss +34 -0
  288. package/src/scss/components/_toggle.scss +120 -0
  289. package/src/scss/components/_warning.scss +65 -0
  290. package/src/scss/index.scss +37 -0
  291. package/src/scss/styledcomponents/_card.scss +130 -0
  292. package/src/scss/styledcomponents/_drawer.scss +36 -0
  293. package/src/scss/styledcomponents/_general.scss +20 -0
  294. package/src/scss/styledcomponents/_table.scss +302 -0
  295. package/src/scss/styledcomponents/_tabs.scss +97 -0
  296. package/src/scss/styledcomponents/_tag.scss +155 -0
  297. package/src/scss/unsorted/_general.scss +259 -0
  298. package/src/services/account.ts +53 -0
  299. package/tsconfig.json +25 -0
  300. package/tsconfig.node.json +11 -0
  301. package/vite.config.ts +7 -0
  302. package/vitest-setup.js +1 -0
  303. package/vitest.config.js +13 -0
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,80 @@
1
+ import { motion, useMotionTemplate, useMotionValue } from "motion/react";
2
+ import {
3
+ ComponentPropsWithRef,
4
+ ElementType,
5
+ ForwardedRef,
6
+ MouseEvent,
7
+ ReactNode,
8
+ Ref,
9
+ RefAttributes,
10
+ forwardRef,
11
+ } from "react";
12
+
13
+ export type ButtonProps<T extends ElementType = "button"> = {
14
+ as?: T;
15
+ label?: string;
16
+ className?: string;
17
+ children?: ReactNode;
18
+ } & DistributiveOmit<ComponentPropsWithRef<T>, "as">;
19
+
20
+ type FixedForwardRef = <T, P = {}>(
21
+ render: (props: P, ref: Ref<T>) => ReactNode
22
+ ) => (props: P & RefAttributes<T>) => ReactNode;
23
+
24
+ const fixedForwardRef = forwardRef as FixedForwardRef;
25
+
26
+ type DistributiveOmit<T, TOmitted extends PropertyKey> = T extends any
27
+ ? Omit<T, TOmitted>
28
+ : never;
29
+
30
+ const UnwrappedAnyComponent = <T extends ElementType>(
31
+ props: ButtonProps<T>,
32
+ ref: ForwardedRef<any>
33
+ ) => {
34
+ const { as: Comp = "button", label, children, className, ...rest } = props;
35
+
36
+ let mouseX = useMotionValue(0);
37
+ let mouseY = useMotionValue(0);
38
+
39
+ function handleMouseMove({ currentTarget, clientX, clientY }: MouseEvent) {
40
+ let { left, top } = currentTarget.getBoundingClientRect();
41
+ mouseX.set(clientX - left);
42
+ mouseY.set(clientY - top);
43
+ }
44
+
45
+ let gradient = "214, 21, 235, 1";
46
+ if (className?.includes("button--grey")) {
47
+ gradient = "96, 125, 139, 1";
48
+ } else if (className?.includes("button--red")) {
49
+ gradient = "244, 81, 30, 1";
50
+ } else if (className?.includes("button--blue")) {
51
+ gradient = "96, 251, 208, 1";
52
+ } else if (className?.includes("button--dark")) {
53
+ gradient = "90, 42, 209, 1";
54
+ }
55
+
56
+ return (
57
+ <Comp
58
+ {...rest}
59
+ ref={ref}
60
+ onMouseMove={handleMouseMove}
61
+ className={`button ${className}`}>
62
+ <motion.div
63
+ className="button__motion"
64
+ style={{
65
+ background: useMotionTemplate`
66
+ radial-gradient(
67
+ 150px circle at ${mouseX}px ${mouseY}px,
68
+ rgba(${gradient}),
69
+ transparent 100%
70
+ )
71
+ `,
72
+ }}
73
+ />
74
+ {label && <span>{label}</span>}
75
+ {children}
76
+ </Comp>
77
+ );
78
+ };
79
+
80
+ export const Button = fixedForwardRef(UnwrappedAnyComponent);
@@ -0,0 +1,74 @@
1
+ import clsx from "clsx";
2
+ import { FC, useEffect, useRef, useState } from "react";
3
+ import { Button } from "./Button";
4
+ import { AngleLeft, Ellipsis } from "../icons/Icons";
5
+
6
+ function getParentOffset(el: HTMLElement) {
7
+ const rect = el.getBoundingClientRect();
8
+ const p = el.closest(".relative")?.getBoundingClientRect();
9
+ return {
10
+ left: rect.left - (p?.left || 0),
11
+ top: rect.top - (p?.top || 0),
12
+ right: (p?.right || 0) - rect.right,
13
+ bottom: (p?.bottom || 0) - rect.bottom - 8,
14
+ };
15
+ }
16
+
17
+ export const Popout: FC<{
18
+ children?: React.ReactNode;
19
+ className?: string;
20
+ buttonClassName?: string;
21
+ }> = ({ children, className, buttonClassName }) => {
22
+ const [open, setOpen] = useState(false);
23
+ const node = useRef<HTMLDivElement>(null);
24
+
25
+ useEffect(() => {
26
+ if (open) {
27
+ document.addEventListener("mousedown", handleClickOutside);
28
+ const nav = node.current?.querySelector("nav");
29
+ if (node.current && nav) {
30
+ const p = getParentOffset(node?.current);
31
+ nav.style.bottom = p.bottom + "px";
32
+ nav.style.right = p.right + node.current.offsetWidth + 4 + "px";
33
+ }
34
+ } else {
35
+ document.removeEventListener("mousedown", handleClickOutside);
36
+ }
37
+ return () => {
38
+ document.removeEventListener("mousedown", handleClickOutside);
39
+ };
40
+ }, [open]);
41
+
42
+ const handleClickOutside = (e: any) => {
43
+ const ref = node.current;
44
+ if (ref) {
45
+ if (ref.contains(e.target)) {
46
+ return;
47
+ }
48
+ }
49
+ e.stopPropagation();
50
+ e.stopImmediatePropagation();
51
+ setOpen(false);
52
+ return false;
53
+ };
54
+
55
+ return (
56
+ <div
57
+ ref={node}
58
+ className={clsx({
59
+ popout: true,
60
+ "popout--open": open,
61
+ [`${className}`]: className,
62
+ })}>
63
+ <Button
64
+ onClick={() => setOpen(!open)}
65
+ className={clsx({
66
+ "button--grey button--small": !buttonClassName,
67
+ [`${buttonClassName}`]: buttonClassName,
68
+ })}>
69
+ {!open ? <Ellipsis /> : <AngleLeft />}
70
+ </Button>
71
+ {children}
72
+ </div>
73
+ );
74
+ };
@@ -0,0 +1,103 @@
1
+ import { ElementType, FC, useEffect, useState } from "react";
2
+ import toast, { Renderable } from "react-hot-toast";
3
+ import { AccountProvider, Msg, Simulation, TxResult } from "rujira.js";
4
+ import { networkTxLink } from "rujira.js/src/network";
5
+ import { i18n } from "../../i18n";
6
+ import { Warning } from "../notices/Warning";
7
+ import { Decimal } from "../numbers/Decimal";
8
+ import { Button, ButtonProps } from "./Button";
9
+
10
+ export type TxButtonProps<T extends ElementType = "button"> = ButtonProps<T> & {
11
+ accountProvider: AccountProvider;
12
+ msg: Msg | null;
13
+ SimulationComponent?: ElementType<{ simulation?: Simulation }>;
14
+ onSuccess?: (res: TxResult) => void;
15
+ toastOpts?: {
16
+ loading?: Renderable;
17
+ success?: Renderable | ((res: TxResult) => Renderable);
18
+ error?: Renderable | ((err: any) => Renderable);
19
+ };
20
+ };
21
+
22
+ export const TxButton: FC<TxButtonProps> = ({
23
+ accountProvider,
24
+ msg,
25
+ onSuccess,
26
+ SimulationComponent = DefaultSimulationComponent,
27
+ children,
28
+ toastOpts = {},
29
+ ...rest
30
+ }) => {
31
+ const { simulate, signAndBroadcast } = accountProvider;
32
+ const [simulation, setSimulation] = useState<Simulation>();
33
+ const [simulationError, setSimulationError] = useState<Error>();
34
+ const { loading, success, error } = toastOpts;
35
+
36
+ useEffect(() => {
37
+ setSimulationError(undefined);
38
+ msg && simulate(msg).then(setSimulation).catch(setSimulationError);
39
+ }, [simulate, msg]);
40
+
41
+ const onClick = () => {
42
+ if (!simulation) throw new Error(`Simulation required`);
43
+ if (!msg) throw new Error(`Msg required`);
44
+ const p = signAndBroadcast(simulation, msg).then((res) => {
45
+ onSuccess && onSuccess(res);
46
+ return res;
47
+ });
48
+ toast.promise(p, {
49
+ loading: loading || i18n.t("Submitting Transaction"),
50
+ success: success || successHandler,
51
+ error:
52
+ error ||
53
+ ((err: any) => i18n.t(err.message || "Error Submitting Transaction")),
54
+ });
55
+ };
56
+
57
+ return (
58
+ <div className="iflex dir-c">
59
+ <Button {...rest} onClick={onClick} disabled={!simulation || !msg}>
60
+ {children}
61
+ </Button>
62
+ <SimulationComponent simulation={simulation} error={simulationError} />
63
+ </div>
64
+ );
65
+ };
66
+
67
+ const DefaultSimulationComponent: FC<{
68
+ simulation?: Simulation;
69
+ error?: Error;
70
+ }> = ({ simulation, error }) => {
71
+ if (!error) {
72
+ return (
73
+ <small className="mt-1 color-white">
74
+ {simulation ? (
75
+ <>
76
+ {i18n.t("Network fee")}:{" "}
77
+ <Decimal
78
+ amount={simulation.amount}
79
+ decimals={simulation.asset.decimals}
80
+ symbol={simulation.asset.symbol}
81
+ />
82
+ </>
83
+ ) : (
84
+ "calculating..."
85
+ )}
86
+ </small>
87
+ );
88
+ }
89
+ return <Warning color="red" className="condensed mt-1" msg={error.message} />;
90
+ };
91
+
92
+ const successHandler = (res: TxResult): Renderable => (
93
+ <p>
94
+ {i18n.t("Transaction Succeeded")}
95
+ <br />
96
+ <a
97
+ href={networkTxLink(res)}
98
+ target="_blank"
99
+ className="color-white no-underline fs-12">
100
+ {res.txHash.slice(0, 8) + "..." + res.txHash.slice(-8)}
101
+ </a>
102
+ </p>
103
+ );
@@ -0,0 +1,56 @@
1
+ import { useRef, useState } from "react";
2
+ import { createPortal } from "react-dom";
3
+
4
+ interface Props {
5
+ children: React.ReactNode;
6
+ position: { top: number; left: number };
7
+ visible: boolean;
8
+ }
9
+
10
+ export const Popout: React.FC<Props> = ({ children, position, visible }) => {
11
+ const node = useRef<HTMLElement>(null);
12
+ if (!visible) return null;
13
+
14
+ return createPortal(
15
+ <nav
16
+ ref={node}
17
+ className="popout condensed"
18
+ style={{
19
+ top: position.top - (node.current?.offsetHeight || 0) + 8,
20
+ left: position.left - (node.current?.offsetWidth || 0),
21
+ }}>
22
+ {children}
23
+ </nav>,
24
+ document.body
25
+ );
26
+ };
27
+
28
+ export const usePopout = () => {
29
+ const [popoutState, setPopoutState] = useState<{
30
+ content: React.ReactNode;
31
+ position: { top: number; left: number };
32
+ visible: boolean;
33
+ }>({
34
+ content: "",
35
+ position: { top: 0, left: 0 },
36
+ visible: false,
37
+ });
38
+
39
+ const showPopout = (content: React.ReactNode, target: HTMLElement) => {
40
+ const rect = target.getBoundingClientRect();
41
+ setPopoutState({
42
+ content,
43
+ position: {
44
+ top: rect.top + window.scrollY + rect.height,
45
+ left: rect.left + window.scrollX,
46
+ },
47
+ visible: true,
48
+ });
49
+ };
50
+
51
+ const hidePopout = () => {
52
+ setPopoutState((prev) => ({ ...prev, visible: false }));
53
+ };
54
+
55
+ return { popoutState, showPopout, hidePopout };
56
+ };
@@ -0,0 +1,17 @@
1
+ import clsx from "clsx";
2
+
3
+ type Props = {
4
+ className?: string;
5
+ children?: React.ReactNode;
6
+ };
7
+ export const Card: React.FC<Props> = ({ className, children }) => {
8
+ return (
9
+ <div
10
+ className={clsx({
11
+ "card p-3 color-white": true,
12
+ [`${className}`]: className,
13
+ })}>
14
+ {children}
15
+ </div>
16
+ );
17
+ };
@@ -0,0 +1,17 @@
1
+ import clsx from "clsx";
2
+
3
+ type Props = {
4
+ className?: string;
5
+ children?: React.ReactNode;
6
+ };
7
+ export const GradientCard: React.FC<Props> = ({ className, children }) => {
8
+ return (
9
+ <div
10
+ className={clsx({
11
+ "gradient-card bg-black p-3 color-white": true,
12
+ [`${className}`]: className,
13
+ })}>
14
+ {children}
15
+ </div>
16
+ );
17
+ };