@monygroupcorp/micro-web3 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.
@@ -0,0 +1,81 @@
1
+ import { Component } from '@monygroupcorp/microact';
2
+
3
+ /**
4
+ * SwapButton Component
5
+ *
6
+ * Main swap action button with state management.
7
+ *
8
+ * @class SwapButton
9
+ * @extends Component
10
+ */
11
+ export class SwapButton extends Component {
12
+ /**
13
+ * @param {Object} props - Component props
14
+ * @param {string} props.direction - Current swap direction ('buy' or 'sell')
15
+ * @param {boolean} props.disabled - Whether button should be disabled
16
+ * @param {Function} props.onClick - Callback when button is clicked
17
+ */
18
+ constructor(props = {}) {
19
+ super();
20
+ this.props = props;
21
+ }
22
+
23
+ /**
24
+ * Update component props
25
+ * @param {Object} newProps - New props to merge
26
+ */
27
+ updateProps(newProps) {
28
+ const oldProps = { ...this.props };
29
+ this.props = { ...this.props, ...newProps };
30
+
31
+ // Only update if the button text would actually change
32
+ const oldText = oldProps.direction === 'buy' ? 'Buy $EXEC' : 'Sell $EXEC';
33
+ const newText = this.props.direction === 'buy' ? 'Buy $EXEC' : 'Sell $EXEC';
34
+
35
+ if (oldText !== newText || oldProps.disabled !== this.props.disabled) {
36
+ // Only update if something actually changed
37
+ if (this.element) {
38
+ const button = this.element.querySelector('.swap-button');
39
+ if (button) {
40
+ button.textContent = newText;
41
+ if (this.props.disabled) {
42
+ button.disabled = true;
43
+ } else {
44
+ button.disabled = false;
45
+ }
46
+ }
47
+ }
48
+ }
49
+ }
50
+
51
+ /**
52
+ * Handle button click
53
+ * @param {Event} e - Click event
54
+ */
55
+ handleClick(e) {
56
+ e.preventDefault();
57
+ if (!this.props.disabled && this.props.onClick) {
58
+ this.props.onClick(e);
59
+ }
60
+ }
61
+
62
+ events() {
63
+ return {
64
+ 'click .swap-button': (e) => this.handleClick(e)
65
+ };
66
+ }
67
+
68
+ render() {
69
+ const { direction, disabled } = this.props;
70
+ const buttonText = direction === 'buy' ? 'Buy $EXEC' : 'Sell $EXEC';
71
+
72
+ return `
73
+ <button class="swap-button" ${disabled ? 'disabled' : ''}>
74
+ ${buttonText}
75
+ </button>
76
+ `;
77
+ }
78
+ }
79
+
80
+ export default SwapButton;
81
+
@@ -0,0 +1,137 @@
1
+ import { Component } from '@monygroupcorp/microact';
2
+
3
+ export class SwapInputs extends Component {
4
+ constructor(props = {}) {
5
+ super(props);
6
+ this.props = {
7
+ balances: { eth: '0', exec: '0' },
8
+ ...props
9
+ };
10
+ }
11
+
12
+ /**
13
+ * Update component props
14
+ * @param {Object} newProps - New props to merge
15
+ */
16
+ updateProps(newProps) {
17
+ this.props = { ...this.props, ...newProps };
18
+ // Don't call update() directly as it will destroy input elements and lose focus
19
+ // Instead, update only the parts that changed
20
+ this.updateSelectively(newProps);
21
+ }
22
+
23
+ /**
24
+ * Update only specific parts of the UI without destroying inputs
25
+ * @param {Object} changedProps - Props that changed
26
+ */
27
+ updateSelectively(changedProps) {
28
+ if (!this.element) return;
29
+
30
+ if (changedProps.direction !== undefined || changedProps.freeMint !== undefined || changedProps.balances !== undefined) {
31
+ const { balances, direction, freeMint } = this.props;
32
+ const formattedEthBalance = parseFloat(balances.eth || 0).toFixed(6);
33
+ const formattedExecBalance = parseInt(balances.exec || 0).toLocaleString();
34
+ const availableExecBalance = direction === 'sell' && freeMint
35
+ ? `Available: ${(parseInt(balances.exec || 0) - 1000000).toLocaleString()}`
36
+ : `Balance: ${formattedExecBalance}`;
37
+
38
+ const balanceDisplays = this.element.querySelectorAll('.token-balance');
39
+ balanceDisplays.forEach((display, index) => {
40
+ const isTopInput = index === 0;
41
+ if (direction === 'buy') {
42
+ display.textContent = isTopInput ? `Balance: ${formattedEthBalance}` : `Balance: ${formattedExecBalance}`;
43
+ } else {
44
+ display.textContent = isTopInput ? availableExecBalance : `Balance: ${formattedEthBalance}`;
45
+ }
46
+ });
47
+
48
+ const tokenSymbols = this.element.querySelectorAll('.token-symbol');
49
+ tokenSymbols.forEach((symbol, index) => {
50
+ const isTopInput = index === 0;
51
+ if (direction === 'buy') {
52
+ symbol.textContent = isTopInput ? 'ETH' : '$EXEC';
53
+ } else {
54
+ symbol.textContent = isTopInput ? '$EXEC' : 'ETH';
55
+ }
56
+ });
57
+ }
58
+
59
+ const topInput = this.element.querySelector('.top-input');
60
+ const bottomInput = this.element.querySelector('.bottom-input');
61
+
62
+ if (changedProps.calculatingAmount !== undefined || changedProps.execAmount !== undefined || changedProps.ethAmount !== undefined) {
63
+ const { direction, ethAmount, execAmount, calculatingAmount } = this.props;
64
+
65
+ if (topInput && !topInput.matches(':focus')) {
66
+ topInput.value = direction === 'buy' ? ethAmount : execAmount;
67
+ }
68
+
69
+ if (bottomInput && !bottomInput.matches(':focus')) {
70
+ bottomInput.value = direction === 'buy'
71
+ ? (calculatingAmount ? 'Loading...' : execAmount)
72
+ : (calculatingAmount ? 'Loading...' : ethAmount);
73
+ }
74
+ }
75
+ }
76
+
77
+ /**
78
+ * Handle input change events
79
+ * @param {Event} e - Input event
80
+ * @param {string} inputType - 'top' or 'bottom'
81
+ */
82
+ handleInput(e, inputType) {
83
+ const value = e.target.value;
84
+ if (this.props.onInput) {
85
+ this.props.onInput(inputType, value);
86
+ }
87
+ }
88
+
89
+ events() {
90
+ return {
91
+ 'input .top-input': (e) => this.handleInput(e, 'top'),
92
+ 'input .bottom-input': (e) => this.handleInput(e, 'bottom')
93
+ };
94
+ }
95
+
96
+ render() {
97
+ const { direction, ethAmount, execAmount, calculatingAmount, freeMint, balances } = this.props;
98
+
99
+ const formattedEthBalance = parseFloat(balances.eth || 0).toFixed(6);
100
+ const formattedExecBalance = parseInt(balances.exec || 0).toLocaleString();
101
+
102
+ const availableExecBalance = direction === 'sell' && freeMint
103
+ ? `Available: ${(parseInt(balances.exec || 0) - 1000000).toLocaleString()}`
104
+ : `Balance: ${formattedExecBalance}`;
105
+
106
+ return `
107
+ <div class="swap-inputs">
108
+ <div class="input-container">
109
+ <input type="text"
110
+ class="top-input"
111
+ value="${direction === 'buy' ? ethAmount : execAmount}"
112
+ placeholder="0.0"
113
+ pattern="^[0-9]*[.]?[0-9]*$">
114
+ <div class="token-info">
115
+ <span class="token-symbol">${direction === 'buy' ? 'ETH' : '$EXEC'}</span>
116
+ <span class="token-balance">Balance: ${direction === 'buy' ? formattedEthBalance : availableExecBalance}</span>
117
+ </div>
118
+ </div>
119
+ <div class="direction-switch-slot"></div>
120
+ <div class="input-container">
121
+ <input type="text"
122
+ class="bottom-input"
123
+ value="${direction === 'buy' ? (calculatingAmount ? 'Loading...' : execAmount) : (calculatingAmount ? 'Loading...' : ethAmount)}"
124
+ placeholder="0.0"
125
+ pattern="^[0-9]*[.]?[0-9]*$">
126
+ <div class="token-info">
127
+ <span class="token-symbol">${direction === 'buy' ? '$EXEC' : 'ETH'}</span>
128
+ <span class="token-balance">Balance: ${direction === 'buy' ? formattedExecBalance : formattedEthBalance}</span>
129
+ </div>
130
+ </div>
131
+ </div>
132
+ `;
133
+ }
134
+ }
135
+
136
+ export default SwapInputs;
137
+