website_next: part 9

This commit is contained in:
nym21
2026-07-08 11:24:52 +02:00
parent 15fbdc168f
commit a43b00c12c
48 changed files with 1756 additions and 1042 deletions
+140
View File
@@ -0,0 +1,140 @@
import { createBrand } from "../../../brand/index.js";
import { openDialog } from "../../../dialog/index.js";
import { getCoinbaseMessage } from "../format.js";
import { createBlockUrl, getReceiptSections } from "./data.js";
import { createReceiptQr } from "./qr.js";
import { createBlockTitle } from "../title/index.js";
/** @typedef {import("../../../modules/brk-client/index.js").BlockInfoV1} Block */
/** @typedef {import("./data.js").ReceiptRow} ReceiptRow */
/** @typedef {import("./data.js").ReceiptSection} ReceiptSection */
/** @param {ReceiptRow} data */
function createReceiptRow(data) {
const row = document.createElement("div");
const name = document.createElement("span");
const amount = document.createElement("strong");
row.dataset.receiptRow = data.variant ?? (data.detail ? "amount" : "");
name.textContent = data.label;
amount.textContent = data.value;
if (data.detail) {
const detail = document.createElement("small");
detail.textContent = data.detail;
amount.append(detail);
}
row.append(name, amount);
return row;
}
/** @param {ReceiptSection} data */
function createReceiptSection(data) {
const section = document.createElement("section");
const heading = document.createElement("h3");
section.dataset.receiptSection = "";
heading.textContent = data.title;
section.append(heading, ...data.rows.map(createReceiptRow));
return section;
}
/** @param {string} message */
function createCoinbaseNote(message) {
const note = document.createElement("p");
note.dataset.receiptNote = "";
note.textContent = message;
return note;
}
/** @param {Block} block */
function createReceiptHead(block) {
const head = document.createElement("header");
const title = document.createElement("h2");
head.dataset.receiptHead = "";
title.dataset.blockTitleText = "";
title.append(...createBlockTitle(block.height));
head.append(title);
return head;
}
function createReceiptBrand() {
const section = document.createElement("section");
section.dataset.receiptBrand = "";
section.append(createBrand({ tone: "receipt", fill: 1 }));
return section;
}
/** @param {Block} block */
function openReceiptDialog(block) {
const dialog = document.createElement("dialog");
const paper = document.createElement("article");
const controls = document.createElement("footer");
const print = document.createElement("button");
const closeForm = document.createElement("form");
const close = document.createElement("button");
const url = createBlockUrl(block);
const coinbase = getCoinbaseMessage(block.extras.coinbaseSignatureAscii);
dialog.dataset.blockReceipt = "";
dialog.tabIndex = -1;
paper.dataset.receiptPaper = "";
controls.dataset.receiptControls = "";
print.type = "button";
print.dataset.receiptAction = "print";
print.textContent = "Print";
closeForm.method = "dialog";
close.type = "submit";
close.dataset.receiptAction = "close";
close.textContent = "Close";
closeForm.append(close);
controls.append(closeForm, print);
paper.append(
createReceiptHead(block),
...getReceiptSections(block).map(createReceiptSection),
...(coinbase ? [createCoinbaseNote(coinbase)] : []),
createReceiptQr(block, url),
createReceiptBrand(),
);
dialog.append(paper, controls);
print.addEventListener("click", () => {
window.print();
});
openDialog(dialog, document.body);
dialog.focus({ preventScroll: true });
dialog.scrollTop = 0;
}
export function createBlockReceipt() {
const button = document.createElement("button");
/** @type {Block | null} */
let block = null;
button.type = "button";
button.disabled = true;
button.dataset.receiptButton = "";
button.textContent = "Receipt";
button.addEventListener("click", () => {
if (block) openReceiptDialog(block);
});
/** @param {Block} nextBlock */
function update(nextBlock) {
block = nextBlock;
button.disabled = false;
}
return /** @type {const} */ ({
button,
update,
});
}
+2 -15
View File
@@ -23,7 +23,6 @@ dialog[data-block-receipt] {
translate: none;
:is(
[data-receipt-head] > h2,
[data-receipt-section] > h3,
[data-receipt-row] > span,
[data-receipt-row] > strong,
@@ -60,9 +59,11 @@ dialog[data-block-receipt] {
}
[data-receipt-head] {
--block-title-color: var(--black);
--block-title-height-color: color-mix(in oklch, var(--black) 62%, transparent);
--block-title-height-line-height: var(--line-height-base);
--block-title-height-size: var(--font-size-base);
--block-title-justify: center;
--block-title-label-size: 1.375rem;
display: grid;
@@ -71,19 +72,6 @@ dialog[data-block-receipt] {
justify-items: center;
margin-block-start: 0.5rem;
text-align: center;
> h2 {
display: flex;
flex-wrap: wrap;
gap: 0.35em;
align-items: baseline;
justify-content: center;
min-width: 0;
color: var(--black);
font-family: var(--font-mono);
font-weight: var(--font-weight-regular);
line-height: 1;
}
}
[data-receipt-section] {
@@ -303,7 +291,6 @@ dialog[data-block-receipt] {
}
dialog[data-block-receipt] :is(
[data-receipt-head] > h2,
[data-receipt-row] > span,
[data-receipt-row] > strong,
[data-receipt-row] small,