this._selectOption(network, e)}"
+ role="option"
+ >
+ ${this._renderNetworkIcon(network.name)}
+ ${capitalize(network.name)}
+
+ `
+ );
+ }
+
+ _renderTriggerContent(): HTMLTemplateResult {
+ return when(
+ this.selectedNetwork,
+ () =>
+ html`${this._renderNetworkIcon(this.selectedNetwork!.name)}
+
+ return html`
-
- `;
}
}
+
declare global {
interface HTMLElementTagNameMap {
'sygma-network-selector': NetworkSelector;
diff --git a/packages/widget/src/components/network-selector/styles.ts b/packages/widget/src/components/network-selector/styles.ts
index 845dd49d..1b36041d 100644
--- a/packages/widget/src/components/network-selector/styles.ts
+++ b/packages/widget/src/components/network-selector/styles.ts
@@ -2,22 +2,24 @@ import { css } from 'lit';
export const styles = css`
.selectorContainer {
- border-radius: 24px;
- border: 1px solid #e4e4e7;
+ border-radius: 1.5rem;
+ border: 0.0625rem solid #e4e4e7;
display: flex;
- width: 314px;
- padding: 12px 16px;
+ width: 100%;
+ max-width: 19.625rem;
+ max-height: 4.625rem;
+ padding: 0.75rem 1rem;
flex-direction: column;
justify-content: center;
align-items: stretch;
- gap: 4px;
+ gap: 0.25rem;
}
.directionLabel {
color: #a1a1aa;
- font-size: 14px;
+ font-size: 0.875rem;
font-weight: 500;
- line-height: 20px;
+ line-height: 1.25rem;
display: flex;
flex-direction: column;
justify-content: center;
@@ -30,15 +32,89 @@ export const styles = css`
.selector {
width: 100%;
color: #525252;
- font-size: 18px;
+ font-size: 1.125rem;
font-weight: 500;
- line-height: 26px;
+ line-height: 1.625rem;
border: none;
}
.selectorSection {
display: flex;
align-items: center;
- gap: 12px;
+ gap: 0.75rem;
+ }
+
+ .dropdown {
+ position: relative;
+ width: 100%;
+ }
+
+ .selectedNetwork {
+ display: flex;
+ align-items: center;
+ }
+
+ .dropdownTrigger {
+ width: 100%;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ cursor: pointer;
+ padding: 0.25rem 0;
+ box-sizing: border-box;
+ }
+
+ .chevron {
+ transform: rotate(0deg);
+ transition: transform 0.3s ease;
+
+ &.open {
+ transform: rotate(180deg);
+ }
+ }
+
+ .dropdownContent {
+ display: none;
+ position: absolute;
+ background-color: white;
+ width: 100%;
+ border-radius: 0.75rem;
+ border: 0.0625rem solid #f3f4f6;
+ box-shadow:
+ 0 0.25rem 0.375rem -0.0625rem rgba(0, 0, 0, 0.1),
+ 0 0.125rem 0.25rem -0.0625rem rgba(0, 0, 0, 0.06);
+ z-index: 1;
+ margin-top: 1rem;
+ }
+
+ .show {
+ display: block;
+ }
+
+ .dropdownOption {
+ display: flex;
+ align-items: center;
+ padding: 0.75rem 1rem;
+ cursor: pointer;
+ transition: background-color 0.3s ease;
+
+ svg {
+ max-width: 1.43656rem;
+ width: 100%;
+ }
+
+ &:hover {
+ background-color: #e9e4dd;
+ }
+ }
+
+ .networkIcon {
+ display: block;
+ width: 1.25rem;
+ height: 1.25rem;
+ }
+
+ .networkName {
+ margin-left: 0.5rem;
}
`;
diff --git a/packages/widget/src/styles.ts b/packages/widget/src/styles.ts
index 3b8120f7..5b009932 100644
--- a/packages/widget/src/styles.ts
+++ b/packages/widget/src/styles.ts
@@ -28,6 +28,10 @@ export const styles = css`
font-family: Inter, sans-serif;
}
+ .networkSelectionWrapper {
+ margin: 1rem 0 0.5rem 0;
+ }
+
.connectAccount {
display: flex;
justify-content: flex-end;
diff --git a/packages/widget/src/widget.ts b/packages/widget/src/widget.ts
index c2e5cd1c..7c481c84 100644
--- a/packages/widget/src/widget.ts
+++ b/packages/widget/src/widget.ts
@@ -22,7 +22,7 @@ class SygmaProtocolWidget extends LitElement {
${switchNetworkIcon} Connect Wallet
-
+
{
- const el = await fixture(html`
+
+ it('renders text when no network selected', async () => {
+ const el = await fixture(html`
`);
- assert.equal(el.shadowRoot!.querySelectorAll('.network-option').length, 1);
+
+ const networkOption = el.shadowRoot!.querySelector(
+ '.selectedNetwork'
+ ) as HTMLDivElement;
+
+ assert.ok(
+ networkOption,
+ 'Network option should be present in the component'
+ );
+
assert.equal(
- getDiffableHTML(el.shadowRoot!.querySelector('.selector')!),
- getDiffableHTML(
- ``
- )
+ getDiffableHTML(networkOption.textContent?.trim() ?? ''),
+ getDiffableHTML('Select Network')
);
});
+
+ it('toggles dropdown on click', async () => {
+ const networks = [
+ { id: '1', name: 'ethereum' },
+ { id: '2', name: 'khala' }
+ ];
+
+ const el = await fixture(
+ html``
+ );
+ const dropdownTrigger = el.shadowRoot!.querySelector(
+ '.dropdownTrigger'
+ ) as HTMLDivElement;
+
+ assert.ok(
+ dropdownTrigger,
+ 'Dropdown trigger should be present in the component'
+ );
+
+ // Initial state should be closed
+ assert.isFalse(el._isDropdownOpen);
+
+ // Simulate click to open dropdown
+ dropdownTrigger?.click();
+ await el.updateComplete;
+ assert.isTrue(el._isDropdownOpen);
+
+ // Simulate another click to close dropdown
+ dropdownTrigger?.click();
+ await el.updateComplete;
+ assert.isFalse(el._isDropdownOpen);
+ });
+
it('triggers callback on network selected', async () => {
const mockNetworkSelectHandler = vi.fn();
const network = { id: 0, chainId: 1, name: 'Test', type: 'evm' };
- const el = await fixture(html`
+ const el = await fixture(html`
`);
- const networkOptions = el.shadowRoot!.querySelectorAll('.network-option');
- assert.equal(networkOptions.length, 2);
- const listener = oneEvent(
- el.shadowRoot!.querySelector('.selector')!,
- 'change',
- false
- );
- (el.shadowRoot!.querySelector('.selector') as HTMLSelectElement).value =
- '1';
- el.shadowRoot!.querySelector('.selector')!.dispatchEvent(
- new Event('change')
- );
- (networkOptions[1] as HTMLOptionElement).selected = true;
- await listener;
+
+ // Simulate selecting a network
+ const firstOption = el.shadowRoot!.querySelector(
+ '.dropdownOption'
+ ) as HTMLDivElement;
+ assert.ok(firstOption, 'First option should be present in the component');
+ firstOption.click();
+ await el.updateComplete;
+
assert.equal(mockNetworkSelectHandler.mock.calls.length, 1);
assert.deepEqual(mockNetworkSelectHandler.mock.lastCall, [network]);
});