mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-06-08 14:11:56 -07:00
website: snapshot
This commit is contained in:
Generated
+2
-2
@@ -1749,9 +1749,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "importmap"
|
||||
version = "0.3.0"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9995d103127daa52df1cd851c1bc9d8b023e4591ca4bdb47836b821499ab35f9"
|
||||
checksum = "7e2d16f9503f27ae2f80f4914e81c98ab8e9921fe951e450936d1eaeaae9e8d0"
|
||||
dependencies = [
|
||||
"include_dir",
|
||||
"rapidhash",
|
||||
|
||||
@@ -11,7 +11,7 @@ include = ["src/**/*", "website/**/*", "examples/**/*", "Cargo.toml", "README.md
|
||||
[dependencies]
|
||||
axum = { workspace = true }
|
||||
include_dir = "0.7"
|
||||
importmap = { version = "0.3.0", features = ["embedded"] }
|
||||
importmap = { version = "0.3.1", features = ["embedded"] }
|
||||
tracing = { workspace = true }
|
||||
|
||||
[dev-dependencies]
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
import { createLegend } from "./legend.js";
|
||||
import { capture } from "./capture.js";
|
||||
import { colors } from "./colors.js";
|
||||
import { createChoiceField } from "../utils/dom.js";
|
||||
import { createRadios, createSelect } from "../utils/dom.js";
|
||||
import { createPersistedValue } from "../utils/persisted.js";
|
||||
import { onChange as onThemeChange } from "../utils/theme.js";
|
||||
import { throttle, debounce } from "../utils/timing.js";
|
||||
@@ -1289,7 +1289,7 @@ export function createChart({
|
||||
paneIndex,
|
||||
position: "sw",
|
||||
createChild() {
|
||||
const field = createChoiceField({
|
||||
return createRadios({
|
||||
choices: /** @type {const} */ (["lin", "log"]),
|
||||
id: stringToId(`${id} ${paneIndex}`),
|
||||
initialValue: persisted.value,
|
||||
@@ -1298,8 +1298,6 @@ export function createChart({
|
||||
applyScale(value);
|
||||
},
|
||||
});
|
||||
|
||||
return field;
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -1481,13 +1479,12 @@ export function createChart({
|
||||
paneIndex,
|
||||
position: "nw",
|
||||
createChild() {
|
||||
return createChoiceField({
|
||||
return createSelect({
|
||||
choices: units,
|
||||
id: `pane-${paneIndex}-unit`,
|
||||
initialValue: blueprints.panes[paneIndex].unit ?? defaultUnit,
|
||||
toKey: (u) => u.id,
|
||||
toLabel: (u) => u.name,
|
||||
type: "select",
|
||||
sorted: true,
|
||||
onChange(unit) {
|
||||
persistedUnit.set(unit.id);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { createShadow, createChoiceField, createHeader } from "../utils/dom.js";
|
||||
import { createShadow, createRadios, createHeader } from "../utils/dom.js";
|
||||
import { chartElement } from "../utils/elements.js";
|
||||
import { serdeChartableIndex } from "../utils/serde.js";
|
||||
import { Unit } from "../utils/units.js";
|
||||
@@ -176,7 +176,7 @@ function createIndexSelector(chart) {
|
||||
chart.index.name.set(currentValue);
|
||||
}
|
||||
|
||||
field = createChoiceField({
|
||||
field = createRadios({
|
||||
initialValue: currentValue,
|
||||
onChange: (v) => {
|
||||
preferredIndex = v; // User explicitly selected, update preference
|
||||
|
||||
@@ -221,23 +221,15 @@ export function importStyle(href) {
|
||||
* @param {(value: T) => void} [args.onChange]
|
||||
* @param {(choice: T) => string} [args.toKey]
|
||||
* @param {(choice: T) => string} [args.toLabel]
|
||||
* @param {"radio" | "select"} [args.type]
|
||||
* @param {boolean} [args.sorted]
|
||||
*/
|
||||
export function createChoiceField({
|
||||
export function createRadios({
|
||||
id,
|
||||
choices: unsortedChoices,
|
||||
choices,
|
||||
initialValue,
|
||||
onChange,
|
||||
sorted,
|
||||
toKey = /** @type {(choice: T) => string} */ ((/** @type {any} */ c) => c),
|
||||
toLabel = /** @type {(choice: T) => string} */ ((/** @type {any} */ c) => c),
|
||||
type = "radio",
|
||||
}) {
|
||||
const choices = sorted
|
||||
? unsortedChoices.toSorted((a, b) => toLabel(a).localeCompare(toLabel(b)))
|
||||
: unsortedChoices;
|
||||
|
||||
const field = window.document.createElement("div");
|
||||
field.classList.add("field");
|
||||
|
||||
@@ -254,33 +246,6 @@ export function createChoiceField({
|
||||
const span = window.document.createElement("span");
|
||||
span.textContent = toLabel(choices[0]);
|
||||
div.append(span);
|
||||
} else if (type === "select") {
|
||||
const select = window.document.createElement("select");
|
||||
select.id = id ?? "";
|
||||
select.name = id ?? "";
|
||||
|
||||
choices.forEach((choice) => {
|
||||
const option = window.document.createElement("option");
|
||||
option.value = toKey(choice);
|
||||
option.textContent = toLabel(choice);
|
||||
if (toKey(choice) === initialKey) {
|
||||
option.selected = true;
|
||||
}
|
||||
select.append(option);
|
||||
});
|
||||
|
||||
select.addEventListener("change", () => {
|
||||
onChange?.(fromKey(select.value));
|
||||
});
|
||||
|
||||
div.append(select);
|
||||
|
||||
const remaining = choices.length - 1;
|
||||
if (remaining > 0) {
|
||||
const small = window.document.createElement("small");
|
||||
small.textContent = ` +${remaining}`;
|
||||
field.append(small);
|
||||
}
|
||||
} else {
|
||||
const fieldId = id ?? "";
|
||||
choices.forEach((choice) => {
|
||||
@@ -308,6 +273,57 @@ export function createChoiceField({
|
||||
return field;
|
||||
}
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @param {Object} args
|
||||
* @param {T} args.initialValue
|
||||
* @param {string} [args.id]
|
||||
* @param {readonly T[]} args.choices
|
||||
* @param {(value: T) => void} [args.onChange]
|
||||
* @param {(choice: T) => string} [args.toKey]
|
||||
* @param {(choice: T) => string} [args.toLabel]
|
||||
* @param {boolean} [args.sorted]
|
||||
*/
|
||||
export function createSelect({
|
||||
id,
|
||||
choices: unsortedChoices,
|
||||
initialValue,
|
||||
onChange,
|
||||
sorted,
|
||||
toKey = /** @type {(choice: T) => string} */ ((/** @type {any} */ c) => c),
|
||||
toLabel = /** @type {(choice: T) => string} */ ((/** @type {any} */ c) => c),
|
||||
}) {
|
||||
const choices = sorted
|
||||
? unsortedChoices.toSorted((a, b) => toLabel(a).localeCompare(toLabel(b)))
|
||||
: unsortedChoices;
|
||||
|
||||
const select = window.document.createElement("select");
|
||||
select.id = id ?? "";
|
||||
select.name = id ?? "";
|
||||
|
||||
const initialKey = toKey(initialValue);
|
||||
|
||||
/** @param {string} key */
|
||||
const fromKey = (key) =>
|
||||
choices.find((c) => toKey(c) === key) ?? initialValue;
|
||||
|
||||
choices.forEach((choice) => {
|
||||
const option = window.document.createElement("option");
|
||||
option.value = toKey(choice);
|
||||
option.textContent = toLabel(choice);
|
||||
if (toKey(choice) === initialKey) {
|
||||
option.selected = true;
|
||||
}
|
||||
select.append(option);
|
||||
});
|
||||
|
||||
select.addEventListener("change", () => {
|
||||
onChange?.(fromKey(select.value));
|
||||
});
|
||||
|
||||
return select;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} [title]
|
||||
* @param {1 | 2 | 3} [level]
|
||||
@@ -344,67 +360,6 @@ export function createOption(arg) {
|
||||
return option;
|
||||
}
|
||||
|
||||
/**
|
||||
* @template {string} Name
|
||||
* @template {string} Value
|
||||
* @template {Value | {name: Name; value: Value}} T
|
||||
* @param {Object} args
|
||||
* @param {string} [args.id]
|
||||
* @param {boolean} [args.deep]
|
||||
* @param {readonly ((T) | {name: string; list: T[]})[]} args.list
|
||||
* @param {Signal<T>} args.signal
|
||||
*/
|
||||
export function createSelect({ id, list, signal, deep = false }) {
|
||||
const select = window.document.createElement("select");
|
||||
|
||||
if (id) {
|
||||
select.name = id;
|
||||
select.id = id;
|
||||
}
|
||||
|
||||
/** @type {Record<string, VoidFunction>} */
|
||||
const setters = {};
|
||||
|
||||
list.forEach((anyOption, index) => {
|
||||
if (typeof anyOption === "object" && "list" in anyOption) {
|
||||
const { name, list } = anyOption;
|
||||
const optGroup = window.document.createElement("optgroup");
|
||||
optGroup.label = name;
|
||||
select.append(optGroup);
|
||||
list.forEach((option) => {
|
||||
optGroup.append(createOption(option));
|
||||
const key = /** @type {string} */ (
|
||||
typeof option === "object" ? option.value : option
|
||||
);
|
||||
setters[key] = () => signal.set(() => option);
|
||||
});
|
||||
} else {
|
||||
select.append(createOption(anyOption));
|
||||
const key = /** @type {string} */ (
|
||||
typeof anyOption === "object" ? anyOption.value : anyOption
|
||||
);
|
||||
setters[key] = () => signal.set(() => anyOption);
|
||||
}
|
||||
if (deep && index !== list.length - 1) {
|
||||
select.append(window.document.createElement("hr"));
|
||||
}
|
||||
});
|
||||
|
||||
select.addEventListener("change", () => {
|
||||
const callback = setters[select.value];
|
||||
// @ts-ignore
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
|
||||
const initialSignal = signal();
|
||||
const initialValue =
|
||||
typeof initialSignal === "object" ? initialSignal.value : initialSignal;
|
||||
select.value = String(initialValue);
|
||||
|
||||
return { select, signal };
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} args
|
||||
|
||||
Reference in New Issue
Block a user