@ensofinance/checkout-widget 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/dist/checkout-widget.es.js +52889 -0
  2. package/dist/checkout-widget.es.js.map +1 -0
  3. package/dist/checkout-widget.umd.js +203 -0
  4. package/dist/checkout-widget.umd.js.map +1 -0
  5. package/dist/index.d.ts +23 -0
  6. package/enso-api.yaml +1982 -0
  7. package/orval.config.ts +25 -0
  8. package/package.json +79 -0
  9. package/src/assets/BinanceBadge.svg +4 -0
  10. package/src/assets/CoinbaseIcon.svg +4 -0
  11. package/src/assets/USD Coin (USDC).svg +5 -0
  12. package/src/assets/avecIcon.svg +5 -0
  13. package/src/assets/base.webp +0 -0
  14. package/src/assets/depositIcon.svg +6 -0
  15. package/src/assets/eth.webp +0 -0
  16. package/src/assets/ethMainnetIcon.svg +10 -0
  17. package/src/assets/fail.svg +5 -0
  18. package/src/assets/kraken.png +0 -0
  19. package/src/assets/logo.svg +10 -0
  20. package/src/assets/mastercard.png +0 -0
  21. package/src/assets/metamask.png +0 -0
  22. package/src/assets/rabby.png +0 -0
  23. package/src/assets/success.svg +4 -0
  24. package/src/assets/usdc.webp +0 -0
  25. package/src/assets/usdt.webp +0 -0
  26. package/src/assets/visa.png +0 -0
  27. package/src/assets/visa.webp +0 -0
  28. package/src/components/BridgeFee.tsx +58 -0
  29. package/src/components/ChakraProvider.tsx +372 -0
  30. package/src/components/Checkout.tsx +127 -0
  31. package/src/components/CheckoutModal.tsx +22 -0
  32. package/src/components/CircleTimer.tsx +66 -0
  33. package/src/components/CurrencySwapDisplay.tsx +153 -0
  34. package/src/components/DepositProcessing.tsx +116 -0
  35. package/src/components/ExchangeConfirmSecurity.tsx +110 -0
  36. package/src/components/QuoteParameters.tsx +341 -0
  37. package/src/components/TransactionDetailRow.tsx +124 -0
  38. package/src/components/cards/AssetCard.tsx +167 -0
  39. package/src/components/cards/ExchangeCard.tsx +53 -0
  40. package/src/components/cards/OptionCard.tsx +59 -0
  41. package/src/components/cards/WalletCard.tsx +99 -0
  42. package/src/components/cards/index.ts +6 -0
  43. package/src/components/modal.tsx +83 -0
  44. package/src/components/steps/ExchangeFlow.tsx +1402 -0
  45. package/src/components/steps/InitialStep.tsx +169 -0
  46. package/src/components/steps/QuoteStep.tsx +121 -0
  47. package/src/components/steps/WalletAmountStep.tsx +258 -0
  48. package/src/components/steps/WalletConfirmStep.tsx +404 -0
  49. package/src/components/steps/WalletTokenStep.tsx +128 -0
  50. package/src/components/ui/index.tsx +394 -0
  51. package/src/components/ui/styled.tsx +85 -0
  52. package/src/components/ui/toaster.tsx +43 -0
  53. package/src/components/ui/tooltip.tsx +46 -0
  54. package/src/enso-api/api.ts +173 -0
  55. package/src/enso-api/custom-instance.ts +35 -0
  56. package/src/enso-api/index.ts +5119 -0
  57. package/src/enso-api/model/action.ts +17 -0
  58. package/src/enso-api/model/actionAction.ts +52 -0
  59. package/src/enso-api/model/actionInputs.ts +12 -0
  60. package/src/enso-api/model/actionToBundle.ts +19 -0
  61. package/src/enso-api/model/actionToBundleAction.ts +53 -0
  62. package/src/enso-api/model/actionToBundleArgs.ts +12 -0
  63. package/src/enso-api/model/bundleControllerBundleShortcutTransactionParams.ts +53 -0
  64. package/src/enso-api/model/bundleControllerBundleShortcutTransactionRoutingStrategy.ts +23 -0
  65. package/src/enso-api/model/bundleShortcutTransaction.ts +35 -0
  66. package/src/enso-api/model/bundleShortcutTransactionAmountsOut.ts +15 -0
  67. package/src/enso-api/model/bundleShortcutTransactionFeeAmount.ts +12 -0
  68. package/src/enso-api/model/connectedNetwork.ts +16 -0
  69. package/src/enso-api/model/hop.ts +24 -0
  70. package/src/enso-api/model/hopArgs.ts +12 -0
  71. package/src/enso-api/model/index.ts +70 -0
  72. package/src/enso-api/model/iporControllerIporShortcutTransactionParams.ts +21 -0
  73. package/src/enso-api/model/iporShortcutInput.ts +33 -0
  74. package/src/enso-api/model/iporShortcutTransaction.ts +22 -0
  75. package/src/enso-api/model/lZDestinationTokenData.ts +19 -0
  76. package/src/enso-api/model/lZPoolLookupResponse.ts +26 -0
  77. package/src/enso-api/model/layerZeroControllerGetPoolAddressParams.ts +29 -0
  78. package/src/enso-api/model/network.ts +15 -0
  79. package/src/enso-api/model/networksControllerNetworksParams.ts +21 -0
  80. package/src/enso-api/model/nonTokenizedControllerTokens200.ts +15 -0
  81. package/src/enso-api/model/nonTokenizedControllerTokens200AllOf.ts +16 -0
  82. package/src/enso-api/model/nonTokenizedControllerTokensParams.ts +41 -0
  83. package/src/enso-api/model/nonTokenizedModel.ts +27 -0
  84. package/src/enso-api/model/nontokenizedControllerRouteNontokenizedShorcutTransactionParams.ts +64 -0
  85. package/src/enso-api/model/nontokenizedControllerRouteNontokenizedShorcutTransactionRoutingStrategy.ts +22 -0
  86. package/src/enso-api/model/paginatedResult.ts +16 -0
  87. package/src/enso-api/model/paginationMeta.ts +27 -0
  88. package/src/enso-api/model/positionModel.ts +77 -0
  89. package/src/enso-api/model/price.ts +20 -0
  90. package/src/enso-api/model/pricesControllerGetPricesParams.ts +17 -0
  91. package/src/enso-api/model/project.ts +15 -0
  92. package/src/enso-api/model/protocol.ts +15 -0
  93. package/src/enso-api/model/protocolModel.ts +26 -0
  94. package/src/enso-api/model/protocolsControllerFindAllParams.ts +21 -0
  95. package/src/enso-api/model/routeShortcutTransaction.ts +33 -0
  96. package/src/enso-api/model/routeShortcutVariableInputs.ts +68 -0
  97. package/src/enso-api/model/routeShortcutVariableInputsRoutingStrategy.ts +27 -0
  98. package/src/enso-api/model/routeShortcutVariableInputsVariableEstimates.ts +14 -0
  99. package/src/enso-api/model/routerControllerRouteShortcutTransactionParams.ts +91 -0
  100. package/src/enso-api/model/routerControllerRouteShortcutTransactionRoutingStrategy.ts +23 -0
  101. package/src/enso-api/model/standard.ts +18 -0
  102. package/src/enso-api/model/standardAction.ts +20 -0
  103. package/src/enso-api/model/standardActionAction.ts +53 -0
  104. package/src/enso-api/model/tokenModel.ts +36 -0
  105. package/src/enso-api/model/tokensControllerTokens200.ts +15 -0
  106. package/src/enso-api/model/tokensControllerTokens200AllOf.ts +16 -0
  107. package/src/enso-api/model/tokensControllerTokensParams.ts +91 -0
  108. package/src/enso-api/model/tokensControllerTokensType.ts +19 -0
  109. package/src/enso-api/model/transaction.ts +17 -0
  110. package/src/enso-api/model/userOperation.ts +28 -0
  111. package/src/enso-api/model/walletApproveTransaction.ts +24 -0
  112. package/src/enso-api/model/walletApproveTransactionTx.ts +15 -0
  113. package/src/enso-api/model/walletBalance.ts +29 -0
  114. package/src/enso-api/model/walletControllerCreateApproveTransactionParams.ts +35 -0
  115. package/src/enso-api/model/walletControllerCreateApproveTransactionRoutingStrategy.ts +23 -0
  116. package/src/enso-api/model/walletControllerWalletBalancesParams.ts +25 -0
  117. package/src/index.ts +17 -0
  118. package/src/store.ts +68 -0
  119. package/src/types/assets.d.ts +29 -0
  120. package/src/types/index.ts +21 -0
  121. package/src/util/common.tsx +324 -0
  122. package/src/util/constants.tsx +213 -0
  123. package/src/util/enso-hooks.tsx +203 -0
  124. package/src/util/index.tsx +68 -0
  125. package/src/util/tx-tracker.tsx +301 -0
  126. package/src/util/wallet.tsx +258 -0
  127. package/tsconfig.json +13 -0
  128. package/vite.config.ts +51 -0
@@ -0,0 +1,394 @@
1
+ // Theme-aware UI components to replace @ensofinance/checkout-ui-library imports
2
+ import React, { forwardRef, useMemo } from "react";
3
+ import {
4
+ Button as ChakraButton,
5
+ IconButton as ChakraIconButton,
6
+ Input as ChakraInput,
7
+ Box,
8
+ Text,
9
+ Flex,
10
+ Image,
11
+ type ButtonProps as ChakraButtonProps,
12
+ type IconButtonProps as ChakraIconButtonProps,
13
+ type InputProps as ChakraInputProps,
14
+ chakra,
15
+ Select as ChakraSelect,
16
+ createListCollection,
17
+ Portal,
18
+ Span,
19
+ Link,
20
+ Badge,
21
+ useRecipe,
22
+ } from "@chakra-ui/react";
23
+ import { inputRecipe } from "../ChakraProvider";
24
+
25
+ // Button Component
26
+ export interface ButtonProps
27
+ extends Omit<ChakraButtonProps, "variant" | "size"> {
28
+ variant?: "primary" | "secondary" | "lightGray";
29
+ visual?: "primary" | "secondary" | "lightGray" | "solid";
30
+ size?: "mdPlus" | "sm" | "md" | "lg";
31
+ onClick?: () => void;
32
+ isDisabled?: boolean;
33
+ }
34
+
35
+ interface CustomInputProps extends Omit<ChakraInputProps, "variant"> {
36
+ variant?: "text" | "outline" | "subtle" | "flushed";
37
+ }
38
+
39
+ export const Input = forwardRef<HTMLInputElement, CustomInputProps>(
40
+ ({ variant, ...props }, ref) => {
41
+ const recipe = useRecipe({ recipe: inputRecipe });
42
+
43
+ // Handle custom "text" variant using the recipe
44
+ if (variant === "text") {
45
+ const styles = recipe({ variant: "text" });
46
+ return <chakra.input ref={ref} css={styles} {...props} />;
47
+ }
48
+
49
+ // For built-in variants, use ChakraInput
50
+ return <ChakraInput ref={ref} variant={variant as any} {...props} />;
51
+ },
52
+ );
53
+
54
+ export const Button = chakra(ChakraButton, {
55
+ base: {
56
+ display: "flex",
57
+ width: "100%",
58
+ justifyContent: "center",
59
+ alignItems: "center",
60
+ borderRadius: "md",
61
+ flexShrink: "initial",
62
+ // cursor: "pointer",
63
+ // transition: "all 0.2s ease-in-out",
64
+ },
65
+ variants: {
66
+ visual: {
67
+ solid: {
68
+ bg: "primary",
69
+ // color: "customWhite",
70
+ _hover: {
71
+ bg: "primary.emphasis",
72
+ // color: "customWhite",
73
+ },
74
+ },
75
+ grayFilled: {
76
+ bg: "bg.emphasized",
77
+ color: "customWhite",
78
+ },
79
+ lightGray: {
80
+ bg: "bg.subtle",
81
+ color: "fg",
82
+ },
83
+ },
84
+ size: {
85
+ sm: { padding: "8px 16px", fontSize: "14px", fontWeight: "medium" },
86
+ md: { padding: "4", fontSize: "16px" },
87
+ lg: { padding: "8", fontSize: "24px" },
88
+ },
89
+ },
90
+ defaultVariants: {
91
+ visual: "solid",
92
+ size: "sm",
93
+ },
94
+ });
95
+
96
+ Button.displayName = "Button";
97
+
98
+ // IconButton Component
99
+ export interface IconButtonProps
100
+ extends Omit<ChakraIconButtonProps, "variant"> {
101
+ variant?: "primary" | "secondary" | "lightGray";
102
+ }
103
+
104
+ export const IconButton = forwardRef<HTMLButtonElement, IconButtonProps>(
105
+ ({ variant = "secondary", children, ...props }, ref) => {
106
+ return (
107
+ <ChakraIconButton
108
+ ref={ref}
109
+ variant="ghost"
110
+ bg="transparent"
111
+ border="none"
112
+ _hover={{
113
+ bg: "bg.subtle",
114
+ }}
115
+ _active={{
116
+ bg: "bg.emphasized",
117
+ }}
118
+ color="fg.muted"
119
+ {...props}
120
+ >
121
+ {children}
122
+ </ChakraIconButton>
123
+ );
124
+ },
125
+ );
126
+
127
+ IconButton.displayName = "IconButton";
128
+
129
+ export const Tab = chakra("div", {
130
+ base: {
131
+ p: "10px 12px",
132
+ h: "32px",
133
+ display: "flex",
134
+ justifyContent: "center",
135
+ alignItems: "center",
136
+ gap: "8px",
137
+ borderRadius: "6px",
138
+ cursor: "pointer",
139
+ color: "fg.muted",
140
+ fontSize: "14px",
141
+ fontWeight: "medium",
142
+ transition: "all 0.2s ease-in-out",
143
+ _hover: {
144
+ bg: "bg.subtle",
145
+ color: "fg",
146
+ },
147
+ },
148
+ });
149
+
150
+ // Select Component
151
+ export interface SelectItem {
152
+ value: string;
153
+ label: string;
154
+ detail?: string;
155
+ icon?: string;
156
+ detailIsLink?: boolean;
157
+ }
158
+
159
+ export interface SelectProps {
160
+ items: SelectItem[];
161
+ variant?: "filled" | "customOutline";
162
+ size?: "xs" | "sm" | "md" | "lg";
163
+ width?: string | number;
164
+ placeholder?: string | React.ReactNode;
165
+ label?: string | React.ReactNode;
166
+ defaultValue?: string;
167
+ value?: string;
168
+ onChange?: (value: string) => void;
169
+ }
170
+
171
+ export const Select: React.FC<SelectProps> = ({
172
+ items,
173
+ variant = "customOutline",
174
+ size = "md",
175
+ width = "320px",
176
+ placeholder,
177
+ label,
178
+ defaultValue,
179
+ onChange,
180
+ value,
181
+ }) => {
182
+ const collection = React.useMemo(
183
+ () =>
184
+ createListCollection({
185
+ items: items.map((item) => ({
186
+ label: item.label,
187
+ value: item.value,
188
+ })),
189
+ }),
190
+ [items],
191
+ );
192
+
193
+ return (
194
+ <ChakraSelect.Root
195
+ collection={collection}
196
+ defaultValue={defaultValue ? [defaultValue] : undefined}
197
+ onValueChange={(details) => onChange?.(details.value[0])}
198
+ value={value ? [value] : undefined}
199
+ size={size}
200
+ width={width}
201
+ >
202
+ <ChakraSelect.HiddenSelect />
203
+ {label && <ChakraSelect.Label>{label}</ChakraSelect.Label>}
204
+ <ChakraSelect.Control>
205
+ <ChakraSelect.Trigger>
206
+ <ChakraSelect.ValueText
207
+ placeholder={placeholder as string}
208
+ />
209
+ </ChakraSelect.Trigger>
210
+ <ChakraSelect.IndicatorGroup>
211
+ <ChakraSelect.Indicator />
212
+ </ChakraSelect.IndicatorGroup>
213
+ </ChakraSelect.Control>
214
+ <Portal>
215
+ <ChakraSelect.Positioner>
216
+ <ChakraSelect.Content>
217
+ {items.map((item) => {
218
+ const { label, value, icon, detail, detailIsLink } =
219
+ item;
220
+ return (
221
+ <ChakraSelect.Item
222
+ item={{ label, value }}
223
+ key={value}
224
+ >
225
+ <Flex
226
+ justify="space-between"
227
+ align="center"
228
+ w="100%"
229
+ >
230
+ <Flex align="center" gap={2}>
231
+ {icon && (
232
+ <Image
233
+ src={icon}
234
+ w={"16px"}
235
+ h={"16px"}
236
+ alt="icon"
237
+ />
238
+ )}
239
+ <Span>{label}</Span>
240
+ </Flex>
241
+ {detail &&
242
+ (detailIsLink ? (
243
+ <Link
244
+ href="#"
245
+ color="fg"
246
+ fontWeight="medium"
247
+ >
248
+ {detail}
249
+ </Link>
250
+ ) : (
251
+ <Span
252
+ color="fg.muted"
253
+ fontWeight="medium"
254
+ >
255
+ {detail}
256
+ </Span>
257
+ ))}
258
+ </Flex>
259
+ <ChakraSelect.ItemIndicator />
260
+ </ChakraSelect.Item>
261
+ );
262
+ })}
263
+ </ChakraSelect.Content>
264
+ </ChakraSelect.Positioner>
265
+ </Portal>
266
+ </ChakraSelect.Root>
267
+ );
268
+ };
269
+
270
+ // Card Component
271
+ export interface CardProps {
272
+ children: React.ReactNode;
273
+ padding?: string;
274
+ onClick?: () => void;
275
+ selected?: boolean;
276
+ disabled?: boolean;
277
+ }
278
+
279
+ const CardTitle: React.FC<{ children: React.ReactNode }> = ({ children }) => (
280
+ <Text fontSize="md" fontWeight="500" color="fg">
281
+ {children}
282
+ </Text>
283
+ );
284
+
285
+ const CardDescription: React.FC<{ children: React.ReactNode }> = ({
286
+ children,
287
+ }) => (
288
+ <Text fontSize="xs" color="fg.muted">
289
+ {children}
290
+ </Text>
291
+ );
292
+
293
+ export const Card: React.FC<CardProps> & {
294
+ Title: typeof CardTitle;
295
+ Description: typeof CardDescription;
296
+ } = ({
297
+ children,
298
+ padding = "8px 12px",
299
+ onClick,
300
+ selected = false,
301
+ disabled = false,
302
+ }) => {
303
+ return (
304
+ <Box
305
+ p={padding}
306
+ borderRadius="md"
307
+ border="1px solid"
308
+ borderColor={selected ? "primary" : "border"}
309
+ bg="bg"
310
+ cursor={onClick && !disabled ? "pointer" : "default"}
311
+ opacity={disabled ? 0.5 : 1}
312
+ _hover={
313
+ selected
314
+ ? undefined
315
+ : {
316
+ borderColor: "border.emphasized",
317
+ }
318
+ }
319
+ onClick={disabled ? undefined : onClick}
320
+ >
321
+ {children}
322
+ </Box>
323
+ );
324
+ };
325
+
326
+ Card.Title = CardTitle;
327
+ Card.Description = CardDescription;
328
+
329
+ export const Tag = chakra(Badge, {
330
+ base: {
331
+ display: "flex",
332
+ padding: "2px 10px",
333
+ justifyContent: "center",
334
+ alignItems: "center",
335
+ lineHeight: "16px",
336
+ borderRadius: "full",
337
+ fontSize: "xs",
338
+ color: "fg.muted",
339
+ backgroundColor: "bg.subtle",
340
+ width: "fit-content",
341
+ fontWeight: 600,
342
+ },
343
+ });
344
+
345
+ // Helper Component
346
+ export interface HelperProps {
347
+ children: React.ReactNode;
348
+ type?: "info" | "warning" | "error" | "success";
349
+ }
350
+
351
+ export const Helper: React.FC<HelperProps> = ({ children, type = "info" }) => {
352
+ const style = useMemo(() => {
353
+ const typeStyles = {
354
+ info: {
355
+ bg: "bg.subtle",
356
+ color: "fg.muted",
357
+ borderColor: "bg.subtle",
358
+ },
359
+ warning: {
360
+ bg: "warning",
361
+ color: "bg",
362
+ borderColor: "warning",
363
+ },
364
+ error: {
365
+ bg: "error",
366
+ color: "bg",
367
+ borderColor: "error",
368
+ },
369
+ success: {
370
+ bg: "success",
371
+ color: "bg",
372
+ borderColor: "success",
373
+ },
374
+ };
375
+
376
+ return typeStyles[type];
377
+ }, [type]);
378
+
379
+ return (
380
+ <Flex
381
+ gap={1}
382
+ p={3}
383
+ borderRadius="md"
384
+ border="1px solid"
385
+ fontSize="sm"
386
+ {...style}
387
+ >
388
+ {children}
389
+ </Flex>
390
+ );
391
+ };
392
+
393
+ // Export Tooltip component
394
+ export { Tooltip } from "./tooltip";
@@ -0,0 +1,85 @@
1
+ import { chakra } from "@chakra-ui/react";
2
+
3
+ // Shared HeaderWrapper variants
4
+ export const HeaderWrapper = chakra("div", {
5
+ base: {
6
+ display: "flex",
7
+ flexDirection: "row",
8
+ width: "100%",
9
+ alignItems: "center",
10
+ gap: "12px",
11
+ paddingBottom: "16px",
12
+ borderBottom: "1px solid",
13
+ borderColor: "border",
14
+ },
15
+ });
16
+
17
+ export const HeaderWrapperSpaceBetween = chakra("div", {
18
+ base: {
19
+ display: "flex",
20
+ flexDirection: "row",
21
+ width: "100%",
22
+ justifyContent: "space-between",
23
+ alignItems: "center",
24
+ gap: "12px",
25
+ paddingBottom: "16px",
26
+ borderBottom: "1px solid",
27
+ borderColor: "border",
28
+ },
29
+ });
30
+
31
+ // Shared HeaderTitle component
32
+ export const HeaderTitle = chakra("h2", {
33
+ base: {
34
+ fontWeight: "600",
35
+ fontSize: "14px",
36
+ lineHeight: "120%",
37
+ letterSpacing: "-0.4px",
38
+ color: "fg",
39
+ },
40
+ });
41
+
42
+ // Shared HeaderDescription component
43
+ export const HeaderDescription = chakra("p", {
44
+ base: {
45
+ fontWeight: "400",
46
+ fontSize: "12px",
47
+ lineHeight: "100%",
48
+ letterSpacing: "-0.4px",
49
+ color: "fg.muted",
50
+ },
51
+ });
52
+
53
+ // Shared ListWrapper component
54
+ export const ListWrapper = chakra("div", {
55
+ base: {
56
+ display: "flex",
57
+ flexDirection: "column",
58
+ width: "100%",
59
+ justifyContent: "center",
60
+ alignItems: "center",
61
+ gap: 4,
62
+ },
63
+ });
64
+
65
+ export const BodyWrapper = chakra("div", {
66
+ base: {
67
+ display: "flex",
68
+ flexDirection: "column",
69
+ width: "100%",
70
+ justifyContent: "center",
71
+ alignItems: "center",
72
+ gap: "12px",
73
+ paddingTop: "16px",
74
+ },
75
+ });
76
+
77
+ export const Divider = chakra("hr", {
78
+ base: {
79
+ width: "100%",
80
+ color: "border",
81
+ backgroundColor: "border",
82
+ borderColor: "border",
83
+ },
84
+ });
85
+
@@ -0,0 +1,43 @@
1
+ "use client"
2
+
3
+ import {
4
+ Toaster as ChakraToaster,
5
+ Portal,
6
+ Spinner,
7
+ Stack,
8
+ Toast,
9
+ createToaster,
10
+ } from "@chakra-ui/react"
11
+
12
+ export const toaster = createToaster({
13
+ placement: "bottom-end",
14
+ pauseOnPageIdle: true,
15
+ })
16
+
17
+ export const Toaster = () => {
18
+ return (
19
+ <Portal>
20
+ <ChakraToaster toaster={toaster} insetInline={{ mdDown: "4" }}>
21
+ {(toast) => (
22
+ <Toast.Root width={{ md: "sm" }}>
23
+ {toast.type === "loading" ? (
24
+ <Spinner size="sm" color="blue.solid" />
25
+ ) : (
26
+ <Toast.Indicator />
27
+ )}
28
+ <Stack gap="1" flex="1" maxWidth="100%">
29
+ {toast.title && <Toast.Title>{toast.title}</Toast.Title>}
30
+ {toast.description && (
31
+ <Toast.Description>{toast.description}</Toast.Description>
32
+ )}
33
+ </Stack>
34
+ {toast.action && (
35
+ <Toast.ActionTrigger>{toast.action.label}</Toast.ActionTrigger>
36
+ )}
37
+ {toast.closable && <Toast.CloseTrigger />}
38
+ </Toast.Root>
39
+ )}
40
+ </ChakraToaster>
41
+ </Portal>
42
+ )
43
+ }
@@ -0,0 +1,46 @@
1
+ import { Tooltip as ChakraTooltip, Portal } from "@chakra-ui/react"
2
+ import * as React from "react"
3
+
4
+ export interface TooltipProps extends ChakraTooltip.RootProps {
5
+ showArrow?: boolean
6
+ portalled?: boolean
7
+ portalRef?: React.RefObject<HTMLElement>
8
+ content: React.ReactNode
9
+ contentProps?: ChakraTooltip.ContentProps
10
+ disabled?: boolean
11
+ }
12
+
13
+ export const Tooltip = React.forwardRef<HTMLDivElement, TooltipProps>(
14
+ function Tooltip(props, ref) {
15
+ const {
16
+ showArrow,
17
+ children,
18
+ disabled,
19
+ portalled = true,
20
+ content,
21
+ contentProps,
22
+ portalRef,
23
+ ...rest
24
+ } = props
25
+
26
+ if (disabled) return children
27
+
28
+ return (
29
+ <ChakraTooltip.Root {...rest}>
30
+ <ChakraTooltip.Trigger asChild>{children}</ChakraTooltip.Trigger>
31
+ <Portal disabled={!portalled} container={portalRef}>
32
+ <ChakraTooltip.Positioner>
33
+ <ChakraTooltip.Content ref={ref} {...contentProps}>
34
+ {showArrow && (
35
+ <ChakraTooltip.Arrow>
36
+ <ChakraTooltip.ArrowTip />
37
+ </ChakraTooltip.Arrow>
38
+ )}
39
+ {content}
40
+ </ChakraTooltip.Content>
41
+ </ChakraTooltip.Positioner>
42
+ </Portal>
43
+ </ChakraTooltip.Root>
44
+ )
45
+ },
46
+ )