mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-07-21 07:58:11 -07:00
global: private xpub support part 2
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
* @typedef {Object} StoredWallet
|
||||
* @property {string} id
|
||||
* @property {string} name
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} WalletSelectorOptions
|
||||
* @property {() => string} getSelectedId
|
||||
* @property {(walletId: string) => void} onSelect
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {HTMLElement} walletList
|
||||
* @param {StoredWallet[]} wallets
|
||||
* @param {WalletSelectorOptions} options
|
||||
*/
|
||||
function renderButtons(walletList, wallets, options) {
|
||||
walletList.replaceChildren();
|
||||
|
||||
for (const wallet of wallets) {
|
||||
const button = document.createElement("button");
|
||||
const selected = wallet.id === options.getSelectedId();
|
||||
|
||||
button.type = "button";
|
||||
button.className = "wallets__wallet-button";
|
||||
button.setAttribute("aria-pressed", selected ? "true" : "false");
|
||||
button.setAttribute("data-wallet-id", wallet.id);
|
||||
button.append(wallet.name);
|
||||
button.addEventListener("click", () => {
|
||||
options.onSelect(wallet.id);
|
||||
});
|
||||
walletList.append(button);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {HTMLElement} walletList
|
||||
* @param {WalletSelectorOptions} options
|
||||
*/
|
||||
export function createSelector(walletList, options) {
|
||||
function selectSnappedWallet() {
|
||||
const buttons = [...walletList.querySelectorAll(".wallets__wallet-button")];
|
||||
|
||||
if (buttons.length === 0) return;
|
||||
|
||||
const listRect = walletList.getBoundingClientRect();
|
||||
const listCenter = listRect.left + listRect.width / 2;
|
||||
const closest = buttons.reduce((best, button) => {
|
||||
const rect = button.getBoundingClientRect();
|
||||
const center = rect.left + rect.width / 2;
|
||||
const distance = Math.abs(center - listCenter);
|
||||
|
||||
return distance < best.distance
|
||||
? { button, distance }
|
||||
: best;
|
||||
}, {
|
||||
button: buttons[0],
|
||||
distance: Number.POSITIVE_INFINITY,
|
||||
});
|
||||
const id = closest.button.getAttribute("data-wallet-id");
|
||||
|
||||
if (id && id !== options.getSelectedId()) {
|
||||
options.onSelect(id);
|
||||
}
|
||||
}
|
||||
|
||||
walletList.addEventListener("scrollend", () => {
|
||||
selectSnappedWallet();
|
||||
});
|
||||
|
||||
walletList.addEventListener("wheel", (event) => {
|
||||
const delta = Math.abs(event.deltaX) > Math.abs(event.deltaY)
|
||||
? event.deltaX
|
||||
: event.deltaY;
|
||||
|
||||
if (delta === 0) return;
|
||||
|
||||
const maxScrollLeft = walletList.scrollWidth - walletList.clientWidth;
|
||||
const nextScrollLeft = Math.max(
|
||||
0,
|
||||
Math.min(maxScrollLeft, walletList.scrollLeft + delta),
|
||||
);
|
||||
|
||||
if (nextScrollLeft === walletList.scrollLeft) return;
|
||||
|
||||
event.preventDefault();
|
||||
walletList.scrollLeft = nextScrollLeft;
|
||||
}, { passive: false });
|
||||
|
||||
return {
|
||||
clear() {
|
||||
walletList.replaceChildren();
|
||||
},
|
||||
/**
|
||||
* @param {StoredWallet[]} wallets
|
||||
*/
|
||||
render(wallets) {
|
||||
renderButtons(walletList, wallets, options);
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
main.wallets {
|
||||
.wallets__selector {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.wallets__wallet-list {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
min-width: 0;
|
||||
overflow-x: auto;
|
||||
padding-bottom: 0.25rem;
|
||||
overscroll-behavior-inline: contain;
|
||||
scroll-padding-inline: var(--page-x);
|
||||
scroll-snap-type: x proximity;
|
||||
}
|
||||
|
||||
.wallets__wallet-button {
|
||||
flex: 0 0 auto;
|
||||
scroll-snap-align: center;
|
||||
border: 0;
|
||||
padding: 0;
|
||||
color: var(--white);
|
||||
background: transparent;
|
||||
font-family: var(--font-serif);
|
||||
font-size: 4rem;
|
||||
font-weight: 400;
|
||||
line-height: 1;
|
||||
opacity: 0.48;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.wallets__wallet-button[aria-pressed="true"] {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.wallets__wallet-button:focus-visible {
|
||||
outline: 2px solid var(--orange);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 56rem) {
|
||||
main.wallets {
|
||||
.wallets__wallet-button {
|
||||
font-size: 3rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 34rem) {
|
||||
main.wallets {
|
||||
.wallets__wallet-button {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user