Skip to content

Commit b5973b8

Browse files
0.1.3 (#266)
* Added github releases (#264) * Added github release * Add github release * Update changelog * Added skip tests on draft PR (#265) * Added skip tests on draft PR * Update changelog * Add test log * Remove log * Refactored unlock panel components (#255) * Refactored unlock panel footer * Updated unlock panel footer * Refactored unlock-panel-group component * Updated imports * Fixed trim component flickering * Fixed trim flickering * Fixes after review * Refactored unlock-provider-button to functional component * Fixed trim flickering * Update changelog * updates * Upgraded version --------- Co-authored-by: Gavrila Andrei <[email protected]>
1 parent 6dac0a5 commit b5973b8

28 files changed

+321
-396
lines changed

.github/workflows/changelog.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: "CHANGELOG entry secretary"
1+
name: 'CHANGELOG entry secretary'
22
on:
33
pull_request:
44
branches: [main, development]
@@ -9,8 +9,9 @@ on:
99
types: [opened, synchronize, reopened, ready_for_review, labeled, unlabeled]
1010

1111
jobs:
12-
# Enforces the update of a changelog file on every pull request
12+
# Enforces the update of a changelog file on every pull request
1313
changelog:
1414
runs-on: ubuntu-latest
15+
if: ${{ !github.event.pull_request.draft }}
1516
steps:
16-
- uses: dangoslen/changelog-enforcer@v3
17+
- uses: dangoslen/changelog-enforcer@v3

.github/workflows/npm-publish.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,28 @@ jobs:
4747
id: package
4848
uses: andreigiura/[email protected]
4949

50+
- name: Create GitHub Release
51+
env:
52+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
53+
if: ${{ steps.package.outputs.is-prerelease == 'false' }}
54+
run: |
55+
RELEASE_TAG=v${{ steps.package.outputs.version }}
56+
echo "Creating release for version: $RELEASE_TAG"
57+
58+
changelog_content=$(awk "/^## \[\[?${RELEASE_TAG#v}[^\]]*\]/{flag=1; next} /^## \[/{flag=0} flag" CHANGELOG.md)
59+
60+
cat > release_notes.md << EOF
61+
## What's Changed
62+
63+
$changelog_content
64+
EOF
65+
66+
# Create the release
67+
gh release create "$RELEASE_TAG" \
68+
--target=$GITHUB_SHA \
69+
--title="$RELEASE_TAG" \
70+
--notes-file release_notes.md
71+
5072
- name: Publish to npmjs next version
5173
env:
5274
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}

.github/workflows/pre-merge-unit-tests.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
name: 'Stencil Unit Tests'
22
on:
33
pull_request:
4+
types: [opened, synchronize, reopened, ready_for_review]
45
branches: [main, development]
56
paths:
67
- 'src/**'
@@ -18,6 +19,7 @@ concurrency:
1819
jobs:
1920
run-unit-tests:
2021
runs-on: ubuntu-latest
22+
if: ${{ !github.event.pull_request.draft }}
2123
steps:
2224
- name: Fix permissions
2325
run: |

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [[0.1.3](https://github.com/multiversx/mx-sdk-dapp-ui/pull/266)] - 2025-11-12
11+
12+
- [Added skip tests if PR is in draft](https://github.com/multiversx/mx-sdk-dapp-ui/pull/265)
13+
- [Refactored unlock panel components](https://github.com/multiversx/mx-sdk-dapp-ui/pull/255)
14+
- [Added github release on publish](https://github.com/multiversx/mx-sdk-dapp-ui/pull/264)
15+
1016
## [[0.1.2](https://github.com/multiversx/mx-sdk-dapp-ui/pull/263)] - 2025-11-06
1117

1218
- [Added expose EventBus from utils](https://github.com/multiversx/mx-sdk-dapp-ui/pull/262)

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@multiversx/sdk-dapp-ui",
3-
"version": "0.1.2",
3+
"version": "0.1.3",
44
"description": "A library to hold UI components for a dApp on the MultiversX blockchain",
55
"author": "MultiversX",
66
"license": "MIT",
@@ -141,4 +141,4 @@
141141
"typescript": "^5.7.3",
142142
"vite": "^7.0.6"
143143
}
144-
}
144+
}

src/common/Trim/Trim.tsx

Lines changed: 75 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ export function Trim({
2222
let currentTrimFontSize = '1rem';
2323
let trimFullElement: HTMLDivElement;
2424
let trimWrapperElement: HTMLDivElement;
25+
let isCurrentlyOverflowing: boolean | null = null;
26+
let isCheckingOverflow = false;
2527

2628
const handleTrimElementReference = (element: HTMLDivElement) => {
2729
if (element) {
@@ -64,43 +66,94 @@ export function Trim({
6466
}
6567

6668
const checkOverflow = () => {
67-
if (!fullWidthUntrimmedElementReference || !trimElementReference || !trimFullElement || !trimWrapperElement) {
69+
if (isCheckingOverflow) {
6870
return;
6971
}
7072

71-
const hiddenFullWidthElementWidth = fullWidthUntrimmedElementReference.scrollWidth;
72-
const trimmedElementWidth = trimElementReference.clientWidth;
73-
const isTrimElementOverflowing = hiddenFullWidthElementWidth > trimmedElementWidth;
74-
75-
if (safeWindow) {
76-
currentTrimFontSize = safeWindow.getComputedStyle(trimElementReference).fontSize;
73+
if (!fullWidthUntrimmedElementReference || !trimElementReference || !trimFullElement || !trimWrapperElement) {
74+
return;
7775
}
7876

79-
const getIdentifierClass = (classes: string) => classes.split(' ')[0];
80-
81-
const trimLeftSelector = `.${getIdentifierClass(styles.trimLeft)}`;
82-
const trimRightSelector = `.${getIdentifierClass(styles.trimRight)}`;
77+
isCheckingOverflow = true;
8378

84-
const trimLeftElement = trimElementReference.querySelector(trimLeftSelector) as HTMLElement;
85-
const trimRightElement = trimElementReference.querySelector(trimRightSelector) as HTMLElement;
86-
if (trimLeftElement) {
87-
trimLeftElement.style.fontSize = currentTrimFontSize;
79+
if (resizeObserver) {
80+
resizeObserver.disconnect();
8881
}
8982

90-
if (trimRightElement) {
91-
trimRightElement.style.fontSize = currentTrimFontSize;
92-
}
83+
84+
const getIdentifierClass = (classes: string) => classes.split(' ')[0];
9385

9486
const trimFullVisibleClasses = styles.trimFullVisible.split(/\s+/);
9587
const trimWrapperVisibleClasses = styles.trimWrapperVisible.split(/\s+/);
9688

97-
if (isTrimElementOverflowing) {
89+
const hasFullVisible = trimFullElement.classList.contains(getIdentifierClass(styles.trimFullVisible));
90+
const hasWrapperVisible = trimWrapperElement.classList.contains(getIdentifierClass(styles.trimWrapperVisible));
91+
92+
if (hasFullVisible) {
9893
trimFullElement.classList.remove(...trimFullVisibleClasses);
99-
trimWrapperElement.classList.add(...trimWrapperVisibleClasses);
100-
} else {
101-
trimFullElement.classList.add(...trimFullVisibleClasses);
94+
}
95+
if (hasWrapperVisible) {
10296
trimWrapperElement.classList.remove(...trimWrapperVisibleClasses);
10397
}
98+
99+
const hiddenFullWidthElementWidth = fullWidthUntrimmedElementReference.scrollWidth;
100+
const trimmedElementWidth = trimElementReference.clientWidth;
101+
const isTrimElementOverflowing = hiddenFullWidthElementWidth > trimmedElementWidth;
102+
103+
if (isCurrentlyOverflowing === isTrimElementOverflowing) {
104+
if (hasFullVisible) {
105+
trimFullElement.classList.add(...trimFullVisibleClasses);
106+
}
107+
if (hasWrapperVisible) {
108+
trimWrapperElement.classList.add(...trimWrapperVisibleClasses);
109+
}
110+
111+
isCheckingOverflow = false;
112+
113+
setTimeout(() => {
114+
if (resizeObserver && trimElementReference) {
115+
resizeObserver.observe(trimElementReference);
116+
}
117+
});
118+
return;
119+
}
120+
121+
isCurrentlyOverflowing = isTrimElementOverflowing;
122+
123+
requestAnimationFrame(() => {
124+
if (safeWindow) {
125+
currentTrimFontSize = safeWindow.getComputedStyle(trimElementReference).fontSize;
126+
}
127+
128+
const trimLeftSelector = `.${getIdentifierClass(styles.trimLeft)}`;
129+
const trimRightSelector = `.${getIdentifierClass(styles.trimRight)}`;
130+
131+
const trimLeftElement = trimElementReference.querySelector(trimLeftSelector) as HTMLElement;
132+
const trimRightElement = trimElementReference.querySelector(trimRightSelector) as HTMLElement;
133+
if (trimLeftElement) {
134+
trimLeftElement.style.fontSize = currentTrimFontSize;
135+
}
136+
137+
if (trimRightElement) {
138+
trimRightElement.style.fontSize = currentTrimFontSize;
139+
}
140+
141+
if (isTrimElementOverflowing) {
142+
trimFullElement.classList.remove(...trimFullVisibleClasses);
143+
trimWrapperElement.classList.add(...trimWrapperVisibleClasses);
144+
} else {
145+
trimFullElement.classList.add(...trimFullVisibleClasses);
146+
trimWrapperElement.classList.remove(...trimWrapperVisibleClasses);
147+
}
148+
149+
isCheckingOverflow = false;
150+
151+
requestAnimationFrame(() => {
152+
if (resizeObserver && trimElementReference) {
153+
resizeObserver.observe(trimElementReference);
154+
}
155+
});
156+
});
104157
};
105158

106159
const middleTextIndex = Math.floor(text.length / 2);

src/common/UnlockButton/UnlockButton.tsx

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,7 @@ import { safeWindow } from 'constants/window.constants';
1313
import type { IProviderBase } from 'types/provider.types';
1414
import { ProviderTypeEnum } from 'types/provider.types';
1515
import { getDetectedBrowser } from 'utils/getDetectedBrowser';
16-
17-
// prettier-ignore
18-
const styles = {
19-
unlockButton: 'unlock-button mvx:pl-3 mvx:pr-4 mvx:h-15 mvx:flex! mvx:gap-4 mvx:cursor-pointer mvx:items-center mvx:transition-all mvx:duration-200 mvx:ease-in-out mvx:bg-secondary mvx:hover:bg-hover',
20-
unlockButtonIcon: 'unlock-button-icon mvx:-order-1 mvx:h-10 mvx:flex mvx:relative mvx:z-1 mvx:items-center mvx:justify-center mvx:w-10',
21-
unlockButtonIconClipped: 'mvx:items-end mvx:justify-start',
22-
unlockButtonLabel: 'unlock-button-label mvx:text-base mvx:relative mvx:z-1 mvx:text-primary mvx:leading-none',
23-
unlockButtonStatus: 'unlock-button-status mvx:ml-auto mvx:relative mvx:rounded-3xl mvx:z-1 mvx:leading-none mvx:flex mvx:items-center mvx:py-1 mvx:px-2 mvx:font-medium mvx:gap-1 mvx:text-xs mvx:bg-surface mvx:border mvx:border-solid mvx:border-outline',
24-
unlockButtonStatusText: 'unlock-button-status-text mvx:text-accent',
25-
unlockButtonStatusIcon: 'unlock-button-status-icon mvx:flex mvx:items-center mvx:text-accent mvx:w-2.5 mvx:h-2.5',
26-
} satisfies Record<string, string>;
16+
import styles from './unlockButton.styles';
2717

2818
interface UnlockButtonPropsType {
2919
label: string;
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// prettier-ignore
2+
export default {
3+
unlockButton: 'unlock-button mvx:pl-3 mvx:pr-4 mvx:h-15 mvx:flex mvx:gap-4 mvx:cursor-pointer mvx:items-center mvx:transition-all mvx:duration-200 mvx:ease-in-out mvx:bg-secondary mvx:hover:bg-hover',
4+
unlockButtonIcon: 'unlock-button-icon mvx:-order-1 mvx:h-10 mvx:flex mvx:relative mvx:z-1 mvx:items-center mvx:justify-center mvx:w-10',
5+
unlockButtonIconClipped: 'mvx:items-end mvx:justify-start',
6+
unlockButtonLabel: 'unlock-button-label mvx:text-base mvx:relative mvx:z-1 mvx:text-primary mvx:leading-none',
7+
unlockButtonStatus: 'unlock-button-status mvx:ml-auto mvx:relative mvx:rounded-3xl mvx:z-1 mvx:leading-none mvx:flex mvx:items-center mvx:py-1 mvx:px-2 mvx:font-medium mvx:gap-1 mvx:text-xs mvx:bg-surface mvx:border mvx:border-solid mvx:border-outline',
8+
unlockButtonStatusText: 'unlock-button-status-text mvx:text-accent',
9+
unlockButtonStatusIcon: 'unlock-button-status-icon mvx:flex mvx:items-center mvx:text-accent mvx:w-2.5 mvx:h-2.5',
10+
} satisfies Record<string, string>;

src/components.d.ts

Lines changed: 2 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { ITransactionListItem as ITransactionListItem1 } from "./components/visu
1717
import { IToastDataState, ITransactionProgressState } from "./components/functional/toasts-list/components/transaction-toast/transaction-toast.type";
1818
import { TransactionStatusEnum } from "./constants/transactionStatus.enum";
1919
import { TransactionRowType } from "./components/controlled/transactions-table/transactions-table.type";
20-
import { IProviderBase, ProviderTypeEnum } from "./types/provider.types";
20+
import { IProviderBase } from "./types/provider.types";
2121
import { IEventBus as IEventBus1, unknown as IWalletConnectPanelData } from "./components.d";
2222
export { IAddressTableData } from "./types/address-table.types";
2323
export { ButtonSizeEnum, ButtonVariantEnum } from "./components/visual/button/button.types";
@@ -31,7 +31,7 @@ export { ITransactionListItem as ITransactionListItem1 } from "./components/visu
3131
export { IToastDataState, ITransactionProgressState } from "./components/functional/toasts-list/components/transaction-toast/transaction-toast.type";
3232
export { TransactionStatusEnum } from "./constants/transactionStatus.enum";
3333
export { TransactionRowType } from "./components/controlled/transactions-table/transactions-table.type";
34-
export { IProviderBase, ProviderTypeEnum } from "./types/provider.types";
34+
export { IProviderBase } from "./types/provider.types";
3535
export { IEventBus as IEventBus1, unknown as IWalletConnectPanelData } from "./components.d";
3636
export namespace Components {
3737
interface MvxAddressTable {
@@ -397,20 +397,6 @@ export namespace Components {
397397
"closeWithAnimation": () => Promise<unknown>;
398398
"getEventBus": () => Promise<IEventBus>;
399399
}
400-
interface MvxUnlockPanelFooter {
401-
"walletAddress": string;
402-
}
403-
interface MvxUnlockPanelGroup {
404-
"class"?: string;
405-
/**
406-
* @default []
407-
*/
408-
"providers": IProviderBase[];
409-
}
410-
interface MvxUnlockProviderButton {
411-
"class"?: string;
412-
"provider": IProviderBase<ProviderTypeEnum>;
413-
}
414400
interface MvxWalletConnect {
415401
/**
416402
* @default { wcURI: '' }
@@ -514,10 +500,6 @@ export interface MvxTransactionToastContentCustomEvent<T> extends CustomEvent<T>
514500
detail: T;
515501
target: HTMLMvxTransactionToastContentElement;
516502
}
517-
export interface MvxUnlockPanelGroupCustomEvent<T> extends CustomEvent<T> {
518-
detail: T;
519-
target: HTMLMvxUnlockPanelGroupElement;
520-
}
521503
export interface MvxWalletConnectScanCustomEvent<T> extends CustomEvent<T> {
522504
detail: T;
523505
target: HTMLMvxWalletConnectScanElement;
@@ -1024,35 +1006,6 @@ declare global {
10241006
prototype: HTMLMvxUnlockPanelElement;
10251007
new (): HTMLMvxUnlockPanelElement;
10261008
};
1027-
interface HTMLMvxUnlockPanelFooterElement extends Components.MvxUnlockPanelFooter, HTMLStencilElement {
1028-
}
1029-
var HTMLMvxUnlockPanelFooterElement: {
1030-
prototype: HTMLMvxUnlockPanelFooterElement;
1031-
new (): HTMLMvxUnlockPanelFooterElement;
1032-
};
1033-
interface HTMLMvxUnlockPanelGroupElementEventMap {
1034-
"login": IProviderBase;
1035-
}
1036-
interface HTMLMvxUnlockPanelGroupElement extends Components.MvxUnlockPanelGroup, HTMLStencilElement {
1037-
addEventListener<K extends keyof HTMLMvxUnlockPanelGroupElementEventMap>(type: K, listener: (this: HTMLMvxUnlockPanelGroupElement, ev: MvxUnlockPanelGroupCustomEvent<HTMLMvxUnlockPanelGroupElementEventMap[K]>) => any, options?: boolean | AddEventListenerOptions): void;
1038-
addEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
1039-
addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
1040-
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
1041-
removeEventListener<K extends keyof HTMLMvxUnlockPanelGroupElementEventMap>(type: K, listener: (this: HTMLMvxUnlockPanelGroupElement, ev: MvxUnlockPanelGroupCustomEvent<HTMLMvxUnlockPanelGroupElementEventMap[K]>) => any, options?: boolean | EventListenerOptions): void;
1042-
removeEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
1043-
removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
1044-
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
1045-
}
1046-
var HTMLMvxUnlockPanelGroupElement: {
1047-
prototype: HTMLMvxUnlockPanelGroupElement;
1048-
new (): HTMLMvxUnlockPanelGroupElement;
1049-
};
1050-
interface HTMLMvxUnlockProviderButtonElement extends Components.MvxUnlockProviderButton, HTMLStencilElement {
1051-
}
1052-
var HTMLMvxUnlockProviderButtonElement: {
1053-
prototype: HTMLMvxUnlockProviderButtonElement;
1054-
new (): HTMLMvxUnlockProviderButtonElement;
1055-
};
10561009
interface HTMLMvxWalletConnectElement extends Components.MvxWalletConnect, HTMLStencilElement {
10571010
}
10581011
var HTMLMvxWalletConnectElement: {
@@ -1176,9 +1129,6 @@ declare global {
11761129
"mvx-trim": HTMLMvxTrimElement;
11771130
"mvx-unlock-button": HTMLMvxUnlockButtonElement;
11781131
"mvx-unlock-panel": HTMLMvxUnlockPanelElement;
1179-
"mvx-unlock-panel-footer": HTMLMvxUnlockPanelFooterElement;
1180-
"mvx-unlock-panel-group": HTMLMvxUnlockPanelGroupElement;
1181-
"mvx-unlock-provider-button": HTMLMvxUnlockProviderButtonElement;
11821132
"mvx-wallet-connect": HTMLMvxWalletConnectElement;
11831133
"mvx-wallet-connect-app-gallery-icon": HTMLMvxWalletConnectAppGalleryIconElement;
11841134
"mvx-wallet-connect-app-store-icon": HTMLMvxWalletConnectAppStoreIconElement;
@@ -1561,21 +1511,6 @@ declare namespace LocalJSX {
15611511
}
15621512
interface MvxUnlockPanel {
15631513
}
1564-
interface MvxUnlockPanelFooter {
1565-
"walletAddress"?: string;
1566-
}
1567-
interface MvxUnlockPanelGroup {
1568-
"class"?: string;
1569-
"onLogin"?: (event: MvxUnlockPanelGroupCustomEvent<IProviderBase>) => void;
1570-
/**
1571-
* @default []
1572-
*/
1573-
"providers"?: IProviderBase[];
1574-
}
1575-
interface MvxUnlockProviderButton {
1576-
"class"?: string;
1577-
"provider"?: IProviderBase<ProviderTypeEnum>;
1578-
}
15791514
interface MvxWalletConnect {
15801515
/**
15811516
* @default { wcURI: '' }
@@ -1680,9 +1615,6 @@ declare namespace LocalJSX {
16801615
"mvx-trim": MvxTrim;
16811616
"mvx-unlock-button": MvxUnlockButton;
16821617
"mvx-unlock-panel": MvxUnlockPanel;
1683-
"mvx-unlock-panel-footer": MvxUnlockPanelFooter;
1684-
"mvx-unlock-panel-group": MvxUnlockPanelGroup;
1685-
"mvx-unlock-provider-button": MvxUnlockProviderButton;
16861618
"mvx-wallet-connect": MvxWalletConnect;
16871619
"mvx-wallet-connect-app-gallery-icon": MvxWalletConnectAppGalleryIcon;
16881620
"mvx-wallet-connect-app-store-icon": MvxWalletConnectAppStoreIcon;
@@ -1755,9 +1687,6 @@ declare module "@stencil/core" {
17551687
"mvx-trim": LocalJSX.MvxTrim & JSXBase.HTMLAttributes<HTMLMvxTrimElement>;
17561688
"mvx-unlock-button": LocalJSX.MvxUnlockButton & JSXBase.HTMLAttributes<HTMLMvxUnlockButtonElement>;
17571689
"mvx-unlock-panel": LocalJSX.MvxUnlockPanel & JSXBase.HTMLAttributes<HTMLMvxUnlockPanelElement>;
1758-
"mvx-unlock-panel-footer": LocalJSX.MvxUnlockPanelFooter & JSXBase.HTMLAttributes<HTMLMvxUnlockPanelFooterElement>;
1759-
"mvx-unlock-panel-group": LocalJSX.MvxUnlockPanelGroup & JSXBase.HTMLAttributes<HTMLMvxUnlockPanelGroupElement>;
1760-
"mvx-unlock-provider-button": LocalJSX.MvxUnlockProviderButton & JSXBase.HTMLAttributes<HTMLMvxUnlockProviderButtonElement>;
17611690
"mvx-wallet-connect": LocalJSX.MvxWalletConnect & JSXBase.HTMLAttributes<HTMLMvxWalletConnectElement>;
17621691
"mvx-wallet-connect-app-gallery-icon": LocalJSX.MvxWalletConnectAppGalleryIcon & JSXBase.HTMLAttributes<HTMLMvxWalletConnectAppGalleryIconElement>;
17631692
"mvx-wallet-connect-app-store-icon": LocalJSX.MvxWalletConnectAppStoreIcon & JSXBase.HTMLAttributes<HTMLMvxWalletConnectAppStoreIconElement>;

0 commit comments

Comments
 (0)