mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-04-25 07:09:59 -07:00
global: snapshot
This commit is contained in:
@@ -1,70 +1,45 @@
|
||||
/**
|
||||
* Reduce color opacity to 50% for dimming effect
|
||||
* @param {string} color - oklch color string
|
||||
*/
|
||||
export function tameColor(color) {
|
||||
if (color === "transparent") return color;
|
||||
return `${color.slice(0, -1)} / 50%)`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} ColorMethods
|
||||
* @property {() => string} tame - Returns tamed (50% opacity) version
|
||||
* @property {(highlighted: boolean) => string} highlight - Returns normal if highlighted, tamed otherwise
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {(() => string) & ColorMethods} Color
|
||||
*/
|
||||
|
||||
/**
|
||||
* Creates a Color object that is callable and has utility methods
|
||||
* @param {() => string} getter
|
||||
* @returns {Color}
|
||||
*/
|
||||
function createColor(getter) {
|
||||
const color = /** @type {Color} */ (() => getter());
|
||||
color.tame = () => tameColor(getter());
|
||||
color.highlight = (highlighted) => highlighted ? getter() : tameColor(getter());
|
||||
return color;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Accessor<boolean>} dark
|
||||
*/
|
||||
export function createColors(dark) {
|
||||
const globalComputedStyle = getComputedStyle(window.document.documentElement);
|
||||
|
||||
/**
|
||||
* @param {string} color
|
||||
* @param {string} name
|
||||
*/
|
||||
function getColor(color) {
|
||||
return globalComputedStyle.getPropertyValue(`--${color}`);
|
||||
}
|
||||
function red() {
|
||||
return getColor("red");
|
||||
}
|
||||
function orange() {
|
||||
return getColor("orange");
|
||||
}
|
||||
function amber() {
|
||||
return getColor("amber");
|
||||
}
|
||||
function yellow() {
|
||||
return getColor("yellow");
|
||||
}
|
||||
function avocado() {
|
||||
return getColor("avocado");
|
||||
}
|
||||
function lime() {
|
||||
return getColor("lime");
|
||||
}
|
||||
function green() {
|
||||
return getColor("green");
|
||||
}
|
||||
function emerald() {
|
||||
return getColor("emerald");
|
||||
}
|
||||
function teal() {
|
||||
return getColor("teal");
|
||||
}
|
||||
function cyan() {
|
||||
return getColor("cyan");
|
||||
}
|
||||
function sky() {
|
||||
return getColor("sky");
|
||||
}
|
||||
function blue() {
|
||||
return getColor("blue");
|
||||
}
|
||||
function indigo() {
|
||||
return getColor("indigo");
|
||||
}
|
||||
function violet() {
|
||||
return getColor("violet");
|
||||
}
|
||||
function purple() {
|
||||
return getColor("purple");
|
||||
}
|
||||
function fuchsia() {
|
||||
return getColor("fuchsia");
|
||||
}
|
||||
function pink() {
|
||||
return getColor("pink");
|
||||
}
|
||||
function rose() {
|
||||
return getColor("rose");
|
||||
}
|
||||
function gray() {
|
||||
return getColor("gray");
|
||||
function getColor(name) {
|
||||
return globalComputedStyle.getPropertyValue(`--${name}`);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -76,41 +51,33 @@ export function createColors(dark) {
|
||||
return dark() ? _dark : light;
|
||||
}
|
||||
|
||||
function textColor() {
|
||||
return getLightDarkValue("--color");
|
||||
}
|
||||
function borderColor() {
|
||||
return getLightDarkValue("--border-color");
|
||||
}
|
||||
|
||||
return {
|
||||
default: textColor,
|
||||
gray,
|
||||
border: borderColor,
|
||||
default: createColor(() => getLightDarkValue("--color")),
|
||||
gray: createColor(() => getColor("gray")),
|
||||
border: createColor(() => getLightDarkValue("--border-color")),
|
||||
|
||||
red,
|
||||
orange,
|
||||
amber,
|
||||
yellow,
|
||||
avocado,
|
||||
lime,
|
||||
green,
|
||||
emerald,
|
||||
teal,
|
||||
cyan,
|
||||
sky,
|
||||
blue,
|
||||
indigo,
|
||||
violet,
|
||||
purple,
|
||||
fuchsia,
|
||||
pink,
|
||||
rose,
|
||||
red: createColor(() => getColor("red")),
|
||||
orange: createColor(() => getColor("orange")),
|
||||
amber: createColor(() => getColor("amber")),
|
||||
yellow: createColor(() => getColor("yellow")),
|
||||
avocado: createColor(() => getColor("avocado")),
|
||||
lime: createColor(() => getColor("lime")),
|
||||
green: createColor(() => getColor("green")),
|
||||
emerald: createColor(() => getColor("emerald")),
|
||||
teal: createColor(() => getColor("teal")),
|
||||
cyan: createColor(() => getColor("cyan")),
|
||||
sky: createColor(() => getColor("sky")),
|
||||
blue: createColor(() => getColor("blue")),
|
||||
indigo: createColor(() => getColor("indigo")),
|
||||
violet: createColor(() => getColor("violet")),
|
||||
purple: createColor(() => getColor("purple")),
|
||||
fuchsia: createColor(() => getColor("fuchsia")),
|
||||
pink: createColor(() => getColor("pink")),
|
||||
rose: createColor(() => getColor("rose")),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {ReturnType<typeof createColors>} Colors
|
||||
* @typedef {Colors["orange"]} Color
|
||||
* @typedef {keyof Colors} ColorName
|
||||
*/
|
||||
|
||||
@@ -215,15 +215,13 @@ export function importStyle(href) {
|
||||
/**
|
||||
* @template T
|
||||
* @param {Object} args
|
||||
* @param {T} args.defaultValue
|
||||
* @param {T} args.defaultValue - Fallback when selected value is no longer in choices
|
||||
* @param {string} [args.id]
|
||||
* @param {readonly T[] | Accessor<readonly T[]>} args.choices
|
||||
* @param {string} [args.keyPrefix]
|
||||
* @param {string} [args.key]
|
||||
* @param {boolean} [args.sorted]
|
||||
* @param {Signals} args.signals
|
||||
* @param {Signal<T>} [args.signal] - Optional external signal to use instead of creating one
|
||||
* @param {(choice: T) => string} [args.toKey] - Extract string key for storage (defaults to identity for strings)
|
||||
* @param {Signal<T>} args.selected
|
||||
* @param {(choice: T) => string} [args.toKey] - Extract string key (defaults to identity for strings)
|
||||
* @param {(choice: T) => string} [args.toLabel] - Extract display label (defaults to identity for strings)
|
||||
* @param {"radio" | "select"} [args.type] - Render as radio buttons or select dropdown
|
||||
*/
|
||||
@@ -231,10 +229,8 @@ export function createChoiceField({
|
||||
id,
|
||||
choices: unsortedChoices,
|
||||
defaultValue,
|
||||
keyPrefix,
|
||||
key,
|
||||
signals,
|
||||
signal: externalSignal,
|
||||
selected,
|
||||
sorted,
|
||||
toKey = /** @type {(choice: T) => string} */ ((/** @type {any} */ c) => c),
|
||||
toLabel = /** @type {(choice: T) => string} */ ((/** @type {any} */ c) => c),
|
||||
@@ -260,25 +256,8 @@ export function createChoiceField({
|
||||
: c;
|
||||
});
|
||||
|
||||
/**
|
||||
* @param {string} storedKey
|
||||
* @returns {T}
|
||||
*/
|
||||
function fromKey(storedKey) {
|
||||
const found = choices().find((c) => toKey(c) === storedKey);
|
||||
return found ?? defaultValue;
|
||||
}
|
||||
|
||||
/** @type {Signal<T>} */
|
||||
const selected = externalSignal ?? signals.createSignal(defaultValue, {
|
||||
save: {
|
||||
serialize: (v) => toKey(v),
|
||||
deserialize: (s) => fromKey(s),
|
||||
keyPrefix: keyPrefix ?? "",
|
||||
key: key ?? "",
|
||||
saveDefaultValue: true,
|
||||
},
|
||||
});
|
||||
/** @param {string} key */
|
||||
const fromKey = (key) => choices().find((c) => toKey(c) === key) ?? defaultValue;
|
||||
|
||||
const field = window.document.createElement("div");
|
||||
field.classList.add("field");
|
||||
@@ -317,8 +296,8 @@ export function createChoiceField({
|
||||
}
|
||||
} else if (type === "select") {
|
||||
const select = window.document.createElement("select");
|
||||
select.id = id ?? key ?? "";
|
||||
select.name = id ?? key ?? "";
|
||||
select.id = id ?? "";
|
||||
select.name = id ?? "";
|
||||
|
||||
choices.forEach((choice) => {
|
||||
const option = window.document.createElement("option");
|
||||
@@ -346,7 +325,7 @@ export function createChoiceField({
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const fieldId = id ?? key ?? "";
|
||||
const fieldId = id ?? "";
|
||||
choices.forEach((choice) => {
|
||||
const choiceKey = toKey(choice);
|
||||
const choiceLabel = toLabel(choice);
|
||||
@@ -372,7 +351,7 @@ export function createChoiceField({
|
||||
}
|
||||
});
|
||||
|
||||
return { field, selected };
|
||||
return field;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -104,10 +104,8 @@ export const serdeBool = {
|
||||
deserialize(v) {
|
||||
if (v === "true" || v === "1") {
|
||||
return true;
|
||||
} else if (v === "false" || v === "0") {
|
||||
return false;
|
||||
} else {
|
||||
throw "deser bool err";
|
||||
return false;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,25 +1,3 @@
|
||||
/**
|
||||
* @param {string} key
|
||||
*/
|
||||
export function readStoredNumber(key) {
|
||||
const saved = readStored(key);
|
||||
if (saved) {
|
||||
return Number(saved);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} key
|
||||
*/
|
||||
export function readStoredBool(key) {
|
||||
const saved = readStored(key);
|
||||
if (saved) {
|
||||
return saved === "true" || saved === "1";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} key
|
||||
*/
|
||||
|
||||
@@ -3,10 +3,12 @@
|
||||
*/
|
||||
function processPathname(pathname) {
|
||||
pathname ||= window.location.pathname;
|
||||
return Array.isArray(pathname) ? pathname.join("/") : pathname;
|
||||
const result = Array.isArray(pathname) ? pathname.join("/") : pathname;
|
||||
// Strip leading slash to avoid double slashes when prepending /
|
||||
return result.startsWith("/") ? result.slice(1) : result;
|
||||
}
|
||||
|
||||
const chartParamsWhitelist = ["from", "to"];
|
||||
const chartParamsWhitelist = ["range"];
|
||||
|
||||
/**
|
||||
* @param {string | string[]} pathname
|
||||
@@ -16,7 +18,6 @@ export function pushHistory(pathname) {
|
||||
pathname = processPathname(pathname);
|
||||
try {
|
||||
const url = `/${pathname}?${urlParams.toString()}`;
|
||||
console.log(`push history: ${url}`);
|
||||
window.history.pushState(null, "", url);
|
||||
} catch (_) {}
|
||||
}
|
||||
@@ -31,7 +32,6 @@ export function replaceHistory({ urlParams, pathname }) {
|
||||
pathname = processPathname(pathname);
|
||||
try {
|
||||
const url = `/${pathname}?${urlParams.toString()}`;
|
||||
console.log(`replace history: ${url}`);
|
||||
window.history.replaceState(null, "", url);
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user