@silentswap/ui-kit 0.0.41

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 (39) hide show
  1. package/dist/components/AssetTile.d.ts +10 -0
  2. package/dist/components/AssetTile.js +18 -0
  3. package/dist/components/Button.d.ts +15 -0
  4. package/dist/components/Button.js +26 -0
  5. package/dist/components/Card.d.ts +14 -0
  6. package/dist/components/Card.js +19 -0
  7. package/dist/components/Input.d.ts +19 -0
  8. package/dist/components/Input.js +23 -0
  9. package/dist/components/PopularTokensArea.d.ts +8 -0
  10. package/dist/components/PopularTokensArea.js +34 -0
  11. package/dist/components/ProgressBar.d.ts +17 -0
  12. package/dist/components/ProgressBar.js +30 -0
  13. package/dist/components/Select.d.ts +12 -0
  14. package/dist/components/Select.js +7 -0
  15. package/dist/components/Warning.d.ts +15 -0
  16. package/dist/components/Warning.js +23 -0
  17. package/dist/constants.d.ts +2 -0
  18. package/dist/constants.js +4 -0
  19. package/dist/data.d.ts +7 -0
  20. package/dist/data.js +14 -0
  21. package/dist/index.d.ts +17 -0
  22. package/dist/index.js +13 -0
  23. package/dist/styles.css +399 -0
  24. package/dist/types.d.ts +15 -0
  25. package/dist/types.js +1 -0
  26. package/package.json +52 -0
  27. package/src/components/AssetTile.tsx +69 -0
  28. package/src/components/Button.tsx +51 -0
  29. package/src/components/Card.tsx +49 -0
  30. package/src/components/Input.tsx +72 -0
  31. package/src/components/PopularTokensArea.tsx +78 -0
  32. package/src/components/ProgressBar.tsx +67 -0
  33. package/src/components/Select.tsx +48 -0
  34. package/src/components/Warning.tsx +54 -0
  35. package/src/constants.ts +5 -0
  36. package/src/data.ts +19 -0
  37. package/src/index.ts +26 -0
  38. package/src/styles.css +399 -0
  39. package/src/types.ts +20 -0
@@ -0,0 +1,72 @@
1
+ import React, { forwardRef } from 'react';
2
+ import type { InputHTMLAttributes } from 'react';
3
+
4
+ export interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
5
+ /** Visual variant of the input */
6
+ variant?: 'default' | 'digital' | 'amount';
7
+ /** Whether the input has an error */
8
+ error?: boolean;
9
+ /** Whether the input is loading */
10
+ loading?: boolean;
11
+ /** Optional label text */
12
+ label?: string;
13
+ /** Prefix text shown before input */
14
+ prefix?: string;
15
+ }
16
+
17
+ /**
18
+ * Simple input component with different variants
19
+ * Based on SilentSwap Form.svelte and Plate.svelte styles
20
+ */
21
+ export const Input = forwardRef<HTMLInputElement, InputProps>(({
22
+ variant = 'default',
23
+ error = false,
24
+ loading = false,
25
+ label,
26
+ prefix,
27
+ className = '',
28
+ ...props
29
+ }, ref) => {
30
+ const baseClasses = 'w-full border-0 rounded-lg transition-all focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed';
31
+
32
+ const variantClasses = {
33
+ default: 'px-3 py-2 text-base bg-black text-white',
34
+ digital: 'digital-input', // Uses CSS class from styles.css
35
+ amount: 'text-[28px] font-bold text-white px-3 py-1 bg-black rounded-t-lg rounded-b-none',
36
+ };
37
+
38
+ const errorClasses = error ? 'focus:ring-red-500' : 'focus:ring-[var(--color-yellow)]';
39
+ const loadingClasses = loading ? 'animate-[trill_350ms_linear_infinite] bg-[var(--color-gray-dark)]' : '';
40
+
41
+ const classes = `${baseClasses} ${variantClasses[variant]} ${errorClasses} ${loadingClasses} ${className}`.trim();
42
+
43
+ const inputElement = (
44
+ <div className="relative flex items-center">
45
+ {prefix && (
46
+ <span className="absolute left-3 text-gray-400 font-medium">
47
+ {prefix}
48
+ </span>
49
+ )}
50
+ <input
51
+ ref={ref}
52
+ className={`${classes} ${prefix ? 'pl-8' : ''}`}
53
+ {...props}
54
+ />
55
+ </div>
56
+ );
57
+
58
+ if (label) {
59
+ return (
60
+ <div className="w-full">
61
+ <label className="block text-sm font-medium mb-1 text-gray-300">
62
+ {label}
63
+ </label>
64
+ {inputElement}
65
+ </div>
66
+ );
67
+ }
68
+
69
+ return inputElement;
70
+ });
71
+
72
+ Input.displayName = 'Input';
@@ -0,0 +1,78 @@
1
+ import React from 'react';
2
+ import { S_CAIP19_USDC_AVALANCHE } from '../constants';
3
+ import { asset_get } from '../data';
4
+ import { AssetTile } from './AssetTile';
5
+
6
+ export interface PopularTokensAreaProps {
7
+ onTokenSelect?: (caip19: string) => void;
8
+ title?: string;
9
+ tokens?: string[];
10
+ className?: string;
11
+ }
12
+
13
+ export const PopularTokensArea: React.FC<PopularTokensAreaProps> = ({
14
+ onTokenSelect,
15
+ title = 'Popular Tokens',
16
+ tokens,
17
+ className = ''
18
+ }) => {
19
+ const defaultTokens = [
20
+ 'eip155:1/slip44:60', // ETH on Ethereum
21
+ 'eip155:1/erc20:0xdAC17F958D2ee523a2206206994597C13D831ec7', // USDT on Ethereum
22
+ 'eip155:1/erc20:0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC on Ethereum
23
+ 'eip155:1/erc20:0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', // WETH on Ethereum
24
+ 'eip155:1/erc20:0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', // WBTC on Ethereum
25
+
26
+ 'eip155:56/slip44:714', // BNB on BSC
27
+ 'eip155:56/erc20:0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c', // WBNB on BSC
28
+
29
+ 'eip155:8453/slip44:60', // ETH on Base
30
+ 'eip155:8453/erc20:0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', // USDC on Base
31
+
32
+ 'eip155:43114/slip44:9005', // WAVAX on Avalanche
33
+ S_CAIP19_USDC_AVALANCHE, // USDC on Avalanche
34
+
35
+ 'eip155:137/slip44:966', // WMATIC/WPOL on Polygon
36
+ 'eip155:137/erc20:0xc2132D05D31c914a87C6611C10748AEb04B58e8F', // USDT0 on Polygon
37
+ 'eip155:137/erc20:0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359', // USDC on Polygon
38
+
39
+ 'eip155:10/slip44:60', // WETH on Optimism
40
+ 'eip155:10/erc20:0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85', // USDC on Optimism
41
+
42
+ 'eip155:42161/slip44:60', // WETH on Arbitrum
43
+ 'eip155:42161/erc20:0xaf88d065e77c8cC2239327C5EDb3A432268e5831', // USDC on Arbitrum
44
+ ];
45
+
46
+ const popularTokens = tokens || defaultTokens;
47
+
48
+ return (
49
+ <div className={`${className}`}>
50
+ <div className="font-orbitron text-lg font-bold text-white mb-3">
51
+ {title}
52
+ </div>
53
+
54
+ <div className="flex gap-2 overflow-x-auto pb-2">
55
+ {popularTokens.map((caip19) => {
56
+ const asset = asset_get(caip19);
57
+ if (!asset) return null;
58
+
59
+ return (
60
+ <div
61
+ key={caip19}
62
+ className="flex flex-col items-center gap-2 bg-dim-med rounded-lg p-2 cursor-pointer hover:bg-dim-light transition-colors min-w-fit"
63
+ onClick={() => onTokenSelect?.(caip19)}
64
+ role="button"
65
+ tabIndex={0}
66
+ aria-label={`Select ${asset.symbol}`}
67
+ >
68
+ <AssetTile caip19={caip19} size="small" />
69
+ <div className="text-text-dim text-xs text-center">
70
+ {asset.symbol?.toUpperCase()}
71
+ </div>
72
+ </div>
73
+ );
74
+ })}
75
+ </div>
76
+ </div>
77
+ );
78
+ };
@@ -0,0 +1,67 @@
1
+ import React from 'react';
2
+ import type { HTMLAttributes } from 'react';
3
+
4
+ export interface ProgressBarProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
5
+ /** Progress value from 0 to 1 (0 = 0%, 1 = 100%) */
6
+ value: number;
7
+ /** Height of the progress bar in pixels */
8
+ height?: number;
9
+ /** Color of the progress fill */
10
+ color?: 'green' | 'yellow' | 'purple' | 'orange';
11
+ /** Whether to show the progress bar (animates height) */
12
+ show?: boolean;
13
+ }
14
+
15
+ /**
16
+ * Simple progress bar component
17
+ * Based on SilentSwap Plate.svelte progress styles
18
+ */
19
+ export const ProgressBar: React.FC<ProgressBarProps> = ({
20
+ value,
21
+ height = 6,
22
+ color = 'green',
23
+ show = true,
24
+ className = '',
25
+ style,
26
+ ...props
27
+ }) => {
28
+ const colorClasses = {
29
+ green: 'bg-[var(--color-green)]',
30
+ yellow: 'bg-[var(--color-yellow)]',
31
+ purple: 'bg-[var(--color-purple)]',
32
+ orange: 'bg-[var(--color-orange)]',
33
+ };
34
+
35
+ // Clamp value between 0 and 1
36
+ const clampedValue = Math.max(0, Math.min(1, value));
37
+
38
+ const containerStyle: React.CSSProperties = {
39
+ height: show ? `${height}px` : '0px',
40
+ width: '100%',
41
+ backgroundColor: 'var(--color-gray-dark)',
42
+ transition: 'height 500ms linear',
43
+ overflow: 'hidden',
44
+ ...style,
45
+ };
46
+
47
+ const fillStyle: React.CSSProperties = {
48
+ width: `${clampedValue * 100}%`,
49
+ height: '100%',
50
+ transition: 'width 490ms linear',
51
+ };
52
+
53
+ return (
54
+ <div
55
+ className={className}
56
+ style={containerStyle}
57
+ role="progressbar"
58
+ aria-valuenow={clampedValue * 100}
59
+ aria-valuemin={0}
60
+ aria-valuemax={100}
61
+ {...props}
62
+ >
63
+ <div className={colorClasses[color]} style={fillStyle} />
64
+ </div>
65
+ );
66
+ };
67
+
@@ -0,0 +1,48 @@
1
+ import React, { forwardRef } from 'react';
2
+ import type { SelectHTMLAttributes, ReactNode } from 'react';
3
+
4
+ export interface SelectOption {
5
+ value: string;
6
+ label: string;
7
+ disabled?: boolean;
8
+ }
9
+
10
+ export interface SelectProps extends Omit<SelectHTMLAttributes<HTMLSelectElement>, 'children'> {
11
+ options: SelectOption[];
12
+ placeholder?: string;
13
+ }
14
+
15
+ export const Select = forwardRef<HTMLSelectElement, SelectProps>(({
16
+ options,
17
+ placeholder,
18
+ className = '',
19
+ ...props
20
+ }, ref) => {
21
+ const classes = `bg-black border-0 rounded-lg text-white px-3 py-2 cursor-pointer transition-colors focus:outline-none focus:ring-2 focus:ring-yellow focus:ring-offset-2 hover:bg-dim-dark ${className}`.trim();
22
+
23
+ return (
24
+ <select
25
+ ref={ref}
26
+ className={classes}
27
+ {...props}
28
+ >
29
+ {placeholder && (
30
+ <option value="" disabled>
31
+ {placeholder}
32
+ </option>
33
+ )}
34
+ {options.map((option) => (
35
+ <option
36
+ key={option.value}
37
+ value={option.value}
38
+ disabled={option.disabled}
39
+ className="bg-black text-text-bright"
40
+ >
41
+ {option.label}
42
+ </option>
43
+ ))}
44
+ </select>
45
+ );
46
+ });
47
+
48
+ Select.displayName = 'Select';
@@ -0,0 +1,54 @@
1
+ import React from 'react';
2
+ import type { HTMLAttributes, ReactNode } from 'react';
3
+
4
+ export interface WarningProps extends HTMLAttributes<HTMLDivElement> {
5
+ /** Warning content */
6
+ children: ReactNode;
7
+ /** Variant of the warning */
8
+ variant?: 'warning' | 'error' | 'info' | 'success';
9
+ /** Whether to show a dot indicator */
10
+ showDot?: boolean;
11
+ }
12
+
13
+ /**
14
+ * Simple warning/notice component
15
+ * Based on SilentSwap Plate.svelte input-notice styles
16
+ */
17
+ export const Warning: React.FC<WarningProps> = ({
18
+ children,
19
+ variant = 'warning',
20
+ showDot = true,
21
+ className = '',
22
+ ...props
23
+ }) => {
24
+ const baseClasses = 'text-xs bg-black/80 rounded px-2 py-1 flex items-center gap-1';
25
+
26
+ const variantClasses = {
27
+ warning: 'text-[#FED703]',
28
+ error: 'text-red-500',
29
+ info: 'text-blue-400',
30
+ success: 'text-[var(--color-green)]',
31
+ };
32
+
33
+ const dotColor = {
34
+ warning: '#FED703',
35
+ error: '#ef4444',
36
+ info: '#60a5fa',
37
+ success: 'var(--color-green)',
38
+ };
39
+
40
+ const classes = `${baseClasses} ${variantClasses[variant]} ${className}`.trim();
41
+
42
+ return (
43
+ <div className={classes} {...props}>
44
+ {showDot && (
45
+ <span
46
+ className="inline-block w-[5px] h-[6px] rounded-full"
47
+ style={{ backgroundColor: dotColor[variant] }}
48
+ />
49
+ )}
50
+ <span>{children}</span>
51
+ </div>
52
+ );
53
+ };
54
+
@@ -0,0 +1,5 @@
1
+ // CAIP-19 identifier for USDC on Avalanche
2
+ export const S_CAIP19_USDC_AVALANCHE = 'eip155:43114/erc20:0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E';
3
+
4
+ // Minimum input USD value
5
+ export const X_MINIMUM_INPUT_USD = 9.95;
package/src/data.ts ADDED
@@ -0,0 +1,19 @@
1
+ import type { Asset, WeakCaip19, WeakCaip2 } from './types';
2
+
3
+ // Global assets and chains stores
4
+ let H_ASSETS: Record<WeakCaip19, Asset> = {};
5
+ let H_CHAINS: Record<WeakCaip2, any> = {};
6
+
7
+ // Asset data loading function - needs to be called by consumer
8
+ export function loadAssets(assetData: { assets: Record<WeakCaip19, Asset>; chains: Record<WeakCaip2, any> }) {
9
+ H_ASSETS = assetData.assets;
10
+ H_CHAINS = assetData.chains;
11
+ }
12
+
13
+ export function asset_get(si_caip19: string): Asset | undefined {
14
+ return H_ASSETS[si_caip19 as WeakCaip19];
15
+ }
16
+
17
+ export function chain_get(si_caip2: string): any | undefined {
18
+ return H_CHAINS[si_caip2 as WeakCaip2];
19
+ }
package/src/index.ts ADDED
@@ -0,0 +1,26 @@
1
+ // Components
2
+ export { Button } from './components/Button';
3
+ export { Input } from './components/Input';
4
+ export { Select } from './components/Select';
5
+ export { Card } from './components/Card';
6
+ export { Warning } from './components/Warning';
7
+ export { ProgressBar } from './components/ProgressBar';
8
+ export { AssetTile } from './components/AssetTile';
9
+ export { PopularTokensArea } from './components/PopularTokensArea';
10
+
11
+ // Note: Import styles.css in your app for Tailwind styles
12
+
13
+ // Types
14
+ export type { Asset, ContactId } from './types';
15
+ export type { ButtonProps } from './components/Button';
16
+ export type { InputProps } from './components/Input';
17
+ export type { SelectProps, SelectOption } from './components/Select';
18
+ export type { CardProps } from './components/Card';
19
+ export type { WarningProps } from './components/Warning';
20
+ export type { ProgressBarProps } from './components/ProgressBar';
21
+
22
+ // Constants
23
+ export { S_CAIP19_USDC_AVALANCHE, X_MINIMUM_INPUT_USD } from './constants';
24
+
25
+ // Data utilities
26
+ export { loadAssets } from './data';