@hivemindhq/core 0.4.0 → 0.5.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 (85) hide show
  1. package/README.md +16 -16
  2. package/dist/{chunk-2RGM3KJL.js → chunk-K2544PJ5.js} +42 -20
  3. package/dist/chunk-K2544PJ5.js.map +1 -0
  4. package/dist/{chunk-P5E2XNDI.js → chunk-K4XDMY2V.js} +3 -3
  5. package/dist/{chunk-P5E2XNDI.js.map → chunk-K4XDMY2V.js.map} +1 -1
  6. package/dist/{chunk-ERZSVDIB.js → chunk-RW4JXOAM.js} +11 -3
  7. package/dist/chunk-RW4JXOAM.js.map +1 -0
  8. package/dist/chunk-VU3OPG32.js +907 -0
  9. package/dist/chunk-VU3OPG32.js.map +1 -0
  10. package/dist/components/index.d.ts +28 -3
  11. package/dist/components/index.js +2 -2
  12. package/dist/components/ui/index.js +2 -2
  13. package/dist/index.d.ts +2 -2
  14. package/dist/index.js +6 -6
  15. package/dist/utils/index.d.ts +312 -6
  16. package/dist/utils/index.js +2 -2
  17. package/package.json +15 -11
  18. package/src/components/AtomIcon.tsx +21 -0
  19. package/src/components/CryptoAmount.tsx +447 -0
  20. package/src/components/ErrorBanner.tsx +35 -0
  21. package/src/components/IpfsImage.tsx +21 -0
  22. package/src/components/LoadingDots.tsx +55 -0
  23. package/src/components/TripleAreaChart.tsx +108 -0
  24. package/src/components/TriplePositionsTornadoMinGraph.tsx +71 -0
  25. package/src/components/UnknownImage.tsx +55 -0
  26. package/src/components/index.ts +24 -0
  27. package/src/components/ui/alert.tsx +59 -0
  28. package/src/components/ui/avatar.tsx +47 -0
  29. package/src/components/ui/badge.tsx +35 -0
  30. package/src/components/ui/breadcrumb.tsx +108 -0
  31. package/src/components/ui/button.tsx +56 -0
  32. package/src/components/ui/card.tsx +75 -0
  33. package/src/components/ui/carousel.tsx +239 -0
  34. package/src/components/ui/chart.tsx +350 -0
  35. package/src/components/ui/checkbox.tsx +28 -0
  36. package/src/components/ui/collapsible.tsx +10 -0
  37. package/src/components/ui/command.tsx +177 -0
  38. package/src/components/ui/dialog.tsx +119 -0
  39. package/src/components/ui/dropdown-menu.tsx +202 -0
  40. package/src/components/ui/form.tsx +175 -0
  41. package/src/components/ui/index.ts +183 -0
  42. package/src/components/ui/input.tsx +21 -0
  43. package/src/components/ui/label.tsx +25 -0
  44. package/src/components/ui/loader.tsx +20 -0
  45. package/src/components/ui/pagination.tsx +104 -0
  46. package/src/components/ui/popover.tsx +45 -0
  47. package/src/components/ui/progress.tsx +25 -0
  48. package/src/components/ui/radio-group.tsx +42 -0
  49. package/src/components/ui/scroll-area.tsx +45 -0
  50. package/src/components/ui/select.tsx +178 -0
  51. package/src/components/ui/separator.tsx +28 -0
  52. package/src/components/ui/sheet.tsx +139 -0
  53. package/src/components/ui/sidebar.tsx +723 -0
  54. package/src/components/ui/skeleton.tsx +15 -0
  55. package/src/components/ui/sonner.tsx +27 -0
  56. package/src/components/ui/spinner.tsx +67 -0
  57. package/src/components/ui/switch.tsx +26 -0
  58. package/src/components/ui/table.tsx +113 -0
  59. package/src/components/ui/tabs.tsx +63 -0
  60. package/src/components/ui/textarea.tsx +21 -0
  61. package/src/components/ui/toast.tsx +146 -0
  62. package/src/components/ui/toaster.tsx +33 -0
  63. package/src/components/ui/toggle-group.tsx +58 -0
  64. package/src/components/ui/toggle.tsx +44 -0
  65. package/src/components/ui/tooltip.tsx +61 -0
  66. package/src/hooks/index.ts +7 -0
  67. package/src/hooks/use-mobile.ts +20 -0
  68. package/src/hooks/use-toast.ts +190 -0
  69. package/src/index.ts +25 -0
  70. package/src/types/index.ts +17 -0
  71. package/src/utils/atom-label-detection.ts +689 -0
  72. package/src/utils/atom.ts +279 -0
  73. package/src/utils/cn.ts +18 -0
  74. package/src/utils/formatting.ts +624 -0
  75. package/src/utils/index.ts +11 -0
  76. package/src/utils/multivault-errors.ts +581 -0
  77. package/src/utils/search/formatting.tsx +95 -0
  78. package/src/utils/search/index.ts +28 -0
  79. package/src/utils/search/ranking.ts +203 -0
  80. package/src/utils/search/types.ts +114 -0
  81. package/tailwind.config.js +3 -3
  82. package/dist/chunk-2RGM3KJL.js.map +0 -1
  83. package/dist/chunk-ERZSVDIB.js.map +0 -1
  84. package/dist/chunk-H4RMZQ2Z.js +0 -213
  85. package/dist/chunk-H4RMZQ2Z.js.map +0 -1
package/README.md CHANGED
@@ -1,25 +1,25 @@
1
- # @revel8/core
1
+ # @hivemindhq/core
2
2
 
3
3
  Shared components, utilities, and types for Revel8 applications.
4
4
 
5
5
  ## Overview
6
6
 
7
7
  This package provides common functionality shared between:
8
- - **revel8-explorer** - Web application for exploring the Intuition knowledge graph
8
+ - **hivemind-explorer** - Web application for exploring the Intuition knowledge graph
9
9
  - **intuition-extension** - Browser extension for Intuition insights
10
10
 
11
11
  ## Installation
12
12
 
13
13
  ```bash
14
14
  # Using pnpm (recommended)
15
- pnpm add @revel8/core
15
+ pnpm add @hivemindhq/core
16
16
 
17
17
  # Using npm
18
- npm install @revel8/core
18
+ npm install @hivemindhq/core
19
19
 
20
20
  # For local development (link)
21
21
  cd revel8-core && pnpm link
22
- cd ../revel8-explorer && pnpm link @revel8/core
22
+ cd ../hivemind-explorer && pnpm link @hivemindhq/core
23
23
  ```
24
24
 
25
25
  ## Usage
@@ -27,7 +27,7 @@ cd ../revel8-explorer && pnpm link @revel8/core
27
27
  ### Utilities
28
28
 
29
29
  ```typescript
30
- import { cn, truncateId, ipfsToHttp, formatCompact } from '@revel8/core'
30
+ import { cn, truncateId, ipfsToHttp, formatCompact } from '@hivemindhq/core'
31
31
 
32
32
  // Merge Tailwind classes
33
33
  cn('px-4 py-2', isActive && 'bg-blue-500')
@@ -46,10 +46,10 @@ formatCompact(1500000) // '1.5M'
46
46
 
47
47
  ```typescript
48
48
  // UI primitives
49
- import { Button, Card, Tooltip } from '@revel8/core'
49
+ import { Button, Card, Tooltip } from '@hivemindhq/core'
50
50
 
51
51
  // Display components
52
- import { CryptoAmount, AtomIcon, IpfsImage } from '@revel8/core'
52
+ import { CryptoAmount, AtomIcon, IpfsImage } from '@hivemindhq/core'
53
53
  ```
54
54
 
55
55
  ### CryptoAmount Component
@@ -57,7 +57,7 @@ import { CryptoAmount, AtomIcon, IpfsImage } from '@revel8/core'
57
57
  A unified component for displaying cryptocurrency amounts with optional fiat conversion.
58
58
 
59
59
  ```tsx
60
- import { CryptoAmount, createCryptoAmountRateProps } from '@revel8/core'
60
+ import { CryptoAmount, createCryptoAmountRateProps } from '@hivemindhq/core'
61
61
 
62
62
  // Basic usage - crypto on top, fiat below
63
63
  <CryptoAmount
@@ -125,13 +125,13 @@ Extend the shared Tailwind config in your app:
125
125
 
126
126
  ```javascript
127
127
  // tailwind.config.js
128
- const sharedConfig = require('@revel8/core/tailwind.config')
128
+ const sharedConfig = require('@hivemindhq/core/tailwind.config')
129
129
 
130
130
  module.exports = {
131
131
  presets: [sharedConfig],
132
132
  content: [
133
133
  './src/**/*.{ts,tsx}',
134
- './node_modules/@revel8/core/dist/**/*.js',
134
+ './node_modules/@hivemindhq/core/dist/**/*.js',
135
135
  ],
136
136
  // Your app-specific extensions...
137
137
  }
@@ -182,10 +182,10 @@ The package provides multiple entry points:
182
182
 
183
183
  | Import Path | Contents |
184
184
  |-------------|----------|
185
- | `@revel8/core` | Everything (utils, components, types) |
186
- | `@revel8/core/utils` | Utility functions only |
187
- | `@revel8/core/components/ui` | UI primitives |
188
- | `@revel8/core/components/display` | Display components |
185
+ | `@hivemindhq/core` | Everything (utils, components, types) |
186
+ | `@hivemindhq/core/utils` | Utility functions only |
187
+ | `@hivemindhq/core/components/ui` | UI primitives |
188
+ | `@hivemindhq/core/components/display` | Display components |
189
189
 
190
190
  ## Peer Dependencies
191
191
 
@@ -211,7 +211,7 @@ When migrating a component from a consuming app:
211
211
  - [ ] Copy component to `src/components/`
212
212
  - [ ] Update imports to use relative paths (no `@/` or `~/` aliases)
213
213
  - [ ] Ensure it only depends on:
214
- - Other `@revel8/core` exports
214
+ - Other `@hivemindhq/core` exports
215
215
  - Peer dependencies (React, etc.)
216
216
  - Direct dependencies listed in package.json
217
217
  - [ ] Add export to the appropriate barrel file
@@ -1,4 +1,4 @@
1
- import { strengthenImageUrl, ipfsToHttp, formatCryptoAmount } from './chunk-ERZSVDIB.js';
1
+ import { strengthenImageUrl, ipfsToHttp, formatCryptoAmount } from './chunk-RW4JXOAM.js';
2
2
  import { Tooltip as Tooltip$1, TooltipTrigger, TooltipContent } from './chunk-E5TTKYNS.js';
3
3
  import { cn } from './chunk-VIRNUAYY.js';
4
4
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
@@ -16,9 +16,9 @@ var AtomIcon = ({ ...props }) => {
16
16
  viewBox: "0 0 24 24",
17
17
  fill: "none",
18
18
  stroke: "rgba(255,255,255,0.6)",
19
- "stroke-width": "1.5",
20
- "stroke-linecap": "round",
21
- "stroke-linejoin": "round",
19
+ strokeWidth: "1.5",
20
+ strokeLinecap: "round",
21
+ strokeLinejoin: "round",
22
22
  className: "lucide lucide-atom",
23
23
  ...props,
24
24
  children: [
@@ -68,14 +68,14 @@ function LoadingDots({
68
68
  {
69
69
  className: "w-2 h-2 bg-gray-600 rounded-full",
70
70
  style: {
71
- animation: "revel8-loading-dots-wave 1.2s infinite ease-in-out",
71
+ animation: "hivemind-loading-dots-wave 1.2s infinite ease-in-out",
72
72
  animationDelay: `${i * 0.2}s`
73
73
  }
74
74
  },
75
75
  i
76
76
  )),
77
77
  /* @__PURE__ */ jsx("style", { children: `
78
- @keyframes revel8-loading-dots-wave {
78
+ @keyframes hivemind-loading-dots-wave {
79
79
  0%, 100% {
80
80
  transform: translateY(0);
81
81
  }
@@ -211,6 +211,7 @@ function CryptoAmount({
211
211
  maxDecimals = 6,
212
212
  showSymbol = true,
213
213
  showFiat = true,
214
+ secondaryDisplay = "inline",
214
215
  className,
215
216
  cryptoClassName,
216
217
  fiatClassName
@@ -219,11 +220,21 @@ function CryptoAmount({
219
220
  const formatted = React2.useMemo(() => {
220
221
  if (isTokenUnits) {
221
222
  const numericValue = typeof value === "string" ? parseFloat(value) : Number(value);
222
- const displayValue = numericValue.toString();
223
+ const fullValue = numericValue.toString();
224
+ let displayValue = fullValue;
225
+ if (maxDecimals !== void 0) {
226
+ const factor = Math.pow(10, maxDecimals);
227
+ const truncated = Math.floor(numericValue * factor) / factor;
228
+ displayValue = truncated.toLocaleString(effectiveLocale, {
229
+ minimumFractionDigits: 0,
230
+ maximumFractionDigits: maxDecimals
231
+ });
232
+ }
233
+ const isTruncated = displayValue !== fullValue;
223
234
  return {
224
235
  display: displayValue,
225
- fullValue: displayValue,
226
- isTruncated: false,
236
+ fullValue,
237
+ isTruncated,
227
238
  numericValue
228
239
  };
229
240
  }
@@ -236,7 +247,7 @@ function CryptoAmount({
236
247
  });
237
248
  }, [value, decimals, isTokenUnits, maxSignificantDigits, maxDecimals, variant, effectiveLocale]);
238
249
  const fiatFormatted = React2.useMemo(() => {
239
- if (!showFiat || exchangeRate == null || variant === "crypto-only") {
250
+ if (!showFiat || exchangeRate == null || variant === "crypto-only" || secondaryDisplay === "hidden") {
240
251
  return null;
241
252
  }
242
253
  const fiatValue = formatted.numericValue * exchangeRate;
@@ -248,9 +259,10 @@ function CryptoAmount({
248
259
  maximumFractionDigits: 2
249
260
  }).format(fiatValue);
250
261
  } catch {
251
- return `$${fiatValue.toFixed(2)}`;
262
+ return null;
252
263
  }
253
- }, [formatted.numericValue, exchangeRate, currencyCode, effectiveLocale, showFiat, variant]);
264
+ }, [formatted.numericValue, exchangeRate, currencyCode, effectiveLocale, showFiat, variant, secondaryDisplay]);
265
+ const showFiatInline = fiatFormatted && secondaryDisplay === "inline";
254
266
  const sizeStyles = {
255
267
  sm: {
256
268
  crypto: "text-sm",
@@ -268,21 +280,31 @@ function CryptoAmount({
268
280
  const styles = sizeStyles[size];
269
281
  const cryptoDisplay = showSymbol ? `${formatted.display} ${symbol}` : formatted.display;
270
282
  const fullCryptoDisplay = showSymbol ? `${formatted.fullValue} ${symbol}` : formatted.fullValue;
271
- const needsTooltip = formatted.isTruncated;
283
+ const showSecondaryInTooltip = secondaryDisplay === "tooltip" && fiatFormatted;
284
+ const needsTooltip = formatted.isTruncated || showSecondaryInTooltip;
272
285
  const cryptoElement = /* @__PURE__ */ jsx(
273
286
  "span",
274
287
  {
275
288
  className: cn(
276
289
  styles.crypto,
277
290
  "font-medium",
291
+ // Add cursor hint when tooltip contains extra info
292
+ // showSecondaryInTooltip && 'cursor-help',
278
293
  cryptoClassName
279
294
  ),
280
295
  children: cryptoDisplay
281
296
  }
282
297
  );
283
- const cryptoWithTooltip = needsTooltip ? /* @__PURE__ */ jsxs(Tooltip$1, { delayDuration: 1e3, children: [
298
+ const tooltipContent = /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-0.5", children: [
299
+ /* @__PURE__ */ jsx("span", { className: "font-mono text-xs", children: fullCryptoDisplay }),
300
+ showSecondaryInTooltip && /* @__PURE__ */ jsxs("span", { className: "text-xs text-primary-foreground/70", children: [
301
+ "\u2248 ",
302
+ fiatFormatted
303
+ ] })
304
+ ] });
305
+ const cryptoWithTooltip = needsTooltip ? /* @__PURE__ */ jsxs(Tooltip$1, { delayDuration: showSecondaryInTooltip ? 300 : 1e3, children: [
284
306
  /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: cryptoElement }),
285
- /* @__PURE__ */ jsx(TooltipContent, { children: /* @__PURE__ */ jsx("span", { className: "font-mono text-xs", children: fullCryptoDisplay }) })
307
+ /* @__PURE__ */ jsx(TooltipContent, { children: tooltipContent })
286
308
  ] }) : cryptoElement;
287
309
  if (variant === "crypto-only") {
288
310
  return /* @__PURE__ */ jsx("div", { className: cn("flex items-center", className), children: cryptoWithTooltip });
@@ -304,7 +326,7 @@ function CryptoAmount({
304
326
  if (variant === "inline") {
305
327
  return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-1", className), children: [
306
328
  cryptoWithTooltip,
307
- fiatFormatted && /* @__PURE__ */ jsxs("span", { className: cn(
329
+ showFiatInline && /* @__PURE__ */ jsxs("span", { className: cn(
308
330
  styles.fiat,
309
331
  "text-muted-foreground",
310
332
  fiatClassName
@@ -318,7 +340,7 @@ function CryptoAmount({
318
340
  if (variant === "compact") {
319
341
  return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-1", className), children: [
320
342
  cryptoWithTooltip,
321
- fiatFormatted && /* @__PURE__ */ jsxs("span", { className: cn(
343
+ showFiatInline && /* @__PURE__ */ jsxs("span", { className: cn(
322
344
  styles.fiat,
323
345
  "text-muted-foreground",
324
346
  fiatClassName
@@ -331,7 +353,7 @@ function CryptoAmount({
331
353
  }
332
354
  return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col", className), children: [
333
355
  cryptoWithTooltip,
334
- fiatFormatted && /* @__PURE__ */ jsx("span", { className: cn(
356
+ showFiatInline && /* @__PURE__ */ jsx("span", { className: cn(
335
357
  styles.fiat,
336
358
  "text-muted-foreground",
337
359
  fiatClassName
@@ -347,5 +369,5 @@ function createCryptoAmountRateProps(exchangeRate, currencyCode = "USD", locale)
347
369
  }
348
370
 
349
371
  export { AtomIcon, CryptoAmount, ErrorBanner, IpfsImage, LoadingDots, TripleAreaChart, TriplePositionsTornadoMinGraph, UnknownImage, createCryptoAmountRateProps };
350
- //# sourceMappingURL=chunk-2RGM3KJL.js.map
351
- //# sourceMappingURL=chunk-2RGM3KJL.js.map
372
+ //# sourceMappingURL=chunk-K2544PJ5.js.map
373
+ //# sourceMappingURL=chunk-K2544PJ5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/AtomIcon.tsx","../src/components/UnknownImage.tsx","../src/components/LoadingDots.tsx","../src/components/IpfsImage.tsx","../src/components/TriplePositionsTornadoMinGraph.tsx","../src/components/TripleAreaChart.tsx","../src/components/ErrorBanner.tsx","../src/components/CryptoAmount.tsx"],"names":["finalSrc","jsx","jsxs","ResponsiveContainer","Tooltip","XAxis","YAxis"],"mappings":"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","file":"chunk-K2544PJ5.js","sourcesContent":["export const AtomIcon = ({ ...props }: React.SVGProps<SVGSVGElement>) => {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"rgba(255,255,255,0.6)\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"lucide lucide-atom\"\n {...props}\n >\n <circle cx=\"12\" cy=\"12\" r=\"1\" />\n <path d=\"M20.2 20.2c2.04-2.03.02-7.36-4.5-11.9-4.54-4.52-9.87-6.54-11.9-4.5-2.04 2.03-.02 7.36 4.5 11.9 4.54 4.52 9.87 6.54 11.9 4.5Z\" />\n <path d=\"M15.7 15.7c4.52-4.54 6.54-9.87 4.5-11.9-2.03-2.04-7.36-.02-11.9 4.5-4.52 4.54-6.54 9.87-4.5 11.9 2.03 2.04 7.36.02 11.9-4.5Z\" />\n </svg>\n )\n}\n","import React, { useState } from 'react'\nimport { strengthenImageUrl } from '../utils/formatting'\n\nexport interface UnknownImageProps extends React.ImgHTMLAttributes<HTMLImageElement> {\n /** The image source URL - can be IPFS, HTTP, or raw hash */\n src: string\n /** Whether to wrap the image in an anchor link to the source */\n asLink?: boolean\n}\n\n/**\n * An image component that handles various URL formats including IPFS.\n * Automatically converts IPFS URIs and hashes to gateway URLs.\n * \n * @example\n * <UnknownImage src=\"ipfs://QmHash123\" alt=\"My image\" className=\"w-10 h-10\" />\n */\nexport const UnknownImage = ({\n asLink = false,\n src,\n ...props\n}: UnknownImageProps) => {\n if (!src) return null\n const [numberOfErrors, setNumberOfErrors] = useState(0)\n\n const onImageError = (\n e: React.SyntheticEvent<HTMLImageElement>,\n finalSrc: string\n ) => {\n setNumberOfErrors(numberOfErrors + 1)\n // Only log in development\n if (typeof window !== 'undefined' && (window as any).__DEV__) {\n console.log('UnknownImage error:', e.currentTarget.src, finalSrc)\n }\n }\n\n const finalSrc = strengthenImageUrl(src)\n\n const img = (\n <img src={finalSrc} onError={(e) => onImageError(e, finalSrc)} {...props} />\n )\n\n if (asLink) {\n return (\n <a href={finalSrc} target=\"_blank\" rel=\"noopener noreferrer\">\n {img}\n </a>\n )\n }\n\n return img\n}\n\nexport default UnknownImage\n\n","export interface LoadingDotsProps {\n /** Duration of opacity transition in ms */\n transitionDuration?: number\n /** Whether the dots are visible */\n isVisible?: boolean\n /** Additional CSS classes */\n className?: string\n}\n\n/**\n * Animated loading dots indicator.\n * Shows three dots with a wave animation.\n * \n * @example\n * <LoadingDots isVisible={isLoading} />\n */\nexport function LoadingDots({\n transitionDuration = 300,\n isVisible = true,\n className = '',\n}: LoadingDotsProps) {\n return (\n <div\n className={`flex gap-1 justify-center items-center ${className}`}\n style={{\n opacity: isVisible ? 1 : 0,\n transition: `opacity ${transitionDuration}ms ease-in-out`,\n }}\n >\n {[0, 1, 2].map((i) => (\n <span\n key={i}\n className=\"w-2 h-2 bg-gray-600 rounded-full\"\n style={{\n animation: 'hivemind-loading-dots-wave 1.2s infinite ease-in-out',\n animationDelay: `${i * 0.2}s`,\n }}\n />\n ))}\n <style>{`\n @keyframes hivemind-loading-dots-wave {\n 0%, 100% {\n transform: translateY(0);\n }\n 50% {\n transform: translateY(-6px);\n }\n }\n `}</style>\n </div>\n )\n}\n\nexport default LoadingDots\n\n","import React from 'react'\nimport { ipfsToHttp } from '../utils/formatting'\n\nexport interface IpfsImageProps extends React.ImgHTMLAttributes<HTMLImageElement> {\n /** The image source - can be an ipfs:// URI or regular URL */\n src: string\n}\n\n/**\n * An image component that automatically converts IPFS URIs to gateway URLs.\n * \n * @example\n * <IpfsImage src=\"ipfs://QmHash123\" alt=\"IPFS image\" />\n */\nexport const IpfsImage = ({ src, ...props }: IpfsImageProps) => {\n const finalSrc = ipfsToHttp(src) || src\n return <img src={finalSrc} {...props} />\n}\n\nexport default IpfsImage\n\n","import { Bar, BarChart, ResponsiveContainer, XAxis, YAxis } from 'recharts'\n\nexport interface TornadoGraphDataPoint {\n /** The range identifier/name */\n name: number\n /** Vault balance for this range */\n vaultBalance?: number\n /** Counter vault balance for this range */\n counterVaultBalance?: number\n /** Aggregate vault balance (positive side) */\n aggregateVaultBalance: number\n /** Aggregate counter vault balance (negative side) */\n aggregateCounterVaultBalance: number\n}\n\nexport interface TriplePositionsTornadoMinGraphProps {\n /** Pre-formatted data for the tornado chart */\n data: TornadoGraphDataPoint[]\n /** Color for the \"FOR\" (vault) bars */\n forColor?: string\n /** Color for the \"AGAINST\" (counter vault) bars */\n againstColor?: string\n /** Additional className for the container */\n className?: string\n}\n\n/**\n * A minimal tornado/butterfly chart for displaying triple position distributions.\n * Shows FOR positions (green) on the right and AGAINST positions (red) on the left.\n * \n * @example\n * <TriplePositionsTornadoMinGraph \n * data={formattedRanges} \n * forColor=\"#31ad31\" \n * againstColor=\"#bc4535\" \n * />\n */\nexport const TriplePositionsTornadoMinGraph = ({\n data,\n forColor = '#31ad31',\n againstColor = '#bc4535',\n className,\n}: TriplePositionsTornadoMinGraphProps) => {\n if (!data || data.length === 0) {\n return null\n }\n\n return (\n <ResponsiveContainer width=\"100%\" height=\"100%\" className={className}>\n <BarChart\n data={data}\n stackOffset=\"sign\"\n layout=\"vertical\"\n barGap={0}\n barCategoryGap={0}\n >\n <XAxis type=\"number\" hide={true} />\n <YAxis dataKey=\"name\" type=\"number\" reversed hide={true} />\n <Bar dataKey=\"aggregateVaultBalance\" fill={forColor} stackId=\"stack\" />\n <Bar\n dataKey=\"aggregateCounterVaultBalance\"\n fill={againstColor}\n stackId=\"stack\"\n />\n </BarChart>\n </ResponsiveContainer>\n )\n}\n\nexport default TriplePositionsTornadoMinGraph\n\n","import {\n Area,\n AreaChart,\n CartesianGrid,\n ResponsiveContainer,\n Tooltip,\n XAxis,\n YAxis,\n} from 'recharts'\n\nexport interface TripleAreaChartDataPoint {\n /** The x-axis value (typically position value) */\n xValue: number\n /** Vault (FOR) position value */\n vault?: number\n /** Counter vault (AGAINST) position value */\n counterVault?: number\n}\n\nexport interface TripleAreaChartProps {\n /** Pre-formatted chart data points */\n chartData: TripleAreaChartDataPoint[]\n /** Display variant - 'min' hides axes/grid, 'max' shows full chart */\n variant?: 'min' | 'max'\n /** Color for vault (FOR) area */\n vaultColor?: string\n /** Color for counter vault (AGAINST) area */\n counterVaultColor?: string\n}\n\n/**\n * An area chart for visualizing triple position distributions.\n * Shows vault (FOR) positions on positive side and counter vault (AGAINST) on negative.\n * \n * @example\n * <TripleAreaChart \n * chartData={formattedPositions} \n * variant=\"min\" \n * />\n */\nexport const TripleAreaChart = ({\n chartData,\n variant = 'min',\n vaultColor = 'green',\n counterVaultColor = 'red',\n}: TripleAreaChartProps) => {\n // Clone data to avoid mutating props\n const data = [...chartData]\n \n const maxValue = Math.max(...data.map((d) => d.xValue))\n const minValue = Math.min(...data.map((d) => d.xValue))\n \n // Add padding points for better visualization\n if (maxValue > 0) {\n data.push({\n xValue: maxValue * 1.2,\n vault: maxValue,\n })\n }\n if (minValue < 0) {\n data.push({\n xValue: minValue * 1.2,\n counterVault: minValue * -1,\n })\n }\n \n data.sort((a, b) => a.xValue - b.xValue)\n const maxAbsValue = Math.max(...data.map((d) => Math.abs(d.xValue)))\n const domain = [maxAbsValue * -1, maxAbsValue]\n\n return (\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <AreaChart data={data} layout=\"vertical\">\n {variant !== 'min' && (\n <>\n <CartesianGrid strokeDasharray=\"3 3\" />\n <Tooltip />\n </>\n )}\n <XAxis type=\"number\" hide={variant === 'min'} />\n <YAxis\n dataKey=\"xValue\"\n type=\"number\"\n reversed\n domain={domain}\n hide={variant === 'min'}\n />\n <Area\n type=\"stepBefore\"\n dataKey=\"vault\"\n stroke={vaultColor}\n fill={vaultColor}\n fillOpacity={0.5}\n />\n <Area\n type=\"stepAfter\"\n dataKey=\"counterVault\"\n stroke={counterVaultColor}\n fill={counterVaultColor}\n fillOpacity={0.5}\n />\n </AreaChart>\n </ResponsiveContainer>\n )\n}\n\nexport default TripleAreaChart\n\n","import { cn } from '../utils/cn'\n\nexport interface ErrorBannerProps {\n /** The error message to display */\n error: string\n /** Optional HTTP status code */\n code?: number\n /** Additional CSS classes */\n className?: string\n}\n\n/**\n * A simple error banner component for displaying error messages.\n * Centered layout with large heading and subtitle.\n * \n * @example\n * <ErrorBanner error=\"Page not found\" code={404} />\n */\nexport const ErrorBanner = ({ \n error, \n code, \n className \n}: ErrorBannerProps) => {\n return (\n <div className={cn(\"flex flex-col gap-2 mt-12\", className)}>\n <h2 className=\"text-center text-2xl font-bold mb-8\">\n {code ? `${code} Error` : 'Error'}\n </h2>\n <p className=\"text-center text-lg text-gray-500\">{error}</p>\n </div>\n )\n}\n\nexport default ErrorBanner\n\n","import * as React from 'react'\nimport { cn } from '../utils/cn'\nimport { Tooltip, TooltipTrigger, TooltipContent } from './ui/tooltip'\nimport { formatCryptoAmount } from '../utils/formatting'\n\n/**\n * Display variant for the CryptoAmount component.\n * \n * - `default`: Crypto on top, fiat below (stacked)\n * - `inline`: Single line with fiat in parentheses\n * - `crypto-only`: Just the native token amount\n * - `fiat-only`: Just the fiat equivalent (useful for previews)\n * - `compact`: Abbreviated format for large amounts (1.5M TRUST)\n */\nexport type CryptoAmountVariant = 'default' | 'inline' | 'crypto-only' | 'fiat-only' | 'compact'\n\n/**\n * Size variant for the CryptoAmount component.\n */\nexport type CryptoAmountSize = 'sm' | 'md' | 'lg'\n\n/**\n * Controls where the secondary currency (fiat for crypto display, crypto for fiat display) appears.\n * \n * - `inline`: Show alongside primary currency (default behavior)\n * - `tooltip`: Show only in tooltip on hover (saves space)\n * - `hidden`: Don't show secondary currency at all\n */\nexport type SecondaryDisplayMode = 'inline' | 'tooltip' | 'hidden'\n\nexport interface CryptoAmountProps {\n /** \n * The crypto amount. By default, expects wei/smallest unit (string or bigint).\n * If `isTokenUnits` is true, expects the value already in token units (e.g., 1.5 for 1.5 TRUST).\n */\n value: string | bigint | number\n \n /** Number of decimals for the token (default: 18). Ignored when isTokenUnits is true. */\n decimals?: number\n \n /**\n * When true, the value is already in token units (e.g., 1.5 for 1.5 TRUST).\n * When false (default), the value is in wei/smallest units and will be converted.\n */\n isTokenUnits?: boolean\n \n /** Token symbol to display (e.g., 'TRUST', 'ETH') */\n symbol: string\n \n /**\n * Exchange rate for fiat conversion (1 token = X fiat).\n * If undefined/null, fiat display is hidden.\n */\n exchangeRate?: number | null\n \n /**\n * Fiat currency code for formatting (default: 'USD').\n * Used with Intl.NumberFormat for proper currency display.\n */\n currencyCode?: string\n \n /**\n * Locale for number/currency formatting (default: browser locale or 'en-US')\n */\n locale?: string\n \n /** Display variant (default: 'default') */\n variant?: CryptoAmountVariant\n \n /** Size variant (default: 'md') */\n size?: CryptoAmountSize\n \n /**\n * Maximum significant digits before truncation (default: 10).\n * Amounts exceeding this will show \"...\" with full value in tooltip.\n */\n maxSignificantDigits?: number\n \n /**\n * Maximum decimal places to display (default: 6).\n * Applied after conversion but before significant digit truncation.\n */\n maxDecimals?: number\n \n /** Whether to show the token symbol (default: true) */\n showSymbol?: boolean\n \n /** Whether to show fiat value when exchange rate is available (default: true) */\n showFiat?: boolean\n \n /**\n * Where to display the secondary currency (fiat when showing crypto, crypto when showing fiat).\n * - `inline`: Show alongside primary (default behavior)\n * - `tooltip`: Show in tooltip on hover (saves space in dense UIs)\n * - `hidden`: Don't show at all\n * @default 'inline'\n */\n secondaryDisplay?: SecondaryDisplayMode\n \n /** Additional CSS classes for the container */\n className?: string\n \n /** Additional CSS classes for the crypto amount text */\n cryptoClassName?: string\n \n /** Additional CSS classes for the fiat amount text */\n fiatClassName?: string\n}\n\n/**\n * A unified component for displaying cryptocurrency amounts with optional fiat conversion.\n * \n * Features:\n * - Crypto-first display (native token amount is primary)\n * - Optional fiat conversion shown as secondary (inline or in tooltip)\n * - Truncation with tooltip for large amounts\n * - Multiple display variants (stacked, inline, compact)\n * - Proper number formatting based on locale\n * \n * @example\n * ```tsx\n * // Basic usage - stacked display\n * <CryptoAmount \n * value=\"1500000000000000000\" \n * symbol=\"TRUST\" \n * exchangeRate={0.42} \n * />\n * // Renders:\n * // 1.5 TRUST\n * // $0.63\n * \n * // Inline variant\n * <CryptoAmount \n * value=\"1500000000000000000\" \n * symbol=\"TRUST\" \n * exchangeRate={0.42}\n * variant=\"inline\"\n * />\n * // Renders: 1.5 TRUST (~$0.63)\n * \n * // Space-saving: show crypto only, fiat in tooltip\n * <CryptoAmount \n * value=\"1500000000000000000\" \n * symbol=\"TRUST\"\n * exchangeRate={0.42}\n * secondaryDisplay=\"tooltip\"\n * />\n * // Renders: 1.5 TRUST (hover shows: 1.5 TRUST + ≈ $0.63)\n * \n * // Compact variant for large amounts\n * <CryptoAmount \n * value=\"1500000000000000000000000\" \n * symbol=\"TRUST\"\n * variant=\"compact\"\n * />\n * // Renders: 1.5M TRUST\n * ```\n */\nexport function CryptoAmount({\n value,\n decimals = 18,\n isTokenUnits = false,\n symbol,\n exchangeRate,\n currencyCode = 'USD',\n locale,\n variant = 'default',\n size = 'md',\n maxSignificantDigits = 10,\n maxDecimals = 6,\n showSymbol = true,\n showFiat = true,\n secondaryDisplay = 'inline',\n className,\n cryptoClassName,\n fiatClassName,\n}: CryptoAmountProps) {\n // Determine locale\n const effectiveLocale = locale || (typeof navigator !== 'undefined' ? navigator.language : 'en-US')\n \n // Format the crypto amount\n const formatted = React.useMemo(() => {\n // If value is already in token units, create a simple formatted result\n if (isTokenUnits) {\n const numericValue = typeof value === 'string' ? parseFloat(value) : Number(value)\n const fullValue = numericValue.toString()\n \n // Apply maxDecimals truncation for display\n let displayValue = fullValue\n if (maxDecimals !== undefined) {\n // Round to maxDecimals places\n const factor = Math.pow(10, maxDecimals)\n const truncated = Math.floor(numericValue * factor) / factor\n displayValue = truncated.toLocaleString(effectiveLocale, {\n minimumFractionDigits: 0,\n maximumFractionDigits: maxDecimals,\n })\n }\n \n const isTruncated = displayValue !== fullValue\n return {\n display: displayValue,\n fullValue,\n isTruncated,\n numericValue,\n }\n }\n \n // Otherwise, convert from wei\n // Ensure value is string or bigint for formatCryptoAmount\n const weiValue = typeof value === 'number' ? value.toString() : value\n return formatCryptoAmount(weiValue, decimals, {\n maxSignificantDigits,\n maxDecimals,\n compact: variant === 'compact',\n locale: effectiveLocale,\n })\n }, [value, decimals, isTokenUnits, maxSignificantDigits, maxDecimals, variant, effectiveLocale])\n \n // Calculate fiat value if exchange rate is available\n // Note: We calculate even when secondaryDisplay='tooltip' because we need it for the tooltip\n const fiatFormatted = React.useMemo(() => {\n if (!showFiat || exchangeRate == null || variant === 'crypto-only' || secondaryDisplay === 'hidden') {\n return null\n }\n \n const fiatValue = formatted.numericValue * exchangeRate\n \n try {\n return new Intl.NumberFormat(effectiveLocale, {\n style: 'currency',\n currency: currencyCode.toUpperCase(),\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n }).format(fiatValue)\n } catch {\n // Fallback if currency code is invalid\n return null\n }\n }, [formatted.numericValue, exchangeRate, currencyCode, effectiveLocale, showFiat, variant, secondaryDisplay])\n \n // Determine if we should show fiat inline (vs in tooltip)\n const showFiatInline = fiatFormatted && secondaryDisplay === 'inline'\n \n // Size-based styling\n const sizeStyles = {\n sm: {\n crypto: 'text-sm',\n fiat: 'text-xs',\n },\n md: {\n crypto: 'text-base',\n fiat: 'text-sm',\n },\n lg: {\n crypto: 'text-lg font-semibold',\n fiat: 'text-base',\n },\n }\n \n const styles = sizeStyles[size]\n \n // Build the crypto display string\n const cryptoDisplay = showSymbol \n ? `${formatted.display} ${symbol}`\n : formatted.display\n \n // Full value for tooltip (when truncated)\n const fullCryptoDisplay = showSymbol\n ? `${formatted.fullValue} ${symbol}`\n : formatted.fullValue\n \n // Determine if we need a tooltip\n // Show tooltip if truncated OR if secondary currency should be in tooltip\n const showSecondaryInTooltip = secondaryDisplay === 'tooltip' && fiatFormatted\n const needsTooltip = formatted.isTruncated || showSecondaryInTooltip\n \n // Render the crypto amount (with or without tooltip)\n const cryptoElement = (\n <span \n className={cn(\n styles.crypto,\n 'font-medium',\n // Add cursor hint when tooltip contains extra info\n // showSecondaryInTooltip && 'cursor-help',\n cryptoClassName\n )}\n >\n {cryptoDisplay}\n </span>\n )\n \n // Build tooltip content - show full crypto always, add fiat if in tooltip mode\n // Note: Tooltip uses bg-primary, so we use text-primary-foreground with opacity\n // rather than text-muted-foreground which is designed for page backgrounds\n const tooltipContent = (\n <div className=\"flex flex-col gap-0.5\">\n <span className=\"font-mono text-xs\">{fullCryptoDisplay}</span>\n {showSecondaryInTooltip && (\n <span className=\"text-xs text-primary-foreground/70\">≈ {fiatFormatted}</span>\n )}\n </div>\n )\n \n const cryptoWithTooltip = needsTooltip ? (\n <Tooltip delayDuration={showSecondaryInTooltip ? 300 : 1000}>\n <TooltipTrigger asChild>\n {cryptoElement}\n </TooltipTrigger>\n <TooltipContent>\n {tooltipContent}\n </TooltipContent>\n </Tooltip>\n ) : cryptoElement\n \n // Render based on variant\n if (variant === 'crypto-only') {\n return (\n <div className={cn('flex items-center', className)}>\n {cryptoWithTooltip}\n </div>\n )\n }\n \n if (variant === 'fiat-only') {\n // Only show fiat, return null if no exchange rate available\n if (!fiatFormatted) {\n return null\n }\n return (\n <span className={cn(\n styles.fiat,\n 'text-muted-foreground',\n fiatClassName,\n className\n )}>\n ≈ {fiatFormatted}\n </span>\n )\n }\n \n if (variant === 'inline') {\n return (\n <div className={cn('flex items-center gap-1', className)}>\n {cryptoWithTooltip}\n {showFiatInline && (\n <span className={cn(\n styles.fiat,\n 'text-muted-foreground',\n fiatClassName\n )}>\n (~{fiatFormatted})\n </span>\n )}\n </div>\n )\n }\n \n if (variant === 'compact') {\n return (\n <div className={cn('flex items-center gap-1', className)}>\n {cryptoWithTooltip}\n {showFiatInline && (\n <span className={cn(\n styles.fiat,\n 'text-muted-foreground',\n fiatClassName\n )}>\n ({fiatFormatted})\n </span>\n )}\n </div>\n )\n }\n \n // Default: stacked layout\n return (\n <div className={cn('flex flex-col', className)}>\n {cryptoWithTooltip}\n {showFiatInline && (\n <span className={cn(\n styles.fiat,\n 'text-muted-foreground',\n fiatClassName\n )}>\n {fiatFormatted}\n </span>\n )}\n </div>\n )\n}\n\nexport default CryptoAmount\n\n// ============================================================================\n// Helper utilities for creating CryptoAmount props\n// ============================================================================\n\n/**\n * Props subset for creating a CryptoAmount from an exchange rate context.\n * Use this type when building a hook wrapper in your app.\n */\nexport type CryptoAmountRateProps = Pick<\n CryptoAmountProps,\n 'exchangeRate' | 'currencyCode' | 'locale'\n>\n\n/**\n * Creates CryptoAmountRateProps from an exchange rate and currency settings.\n * This is a helper for building hook wrappers in consuming applications.\n * \n * @param exchangeRate - The current exchange rate (1 token = X fiat), or null/undefined\n * @param currencyCode - The fiat currency code (e.g., 'USD', 'EUR')\n * @param locale - Optional locale for formatting\n * @returns Props object to spread onto CryptoAmount\n * \n * @example\n * ```tsx\n * // In your app's hook wrapper:\n * export function useCryptoAmountProps() {\n * const { data } = useExchangeRates()\n * const { selectedCurrency } = useCurrency()\n * \n * return createCryptoAmountRateProps(\n * data?.rate,\n * selectedCurrency,\n * navigator.language\n * )\n * }\n * \n * // Then in components:\n * const rateProps = useCryptoAmountProps()\n * <CryptoAmount value=\"1000000000000000000\" symbol=\"TRUST\" {...rateProps} />\n * ```\n */\nexport function createCryptoAmountRateProps(\n exchangeRate: number | null | undefined,\n currencyCode: string = 'USD',\n locale?: string\n): CryptoAmountRateProps {\n return {\n exchangeRate: exchangeRate ?? undefined,\n currencyCode,\n locale,\n }\n}\n\n"]}
@@ -1,6 +1,6 @@
1
1
  import { TooltipProvider, Tooltip, TooltipTrigger, TooltipContent } from './chunk-E5TTKYNS.js';
2
- import { cn } from './chunk-VIRNUAYY.js';
3
2
  import { useIsMobile, useToast } from './chunk-T2XWV636.js';
3
+ import { cn } from './chunk-VIRNUAYY.js';
4
4
  import * as React5 from 'react';
5
5
  import { cva } from 'class-variance-authority';
6
6
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
@@ -2754,5 +2754,5 @@ var ToggleGroupItem = React5.forwardRef(({ className, children, variant, size, .
2754
2754
  ToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName;
2755
2755
 
2756
2756
  export { Alert, AlertDescription, AlertTitle, Avatar, AvatarFallback, AvatarImage, Badge, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious, ChartContainer, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent, Checkbox, Collapsible, CollapsibleContent2 as CollapsibleContent, CollapsibleTrigger2 as CollapsibleTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, Input, Label2 as Label, Loader, Pagination, Popover, PopoverContent, PopoverTrigger, Progress, RadioGroup2 as RadioGroup, RadioGroupItem, ScrollArea, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator3 as Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, Skeleton, Spinner, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, Toast, ToastAction, ToastClose, ToastDescription, ToastProvider, ToastTitle, ToastViewport, Toaster, Toaster2, Toggle, ToggleGroup, ToggleGroupItem, badgeVariants, buttonVariants, toggleVariants, useFormField, useSidebar };
2757
- //# sourceMappingURL=chunk-P5E2XNDI.js.map
2758
- //# sourceMappingURL=chunk-P5E2XNDI.js.map
2757
+ //# sourceMappingURL=chunk-K4XDMY2V.js.map
2758
+ //# sourceMappingURL=chunk-K4XDMY2V.js.map