mevebu 1.2.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/mevebu/app/mevebu.js +260 -208
- package/mevebu/app/tailwind.css +1639 -2077
- package/mevebu/app/tailwind.src.css +155 -1120
- package/mevebu/index.html +2 -2
- package/mevebu/libs/js/core.js +236 -96
- package/mevebu/libs/js/registry.js +11 -11
- package/mevebu/libs/js/tools/abstract-checklist.js +5 -7
- package/mevebu/libs/js/tools/add-subtract-days.js +9 -11
- package/mevebu/libs/js/tools/age-calculator.js +7 -8
- package/mevebu/libs/js/tools/api-request-builder.js +3 -4
- package/mevebu/libs/js/tools/area-converter.js +7 -9
- package/mevebu/libs/js/tools/aspect-ratio.js +8 -9
- package/mevebu/libs/js/tools/average-calculator.js +4 -5
- package/mevebu/libs/js/tools/base64.js +31 -11
- package/mevebu/libs/js/tools/binary-calculator.js +6 -7
- package/mevebu/libs/js/tools/border-radius.js +7 -9
- package/mevebu/libs/js/tools/box-shadow.js +6 -7
- package/mevebu/libs/js/tools/break-even.js +4 -5
- package/mevebu/libs/js/tools/business-days.js +7 -8
- package/mevebu/libs/js/tools/canonical-tag.js +5 -6
- package/mevebu/libs/js/tools/caption-counter.js +5 -7
- package/mevebu/libs/js/tools/case-converter.js +11 -12
- package/mevebu/libs/js/tools/case-inspector.js +14 -16
- package/mevebu/libs/js/tools/cash-denomination.js +7 -8
- package/mevebu/libs/js/tools/cash-flow.js +7 -8
- package/mevebu/libs/js/tools/cert-expiry.js +6 -10
- package/mevebu/libs/js/tools/changelog-generator.js +4 -6
- package/mevebu/libs/js/tools/character-counter.js +10 -13
- package/mevebu/libs/js/tools/checklist.js +6 -7
- package/mevebu/libs/js/tools/citation-number-check.js +10 -13
- package/mevebu/libs/js/tools/coin-flip.js +9 -11
- package/mevebu/libs/js/tools/color-converter.js +23 -17
- package/mevebu/libs/js/tools/color-palette.js +6 -8
- package/mevebu/libs/js/tools/color-picker.js +4 -5
- package/mevebu/libs/js/tools/content-calendar.js +3 -4
- package/mevebu/libs/js/tools/contrast-checker.js +5 -6
- package/mevebu/libs/js/tools/cron-builder.js +4 -6
- package/mevebu/libs/js/tools/css-clamp.js +5 -6
- package/mevebu/libs/js/tools/css-formatter.js +4 -7
- package/mevebu/libs/js/tools/css-grid.js +6 -7
- package/mevebu/libs/js/tools/css-minifier.js +5 -8
- package/mevebu/libs/js/tools/csv-to-json.js +2 -3
- package/mevebu/libs/js/tools/csv-viewer.js +9 -11
- package/mevebu/libs/js/tools/currency-format.js +5 -7
- package/mevebu/libs/js/tools/daily-planner.js +9 -10
- package/mevebu/libs/js/tools/data-masker.js +7 -9
- package/mevebu/libs/js/tools/data-storage.js +7 -9
- package/mevebu/libs/js/tools/data-validator.js +9 -11
- package/mevebu/libs/js/tools/date-difference.js +6 -7
- package/mevebu/libs/js/tools/date-format.js +11 -13
- package/mevebu/libs/js/tools/delimiter-converter.js +3 -5
- package/mevebu/libs/js/tools/discount-calculator.js +4 -5
- package/mevebu/libs/js/tools/doi-resolver.js +4 -5
- package/mevebu/libs/js/tools/env-formatter.js +3 -6
- package/mevebu/libs/js/tools/equation-formatter.js +5 -9
- package/mevebu/libs/js/tools/expense-split.js +6 -7
- package/mevebu/libs/js/tools/fake-data.js +20 -13
- package/mevebu/libs/js/tools/find-replace.js +3 -5
- package/mevebu/libs/js/tools/flashcard-creator.js +9 -10
- package/mevebu/libs/js/tools/font-pairing.js +6 -8
- package/mevebu/libs/js/tools/fraction-calculator.js +10 -13
- package/mevebu/libs/js/tools/git-command-builder.js +11 -22
- package/mevebu/libs/js/tools/gpa-calculator.js +8 -10
- package/mevebu/libs/js/tools/grade-calculator.js +7 -8
- package/mevebu/libs/js/tools/gradient-generator.js +10 -12
- package/mevebu/libs/js/tools/habit-tracker.js +8 -9
- package/mevebu/libs/js/tools/hash-generator.js +3 -5
- package/mevebu/libs/js/tools/hashtag-formatter.js +6 -8
- package/mevebu/libs/js/tools/hmac-generator.js +3 -5
- package/mevebu/libs/js/tools/hpp-calculator.js +4 -5
- package/mevebu/libs/js/tools/html-entity.js +2 -3
- package/mevebu/libs/js/tools/html-formatter.js +3 -6
- package/mevebu/libs/js/tools/http-status.js +5 -7
- package/mevebu/libs/js/tools/inventory-quantity.js +7 -8
- package/mevebu/libs/js/tools/json-formatter.js +3 -6
- package/mevebu/libs/js/tools/json-minifier.js +5 -8
- package/mevebu/libs/js/tools/json-to-csv.js +3 -5
- package/mevebu/libs/js/tools/json-to-typescript.js +2 -5
- package/mevebu/libs/js/tools/json-validator.js +2 -3
- package/mevebu/libs/js/tools/jwt-decoder.js +6 -7
- package/mevebu/libs/js/tools/jwt-expiry.js +5 -6
- package/mevebu/libs/js/tools/jwt-generator.js +4 -6
- package/mevebu/libs/js/tools/length-converter.js +7 -9
- package/mevebu/libs/js/tools/license-reference.js +10 -13
- package/mevebu/libs/js/tools/line-counter.js +5 -7
- package/mevebu/libs/js/tools/list-difference.js +5 -7
- package/mevebu/libs/js/tools/list-merger.js +4 -5
- package/mevebu/libs/js/tools/locale-number.js +5 -8
- package/mevebu/libs/js/tools/lorem-ipsum.js +4 -2
- package/mevebu/libs/js/tools/markdown-preview.js +5 -8
- package/mevebu/libs/js/tools/markdown-table.js +5 -7
- package/mevebu/libs/js/tools/markup-calculator.js +4 -5
- package/mevebu/libs/js/tools/meeting-agenda.js +8 -9
- package/mevebu/libs/js/tools/meta-preview.js +12 -13
- package/mevebu/libs/js/tools/meta-tags.js +6 -7
- package/mevebu/libs/js/tools/mime-types.js +5 -7
- package/mevebu/libs/js/tools/name-picker.js +2 -3
- package/mevebu/libs/js/tools/number-base-converter.js +9 -12
- package/mevebu/libs/js/tools/password-generator.js +9 -12
- package/mevebu/libs/js/tools/password-strength.js +21 -25
- package/mevebu/libs/js/tools/percent-to-fraction.js +6 -7
- package/mevebu/libs/js/tools/percentage-calculator.js +6 -9
- package/mevebu/libs/js/tools/percentage-change.js +4 -5
- package/mevebu/libs/js/tools/permutation-combination.js +9 -12
- package/mevebu/libs/js/tools/prefix-suffix.js +2 -3
- package/mevebu/libs/js/tools/priority-matrix.js +6 -10
- package/mevebu/libs/js/tools/profit-margin.js +4 -5
- package/mevebu/libs/js/tools/qr-generator.js +3 -4
- package/mevebu/libs/js/tools/qr-scanner.js +11 -12
- package/mevebu/libs/js/tools/quadratic-solver.js +7 -8
- package/mevebu/libs/js/tools/query-builder.js +2 -3
- package/mevebu/libs/js/tools/quiz-formatter.js +4 -6
- package/mevebu/libs/js/tools/ratio-calculator.js +7 -8
- package/mevebu/libs/js/tools/readability.js +12 -15
- package/mevebu/libs/js/tools/reading-time.js +5 -7
- package/mevebu/libs/js/tools/reference-completeness.js +6 -8
- package/mevebu/libs/js/tools/regex-tester.js +7 -10
- package/mevebu/libs/js/tools/remove-duplicate-lines.js +2 -3
- package/mevebu/libs/js/tools/remove-extra-spaces.js +3 -5
- package/mevebu/libs/js/tools/robots-txt.js +3 -4
- package/mevebu/libs/js/tools/roman-numeral-converter.js +6 -8
- package/mevebu/libs/js/tools/sales-commission.js +8 -9
- package/mevebu/libs/js/tools/scientific-calculator.js +10 -14
- package/mevebu/libs/js/tools/scientific-notation.js +8 -9
- package/mevebu/libs/js/tools/script-planner.js +8 -10
- package/mevebu/libs/js/tools/selling-price.js +4 -5
- package/mevebu/libs/js/tools/semver-helper.js +3 -5
- package/mevebu/libs/js/tools/sentence-length.js +9 -10
- package/mevebu/libs/js/tools/sequence-analyzer.js +7 -8
- package/mevebu/libs/js/tools/sitemap-xml.js +4 -7
- package/mevebu/libs/js/tools/slug-converter.js +3 -5
- package/mevebu/libs/js/tools/slug-preview.js +6 -7
- package/mevebu/libs/js/tools/sort-lines.js +3 -5
- package/mevebu/libs/js/tools/speed-converter.js +7 -9
- package/mevebu/libs/js/tools/spin-wheel.js +19 -17
- package/mevebu/libs/js/tools/sql-formatter.js +5 -9
- package/mevebu/libs/js/tools/sql-minifier.js +5 -8
- package/mevebu/libs/js/tools/standard-deviation.js +6 -9
- package/mevebu/libs/js/tools/stopwatch.js +4 -6
- package/mevebu/libs/js/tools/study-schedule.js +8 -9
- package/mevebu/libs/js/tools/subtitle-formatter.js +10 -11
- package/mevebu/libs/js/tools/table-to-markdown.js +8 -12
- package/mevebu/libs/js/tools/tax-calculator.js +4 -5
- package/mevebu/libs/js/tools/temperature-converter.js +8 -11
- package/mevebu/libs/js/tools/text-diff.js +11 -7
- package/mevebu/libs/js/tools/text-direction.js +3 -5
- package/mevebu/libs/js/tools/text-reverser.js +3 -5
- package/mevebu/libs/js/tools/time-duration.js +8 -9
- package/mevebu/libs/js/tools/timestamp-converter.js +4 -6
- package/mevebu/libs/js/tools/timezone-converter.js +9 -13
- package/mevebu/libs/js/tools/title-length.js +6 -7
- package/mevebu/libs/js/tools/unicode-inspector.js +4 -5
- package/mevebu/libs/js/tools/url-encoder.js +4 -2
- package/mevebu/libs/js/tools/url-inspector.js +9 -11
- package/mevebu/libs/js/tools/url-parser.js +12 -13
- package/mevebu/libs/js/tools/utf8-bytes.js +6 -9
- package/mevebu/libs/js/tools/uuid-generator.js +107 -15
- package/mevebu/libs/js/tools/version-compare.js +3 -4
- package/mevebu/libs/js/tools/video-duration.js +5 -7
- package/mevebu/libs/js/tools/volume-converter.js +7 -9
- package/mevebu/libs/js/tools/weekly-planner.js +8 -10
- package/mevebu/libs/js/tools/weight-converter.js +7 -9
- package/mevebu/libs/js/tools/weighted-average.js +4 -5
- package/mevebu/libs/js/tools/word-counter.js +10 -13
- package/mevebu/libs/js/tools/word-limit.js +4 -5
- package/mevebu/libs/js/tools/yaml-formatter.js +6 -7
- package/package.json +1 -1
|
@@ -7,8 +7,7 @@ const SCALE = [
|
|
|
7
7
|
["A+", 4.0], ["A", 4.0], ["A-", 3.7],
|
|
8
8
|
["B+", 3.3], ["B", 3.0], ["B-", 2.7],
|
|
9
9
|
["C+", 2.3], ["C", 2.0], ["C-", 1.7],
|
|
10
|
-
["D+", 1.3], ["D", 1.0], ["F", 0.0]
|
|
11
|
-
];
|
|
10
|
+
["D+", 1.3], ["D", 1.0], ["F", 0.0]];
|
|
12
11
|
const POINTS = new Map(SCALE);
|
|
13
12
|
|
|
14
13
|
function fmt(n) {
|
|
@@ -23,15 +22,15 @@ export function mount(slot) {
|
|
|
23
22
|
const name = textInput({ placeholder: "Course", "aria-label": "Course" });
|
|
24
23
|
const credits = numberInput({ min: "0", step: "0.5", placeholder: "Credits", "aria-label": "Credits" });
|
|
25
24
|
const grade = selectInput(SCALE.map(([label]) => ({ value: label, label })), { value: "A", "aria-label": "Grade" });
|
|
26
|
-
const listWrap = el("div", { class: "
|
|
27
|
-
const stats = el("div", { class: "
|
|
25
|
+
const listWrap = el("div", { class: "max-h-80 overflow-auto" });
|
|
26
|
+
const stats = el("div", { class: "grid gap-2.5 [grid-template-columns:repeat(auto-fit,minmax(120px,1fr))]" });
|
|
28
27
|
|
|
29
28
|
const addButton = button("Add", { icon: "plus", kind: "fill" });
|
|
30
29
|
|
|
31
30
|
const save = () => writePin(PIN, list);
|
|
32
|
-
const tile = (key, value) => el("div", { class: "
|
|
33
|
-
el("span", { class: "
|
|
34
|
-
el("span", { class: "
|
|
31
|
+
const tile = (key, value) => el("div", { class: "grid gap-0.5 rounded-r1 border border-orbit bg-deck-2 px-3.5 py-3" },
|
|
32
|
+
el("span", { class: "wrap-anywhere text-xl font-bold tracking-[-0.02em] tabular-nums" }, String(value)),
|
|
33
|
+
el("span", { class: "text-2xs font-semibold text-ink-3" }, key));
|
|
35
34
|
|
|
36
35
|
const totals = () => {
|
|
37
36
|
const totalCredits = list.reduce((sum, item) => sum + item.credits, 0);
|
|
@@ -53,7 +52,7 @@ export function mount(slot) {
|
|
|
53
52
|
if (!list.length) {
|
|
54
53
|
listWrap.replaceChildren(blank("graduation-cap", "No courses yet."));
|
|
55
54
|
} else {
|
|
56
|
-
listWrap.replaceChildren(el("table", { class: "
|
|
55
|
+
listWrap.replaceChildren(el("table", { class: "w-full border-collapse font-mono text-sm [&_th]:wrap-anywhere [&_td]:wrap-anywhere [&_th]:border-b [&_td]:border-b [&_th]:border-orbit [&_td]:border-orbit [&_th]:px-2.5 [&_td]:px-2.5 [&_th]:py-2 [&_td]:py-2 [&_th]:text-start [&_td]:text-start [&_th]:font-sans [&_th]:text-2xs [&_th]:font-semibold [&_th]:text-ink-2 [&_tbody>tr:last-child>th]:border-b-0 [&_tbody>tr:last-child>td]:border-b-0" },
|
|
57
56
|
el("thead", {}, el("tr", {}, el("th", {}, "Course"), el("th", {}, "Credits"), el("th", {}, "Grade"), el("th", {}, ""))),
|
|
58
57
|
el("tbody", {}, ...list.map((item) => el("tr", {},
|
|
59
58
|
el("th", {}, item.name),
|
|
@@ -89,8 +88,7 @@ export function mount(slot) {
|
|
|
89
88
|
foot: actions(copyButton(() => {
|
|
90
89
|
const { totalCredits, gpa } = totals();
|
|
91
90
|
return gpa == null ? "" : `GPA ${fmt(gpa)}, credits ${fmt(totalCredits)}`;
|
|
92
|
-
}, "Copy result"), addButton)
|
|
93
|
-
});
|
|
91
|
+
}, "Copy result"), addButton)});
|
|
94
92
|
slot.append(card.node);
|
|
95
93
|
render();
|
|
96
94
|
|
|
@@ -15,16 +15,16 @@ export function mount(slot) {
|
|
|
15
15
|
const name = textInput({ placeholder: "Component", "aria-label": "Component" });
|
|
16
16
|
const score = numberInput({ min: "0", max: "100", placeholder: "Score", "aria-label": "Score" });
|
|
17
17
|
const weight = numberInput({ min: "0", max: "100", placeholder: "Weight", "aria-label": "Weight" });
|
|
18
|
-
const listWrap = el("div", { class: "
|
|
19
|
-
const stats = el("div", { class: "
|
|
18
|
+
const listWrap = el("div", { class: "max-h-80 overflow-auto" });
|
|
19
|
+
const stats = el("div", { class: "grid gap-2.5 [grid-template-columns:repeat(auto-fit,minmax(120px,1fr))]" });
|
|
20
20
|
const weightNote = notice("warn");
|
|
21
21
|
|
|
22
22
|
const addButton = button("Add", { icon: "plus", kind: "fill" });
|
|
23
23
|
|
|
24
24
|
const save = () => writePin(PIN, list);
|
|
25
|
-
const tile = (key, value) => el("div", { class: "
|
|
26
|
-
el("span", { class: "
|
|
27
|
-
el("span", { class: "
|
|
25
|
+
const tile = (key, value) => el("div", { class: "grid gap-0.5 rounded-r1 border border-orbit bg-deck-2 px-3.5 py-3" },
|
|
26
|
+
el("span", { class: "wrap-anywhere text-xl font-bold tracking-[-0.02em] tabular-nums" }, String(value)),
|
|
27
|
+
el("span", { class: "text-2xs font-semibold text-ink-3" }, key));
|
|
28
28
|
|
|
29
29
|
const totalWeight = () => list.reduce((sum, item) => sum + item.weight, 0);
|
|
30
30
|
const grade = () => {
|
|
@@ -47,7 +47,7 @@ export function mount(slot) {
|
|
|
47
47
|
if (!list.length) {
|
|
48
48
|
listWrap.replaceChildren(blank("graduation-cap", "No components yet."));
|
|
49
49
|
} else {
|
|
50
|
-
listWrap.replaceChildren(el("table", { class: "
|
|
50
|
+
listWrap.replaceChildren(el("table", { class: "w-full border-collapse font-mono text-sm [&_th]:wrap-anywhere [&_td]:wrap-anywhere [&_th]:border-b [&_td]:border-b [&_th]:border-orbit [&_td]:border-orbit [&_th]:px-2.5 [&_td]:px-2.5 [&_th]:py-2 [&_td]:py-2 [&_th]:text-start [&_td]:text-start [&_th]:font-sans [&_th]:text-2xs [&_th]:font-semibold [&_th]:text-ink-2 [&_tbody>tr:last-child>th]:border-b-0 [&_tbody>tr:last-child>td]:border-b-0" },
|
|
51
51
|
el("thead", {}, el("tr", {}, el("th", {}, "Component"), el("th", {}, "Score"), el("th", {}, "Weight"), el("th", {}, ""))),
|
|
52
52
|
el("tbody", {}, ...list.map((item) => el("tr", {},
|
|
53
53
|
el("th", {}, item.name),
|
|
@@ -90,8 +90,7 @@ export function mount(slot) {
|
|
|
90
90
|
foot: actions(copyButton(() => {
|
|
91
91
|
const result = grade();
|
|
92
92
|
return result == null ? "" : `Grade ${fmt(result)}, total weight ${fmt(totalWeight())}%`;
|
|
93
|
-
}, "Copy result"), addButton)
|
|
94
|
-
});
|
|
93
|
+
}, "Copy result"), addButton)});
|
|
95
94
|
slot.append(card.node);
|
|
96
95
|
render();
|
|
97
96
|
|
|
@@ -6,11 +6,10 @@ export function mount(slot) {
|
|
|
6
6
|
let angle = 90;
|
|
7
7
|
const stops = [
|
|
8
8
|
{ color: "#f5b942", pos: 0 },
|
|
9
|
-
{ color: "#8a2be2", pos: 100 }
|
|
10
|
-
];
|
|
9
|
+
{ color: "#8a2be2", pos: 100 }];
|
|
11
10
|
|
|
12
|
-
const stopsBox = el("div", { class: "
|
|
13
|
-
const previewBox = el("div", { class: "
|
|
11
|
+
const stopsBox = el("div", { class: "grid content-start gap-4" });
|
|
12
|
+
const previewBox = el("div", { class: "grid h-[120px] w-[min(200px,100%)] place-items-center bg-jade text-2xs text-on-jade" });
|
|
14
13
|
const code = output();
|
|
15
14
|
|
|
16
15
|
function gradientCss() {
|
|
@@ -30,7 +29,7 @@ export function mount(slot) {
|
|
|
30
29
|
|
|
31
30
|
const range = rangeInput({ min: 0, max: 100, value: stop.pos, "aria-label": "Stop position" });
|
|
32
31
|
range.style.flex = "1";
|
|
33
|
-
const val = el("span", { class: "
|
|
32
|
+
const val = el("span", { class: "text-end font-mono text-2xs text-ink-2" }, `${stop.pos}%`);
|
|
34
33
|
range.addEventListener("input", () => {
|
|
35
34
|
stop.pos = parseInt(range.value, 10) || 0;
|
|
36
35
|
val.textContent = `${stop.pos}%`;
|
|
@@ -45,7 +44,7 @@ export function mount(slot) {
|
|
|
45
44
|
update();
|
|
46
45
|
});
|
|
47
46
|
|
|
48
|
-
return el("div", { class: "
|
|
47
|
+
return el("div", { class: "flex min-w-0 flex-wrap items-center gap-2" }, picker, range, val, remove);
|
|
49
48
|
}
|
|
50
49
|
|
|
51
50
|
function paintStops() {
|
|
@@ -63,11 +62,11 @@ export function mount(slot) {
|
|
|
63
62
|
});
|
|
64
63
|
|
|
65
64
|
const angleInput = rangeInput({ min: 0, max: 360, value: angle, "aria-label": "Angle" });
|
|
66
|
-
const angleVal = el("span", { class: "
|
|
65
|
+
const angleVal = el("span", { class: "text-end font-mono text-2xs text-ink-2" }, `${angle}deg`);
|
|
67
66
|
const angleRow = el(
|
|
68
67
|
"div",
|
|
69
|
-
{ class: "
|
|
70
|
-
el("span", { class: "
|
|
68
|
+
{ class: "grid items-center gap-2.5 [grid-template-columns:88px_minmax(0,1fr)_62px] max-[45rem]:[grid-template-columns:minmax(0,1fr)_62px]" },
|
|
69
|
+
el("span", { class: "text-2xs font-semibold text-ink-2 max-[45rem]:col-span-2" }, "Angle"),
|
|
71
70
|
angleInput,
|
|
72
71
|
angleVal
|
|
73
72
|
);
|
|
@@ -85,10 +84,9 @@ export function mount(slot) {
|
|
|
85
84
|
const card = toolcard({
|
|
86
85
|
body: bench(
|
|
87
86
|
stack(panel("Type", typeChips), angleRow, panel("Color stops", stopsBox), addStop),
|
|
88
|
-
stack(el("div", { class: "
|
|
87
|
+
stack(el("div", { class: "grid min-h-40 place-items-center overflow-hidden rounded-r1 border border-orbit bg-deck-2 p-[22px]" }, previewBox), code)
|
|
89
88
|
),
|
|
90
|
-
foot: actions(copyButton(() => `background: ${gradientCss()};`, "Copy CSS", "fill"))
|
|
91
|
-
});
|
|
89
|
+
foot: actions(copyButton(() => `background: ${gradientCss()};`, "Copy CSS", "fill"))});
|
|
92
90
|
slot.append(card.node);
|
|
93
91
|
paintStops();
|
|
94
92
|
update();
|
|
@@ -11,15 +11,15 @@ export function mount(slot) {
|
|
|
11
11
|
let list = Array.isArray(saved) ? saved : [];
|
|
12
12
|
|
|
13
13
|
const name = textInput({ placeholder: "Habit", "aria-label": "Habit" });
|
|
14
|
-
const tableWrap = el("div", { class: "
|
|
15
|
-
const stats = el("div", { class: "
|
|
14
|
+
const tableWrap = el("div", { class: "max-h-80 overflow-auto" });
|
|
15
|
+
const stats = el("div", { class: "grid gap-2.5 [grid-template-columns:repeat(auto-fit,minmax(120px,1fr))]" });
|
|
16
16
|
|
|
17
17
|
const addButton = button("Add", { icon: "plus", kind: "fill" });
|
|
18
18
|
const clearWeek = button("Clear week", { icon: "trash" });
|
|
19
19
|
|
|
20
|
-
const tile = (key, value) => el("div", { class: "
|
|
21
|
-
el("span", { class: "
|
|
22
|
-
el("span", { class: "
|
|
20
|
+
const tile = (key, value) => el("div", { class: "grid gap-0.5 rounded-r1 border border-orbit bg-deck-2 px-3.5 py-3" },
|
|
21
|
+
el("span", { class: "wrap-anywhere text-xl font-bold tracking-[-0.02em] tabular-nums" }, String(value)),
|
|
22
|
+
el("span", { class: "text-2xs font-semibold text-ink-3" }, key));
|
|
23
23
|
|
|
24
24
|
const save = () => writePin(PIN, list);
|
|
25
25
|
const today = todayIndex();
|
|
@@ -57,7 +57,7 @@ export function mount(slot) {
|
|
|
57
57
|
|
|
58
58
|
function render() {
|
|
59
59
|
if (!list.length) {
|
|
60
|
-
tableWrap.replaceChildren(el("p", { class: "
|
|
60
|
+
tableWrap.replaceChildren(el("p", { class: "border-s-[3px] border-transparent ps-2 text-sm text-ink-3" }, "No habits yet."));
|
|
61
61
|
} else {
|
|
62
62
|
const head = el("tr", {},
|
|
63
63
|
el("th", {}, "Habit"),
|
|
@@ -73,7 +73,7 @@ export function mount(slot) {
|
|
|
73
73
|
el("td", {}, String(streak(habit))),
|
|
74
74
|
el("td", {}, removeButton(habit))
|
|
75
75
|
));
|
|
76
|
-
tableWrap.replaceChildren(el("table", { class: "
|
|
76
|
+
tableWrap.replaceChildren(el("table", { class: "w-full border-collapse font-mono text-sm [&_th]:wrap-anywhere [&_td]:wrap-anywhere [&_th]:border-b [&_td]:border-b [&_th]:border-orbit [&_td]:border-orbit [&_th]:px-2.5 [&_td]:px-2.5 [&_th]:py-2 [&_td]:py-2 [&_th]:text-start [&_td]:text-start [&_th]:font-sans [&_th]:text-2xs [&_th]:font-semibold [&_th]:text-ink-2 [&_tbody>tr:last-child>th]:border-b-0 [&_tbody>tr:last-child>td]:border-b-0" },
|
|
77
77
|
el("thead", {}, head),
|
|
78
78
|
el("tbody", {}, ...rows)
|
|
79
79
|
));
|
|
@@ -109,8 +109,7 @@ export function mount(slot) {
|
|
|
109
109
|
stack(panel("Habit", name)),
|
|
110
110
|
stack(stats, panel("Week", tableWrap))
|
|
111
111
|
),
|
|
112
|
-
foot: actions(clearWeek, addButton)
|
|
113
|
-
});
|
|
112
|
+
foot: actions(clearWeek, addButton)});
|
|
114
113
|
slot.append(card.node);
|
|
115
114
|
render();
|
|
116
115
|
|
|
@@ -6,7 +6,7 @@ const ALGORITHMS = ["SHA-1", "SHA-256", "SHA-384", "SHA-512"];
|
|
|
6
6
|
export function mount(slot) {
|
|
7
7
|
const source = textArea({ value: "mevebu", rows: 5, "aria-label": "Text to hash", placeholder: "Type or paste text" });
|
|
8
8
|
const result = output();
|
|
9
|
-
const digest = el("p", { class: "
|
|
9
|
+
const digest = el("p", { class: "border-s-[3px] border-transparent ps-2 text-sm text-ink-3" });
|
|
10
10
|
const error = notice("error");
|
|
11
11
|
|
|
12
12
|
let algorithm = "SHA-256";
|
|
@@ -17,8 +17,7 @@ export function mount(slot) {
|
|
|
17
17
|
onChange: (value) => {
|
|
18
18
|
algorithm = value;
|
|
19
19
|
run();
|
|
20
|
-
}
|
|
21
|
-
});
|
|
20
|
+
}});
|
|
22
21
|
|
|
23
22
|
async function run() {
|
|
24
23
|
error.write("");
|
|
@@ -45,8 +44,7 @@ export function mount(slot) {
|
|
|
45
44
|
stack(panel("Algorithm", chips), panel("Text", source)),
|
|
46
45
|
stack(panel("Hash", result), digest, error)
|
|
47
46
|
),
|
|
48
|
-
foot: actions(copy)
|
|
49
|
-
});
|
|
47
|
+
foot: actions(copy)});
|
|
50
48
|
slot.append(card.node);
|
|
51
49
|
run();
|
|
52
50
|
|
|
@@ -4,8 +4,8 @@ import { el, bench, stack, panel, textArea, chipRow, output, copyButton, actions
|
|
|
4
4
|
const clean = (raw) => raw.replace(/#/g, "").replace(/[^\p{L}\p{N}_]/gu, "");
|
|
5
5
|
|
|
6
6
|
function tile(label) {
|
|
7
|
-
const value = el("span", { class: "
|
|
8
|
-
const node = el("div", { class: "
|
|
7
|
+
const value = el("span", { class: "wrap-anywhere text-xl font-bold tracking-[-0.02em] tabular-nums" }, "0");
|
|
8
|
+
const node = el("div", { class: "grid gap-0.5 rounded-r1 border border-orbit bg-deck-2 px-3.5 py-3" }, value, el("span", { class: "text-2xs font-semibold text-ink-3" }, label));
|
|
9
9
|
node.set = (text) => { value.textContent = text; };
|
|
10
10
|
return node;
|
|
11
11
|
}
|
|
@@ -14,22 +14,21 @@ export function mount(slot) {
|
|
|
14
14
|
const source = textArea({ rows: 8, "aria-label": "Tags", placeholder: "One tag per line or space separated" });
|
|
15
15
|
const tagsTile = tile("Tags");
|
|
16
16
|
const removedTile = tile("Duplicates removed");
|
|
17
|
-
const stats = el("div", { class: "
|
|
17
|
+
const stats = el("div", { class: "grid gap-2.5 [grid-template-columns:repeat(auto-fit,minmax(120px,1fr))]" }, tagsTile, removedTile);
|
|
18
18
|
const out = output({ rows: 8 });
|
|
19
19
|
|
|
20
20
|
let mode = "list";
|
|
21
21
|
const modeChips = chipRow(
|
|
22
22
|
[
|
|
23
23
|
{ value: "line", label: "One line" },
|
|
24
|
-
{ value: "list", label: "One per line" },
|
|
25
|
-
],
|
|
24
|
+
{ value: "list", label: "One per line" }],
|
|
26
25
|
{ value: "list", label: "Layout", onChange: (next) => { mode = next; run(); } }
|
|
27
26
|
);
|
|
28
27
|
|
|
29
28
|
let result = "";
|
|
30
29
|
|
|
31
30
|
function run() {
|
|
32
|
-
const tokens = source.value.split(/[\s
|
|
31
|
+
const tokens = source.value.split(/[\s]+/).map(clean).filter(Boolean);
|
|
33
32
|
const seen = new Set();
|
|
34
33
|
const tags = [];
|
|
35
34
|
for (const token of tokens) {
|
|
@@ -51,8 +50,7 @@ export function mount(slot) {
|
|
|
51
50
|
stack(panel("Tags", source), panel("Layout", modeChips)),
|
|
52
51
|
stack(stats, panel("Result", out))
|
|
53
52
|
),
|
|
54
|
-
foot: actions(copyButton(() => result, "Copy tags", "fill"))
|
|
55
|
-
});
|
|
53
|
+
foot: actions(copyButton(() => result, "Copy tags", "fill"))});
|
|
56
54
|
slot.append(card.node);
|
|
57
55
|
run();
|
|
58
56
|
|
|
@@ -5,8 +5,7 @@ const ALGORITHMS = [
|
|
|
5
5
|
{ value: "SHA-256", label: "SHA-256" },
|
|
6
6
|
{ value: "SHA-384", label: "SHA-384" },
|
|
7
7
|
{ value: "SHA-512", label: "SHA-512" },
|
|
8
|
-
{ value: "SHA-1", label: "SHA-1" }
|
|
9
|
-
];
|
|
8
|
+
{ value: "SHA-1", label: "SHA-1" }];
|
|
10
9
|
|
|
11
10
|
const encoder = new TextEncoder();
|
|
12
11
|
const toHex = (bytes) => [...bytes].map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
@@ -46,13 +45,12 @@ export function mount(slot) {
|
|
|
46
45
|
body: bench(
|
|
47
46
|
stack(
|
|
48
47
|
panel("Message", message),
|
|
49
|
-
panel("Secret key", el("div", { class: "
|
|
48
|
+
panel("Secret key", el("div", { class: "grid grid-cols-[minmax(0,1fr)_auto] items-center gap-2" }, secret, showButton)),
|
|
50
49
|
panel("Hash", hashField)
|
|
51
50
|
),
|
|
52
51
|
stack(panel("Signature", result), error)
|
|
53
52
|
),
|
|
54
|
-
foot: actions(copyButton(() => result.textContent, "Copy signature", "fill"))
|
|
55
|
-
});
|
|
53
|
+
foot: actions(copyButton(() => result.textContent, "Copy signature", "fill"))});
|
|
56
54
|
slot.append(card.node);
|
|
57
55
|
run();
|
|
58
56
|
|
|
@@ -6,8 +6,8 @@ function fmt(n) {
|
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
function tile(label) {
|
|
9
|
-
const value = el("span", { class: "
|
|
10
|
-
const node = el("div", { class: "
|
|
9
|
+
const value = el("span", { class: "wrap-anywhere text-xl font-bold tracking-[-0.02em] tabular-nums" }, "-");
|
|
10
|
+
const node = el("div", { class: "grid gap-0.5 rounded-r1 border border-orbit bg-deck-2 px-3.5 py-3" }, value, el("span", { class: "text-2xs font-semibold text-ink-3" }, label));
|
|
11
11
|
node.set = (text) => { value.textContent = text; };
|
|
12
12
|
return node;
|
|
13
13
|
}
|
|
@@ -19,7 +19,7 @@ export function mount(slot) {
|
|
|
19
19
|
const units = numberInput({ value: "1", min: "1", "aria-label": "Units made" });
|
|
20
20
|
const total = tile("Total cost");
|
|
21
21
|
const perUnit = tile("Cost per unit");
|
|
22
|
-
const stats = el("div", { class: "
|
|
22
|
+
const stats = el("div", { class: "grid gap-2.5 [grid-template-columns:repeat(auto-fit,minmax(120px,1fr))]" }, total, perUnit);
|
|
23
23
|
const error = notice("error");
|
|
24
24
|
let text = "";
|
|
25
25
|
|
|
@@ -59,8 +59,7 @@ export function mount(slot) {
|
|
|
59
59
|
),
|
|
60
60
|
stack(stats)
|
|
61
61
|
),
|
|
62
|
-
foot: actions(copyButton(() => text, "Copy result", "fill"))
|
|
63
|
-
});
|
|
62
|
+
foot: actions(copyButton(() => text, "Copy result", "fill"))});
|
|
64
63
|
slot.append(card.node);
|
|
65
64
|
run();
|
|
66
65
|
|
|
@@ -13,7 +13,7 @@ function decode(text) {
|
|
|
13
13
|
|
|
14
14
|
export function mount(slot) {
|
|
15
15
|
const source = textArea({ rows: 6, value: "<a href=\"/x\">Tom & Jerry</a>", "aria-label": "Input" });
|
|
16
|
-
const result = textArea({ rows: 6, readonly: true,
|
|
16
|
+
const result = textArea({ rows: 6, readonly: true, "aria-label": "Result" });
|
|
17
17
|
const error = notice("error");
|
|
18
18
|
let mode = "encode";
|
|
19
19
|
|
|
@@ -38,8 +38,7 @@ export function mount(slot) {
|
|
|
38
38
|
stack(panel("Direction", chips), panel("Input", source), error),
|
|
39
39
|
stack(panel("Result", result))
|
|
40
40
|
),
|
|
41
|
-
foot: actions(copyButton(() => result.value, "Copy result", "fill"))
|
|
42
|
-
});
|
|
41
|
+
foot: actions(copyButton(() => result.value, "Copy result", "fill"))});
|
|
43
42
|
slot.append(card.node);
|
|
44
43
|
run();
|
|
45
44
|
|
|
@@ -8,11 +8,9 @@ const tagName = (token) => (token.match(/^<\s*\/?\s*([a-zA-Z0-9:-]+)/) || [])[1]
|
|
|
8
8
|
export function mount(slot) {
|
|
9
9
|
const source = textArea({
|
|
10
10
|
rows: 12,
|
|
11
|
-
class: "mvb-in mvb-in--area mvb-in--mono",
|
|
12
11
|
"aria-label": "HTML",
|
|
13
|
-
value: "<div class=\"card\"><h1>Title</h1><p>Text <strong>bold</strong></p><br></div>"
|
|
14
|
-
});
|
|
15
|
-
const result = textArea({ rows: 12, readonly: true, class: "mvb-in mvb-in--area mvb-in--mono", "aria-label": "Formatted HTML" });
|
|
12
|
+
value: "<div class=\"card\"><h1>Title</h1><p>Text <strong>bold</strong></p><br></div>"});
|
|
13
|
+
const result = textArea({ rows: 12, readonly: true, "aria-label": "Formatted HTML" });
|
|
16
14
|
const warn = notice("warn");
|
|
17
15
|
let size = "2";
|
|
18
16
|
|
|
@@ -61,8 +59,7 @@ export function mount(slot) {
|
|
|
61
59
|
stack(panel("Indent", chips), panel("HTML", source), warn),
|
|
62
60
|
stack(panel("Formatted", result))
|
|
63
61
|
),
|
|
64
|
-
foot: actions(copyButton(() => result.value, "Copy markup", "fill"))
|
|
65
|
-
});
|
|
62
|
+
foot: actions(copyButton(() => result.value, "Copy markup", "fill"))});
|
|
66
63
|
slot.append(card.node);
|
|
67
64
|
run();
|
|
68
65
|
|
|
@@ -6,14 +6,13 @@ const CODES = [
|
|
|
6
6
|
[200, "OK"], [201, "Created"], [202, "Accepted"], [203, "Non-Authoritative Information"], [204, "No Content"], [205, "Reset Content"], [206, "Partial Content"],
|
|
7
7
|
[300, "Multiple Choices"], [301, "Moved Permanently"], [302, "Found"], [303, "See Other"], [304, "Not Modified"], [307, "Temporary Redirect"], [308, "Permanent Redirect"],
|
|
8
8
|
[400, "Bad Request"], [401, "Unauthorized"], [402, "Payment Required"], [403, "Forbidden"], [404, "Not Found"], [405, "Method Not Allowed"], [406, "Not Acceptable"], [408, "Request Timeout"], [409, "Conflict"], [410, "Gone"], [411, "Length Required"], [412, "Precondition Failed"], [413, "Payload Too Large"], [414, "URI Too Long"], [415, "Unsupported Media Type"], [416, "Range Not Satisfiable"], [418, "I'm a teapot"], [422, "Unprocessable Entity"], [425, "Too Early"], [426, "Upgrade Required"], [428, "Precondition Required"], [429, "Too Many Requests"], [431, "Request Header Fields Too Large"], [451, "Unavailable For Legal Reasons"],
|
|
9
|
-
[500, "Internal Server Error"], [501, "Not Implemented"], [502, "Bad Gateway"], [503, "Service Unavailable"], [504, "Gateway Timeout"], [505, "HTTP Version Not Supported"], [507, "Insufficient Storage"], [508, "Loop Detected"], [511, "Network Authentication Required"]
|
|
10
|
-
];
|
|
9
|
+
[500, "Internal Server Error"], [501, "Not Implemented"], [502, "Bad Gateway"], [503, "Service Unavailable"], [504, "Gateway Timeout"], [505, "HTTP Version Not Supported"], [507, "Insufficient Storage"], [508, "Loop Detected"], [511, "Network Authentication Required"]];
|
|
11
10
|
|
|
12
11
|
const statusClass = (code) => `${Math.floor(code / 100)}xx`;
|
|
13
12
|
|
|
14
13
|
export function mount(slot) {
|
|
15
14
|
const filter = textInput({ type: "search", placeholder: "Code or reason", "aria-label": "Filter" });
|
|
16
|
-
const scroll = el("div", { class: "
|
|
15
|
+
const scroll = el("div", { class: "max-h-80 overflow-auto" });
|
|
17
16
|
let group = "all";
|
|
18
17
|
let visible = CODES;
|
|
19
18
|
|
|
@@ -30,12 +29,12 @@ export function mount(slot) {
|
|
|
30
29
|
return String(code).includes(query) || message.toLowerCase().includes(query);
|
|
31
30
|
});
|
|
32
31
|
if (!visible.length) {
|
|
33
|
-
scroll.replaceChildren(el("p", { class: "
|
|
32
|
+
scroll.replaceChildren(el("p", { class: "border-s-[3px] border-transparent ps-2 text-sm text-ink-3" }, "No code matches."));
|
|
34
33
|
return;
|
|
35
34
|
}
|
|
36
35
|
scroll.replaceChildren(el(
|
|
37
36
|
"table",
|
|
38
|
-
{ class: "
|
|
37
|
+
{ class: "w-full border-collapse font-mono text-sm [&_th]:wrap-anywhere [&_td]:wrap-anywhere [&_th]:border-b [&_td]:border-b [&_th]:border-orbit [&_td]:border-orbit [&_th]:px-2.5 [&_td]:px-2.5 [&_th]:py-2 [&_td]:py-2 [&_th]:text-start [&_td]:text-start [&_th]:font-sans [&_th]:text-2xs [&_th]:font-semibold [&_th]:text-ink-2 [&_tbody>tr:last-child>th]:border-b-0 [&_tbody>tr:last-child>td]:border-b-0" },
|
|
39
38
|
el("thead", {}, el("tr", {}, el("th", {}, "Code"), el("th", {}, "Message"), el("th", {}, "Class"))),
|
|
40
39
|
el("tbody", {}, ...visible.map(([code, message]) => el("tr", {},
|
|
41
40
|
el("td", {}, String(code)),
|
|
@@ -52,8 +51,7 @@ export function mount(slot) {
|
|
|
52
51
|
stack(panel("Filter", filter), panel("Class", chips)),
|
|
53
52
|
stack(panel("Status codes", scroll))
|
|
54
53
|
),
|
|
55
|
-
foot: actions(copyButton(() => visible.map(([code, message]) => `${code} ${message}`).join("\n"), "Copy list", "fill"))
|
|
56
|
-
});
|
|
54
|
+
foot: actions(copyButton(() => visible.map(([code, message]) => `${code} ${message}`).join("\n"), "Copy list", "fill"))});
|
|
57
55
|
slot.append(card.node);
|
|
58
56
|
run();
|
|
59
57
|
|
|
@@ -16,16 +16,16 @@ export function mount(slot) {
|
|
|
16
16
|
const opening = numberInput({ value: "0", min: "0", "aria-label": "Opening stock" });
|
|
17
17
|
const stockIn = numberInput({ value: "0", min: "0", "aria-label": "Stock in" });
|
|
18
18
|
const stockOut = numberInput({ value: "0", min: "0", "aria-label": "Stock out" });
|
|
19
|
-
const listWrap = el("div", { class: "
|
|
20
|
-
const stats = el("div", { class: "
|
|
19
|
+
const listWrap = el("div", { class: "max-h-80 overflow-auto" });
|
|
20
|
+
const stats = el("div", { class: "grid gap-2.5 [grid-template-columns:repeat(auto-fit,minmax(120px,1fr))]" });
|
|
21
21
|
const warn = notice("warn");
|
|
22
22
|
|
|
23
23
|
const addButton = button("Add", { icon: "plus", kind: "fill" });
|
|
24
24
|
|
|
25
25
|
const save = () => writePin(PIN, list);
|
|
26
|
-
const tile = (key, value) => el("div", { class: "
|
|
27
|
-
el("span", { class: "
|
|
28
|
-
el("span", { class: "
|
|
26
|
+
const tile = (key, value) => el("div", { class: "grid gap-0.5 rounded-r1 border border-orbit bg-deck-2 px-3.5 py-3" },
|
|
27
|
+
el("span", { class: "wrap-anywhere text-xl font-bold tracking-[-0.02em] tabular-nums" }, String(value)),
|
|
28
|
+
el("span", { class: "text-2xs font-semibold text-ink-3" }, key));
|
|
29
29
|
|
|
30
30
|
const closing = (item) => item.opening + item.in - item.out;
|
|
31
31
|
|
|
@@ -43,7 +43,7 @@ export function mount(slot) {
|
|
|
43
43
|
if (!list.length) {
|
|
44
44
|
listWrap.replaceChildren(blank("package", "No items yet."));
|
|
45
45
|
} else {
|
|
46
|
-
listWrap.replaceChildren(el("table", { class: "
|
|
46
|
+
listWrap.replaceChildren(el("table", { class: "w-full border-collapse font-mono text-sm [&_th]:wrap-anywhere [&_td]:wrap-anywhere [&_th]:border-b [&_td]:border-b [&_th]:border-orbit [&_td]:border-orbit [&_th]:px-2.5 [&_td]:px-2.5 [&_th]:py-2 [&_td]:py-2 [&_th]:text-start [&_td]:text-start [&_th]:font-sans [&_th]:text-2xs [&_th]:font-semibold [&_th]:text-ink-2 [&_tbody>tr:last-child>th]:border-b-0 [&_tbody>tr:last-child>td]:border-b-0" },
|
|
47
47
|
el("thead", {}, el("tr", {},
|
|
48
48
|
el("th", {}, "Item"), el("th", {}, "Opening"), el("th", {}, "In"),
|
|
49
49
|
el("th", {}, "Out"), el("th", {}, "Closing"), el("th", {}, ""))),
|
|
@@ -92,8 +92,7 @@ export function mount(slot) {
|
|
|
92
92
|
foot: actions(
|
|
93
93
|
copyButton(() => list.map((item) => `${item.name}: opening ${fmt(item.opening)}, in ${fmt(item.in)}, out ${fmt(item.out)}, closing ${fmt(closing(item))}`).join("\n"), "Copy stock"),
|
|
94
94
|
addButton
|
|
95
|
-
)
|
|
96
|
-
});
|
|
95
|
+
)});
|
|
97
96
|
slot.append(card.node);
|
|
98
97
|
render();
|
|
99
98
|
|
|
@@ -4,12 +4,10 @@ import { bench, stack, panel, textArea, notice, chipRow, copyButton, actions, to
|
|
|
4
4
|
export function mount(slot) {
|
|
5
5
|
const source = textArea({
|
|
6
6
|
rows: 12,
|
|
7
|
-
class: "mvb-in mvb-in--area mvb-in--mono",
|
|
8
7
|
"aria-label": "JSON",
|
|
9
8
|
placeholder: "Paste JSON",
|
|
10
|
-
value: '{"hello":"world","count":3,"items":[1,2,3]}'
|
|
11
|
-
});
|
|
12
|
-
const result = textArea({ rows: 12, readonly: true, class: "mvb-in mvb-in--area mvb-in--mono", "aria-label": "Result" });
|
|
9
|
+
value: '{"hello":"world","count":3,"items":[1,2,3]}'});
|
|
10
|
+
const result = textArea({ rows: 12, readonly: true, "aria-label": "Result" });
|
|
13
11
|
const error = notice("error");
|
|
14
12
|
let indent = "2";
|
|
15
13
|
|
|
@@ -40,8 +38,7 @@ export function mount(slot) {
|
|
|
40
38
|
stack(panel("Indent", chips), panel("JSON", source), error),
|
|
41
39
|
stack(panel("Result", result))
|
|
42
40
|
),
|
|
43
|
-
foot: actions(copyButton(() => result.value, "Copy result", "fill"))
|
|
44
|
-
});
|
|
41
|
+
foot: actions(copyButton(() => result.value, "Copy result", "fill"))});
|
|
45
42
|
slot.append(card.node);
|
|
46
43
|
run();
|
|
47
44
|
|
|
@@ -4,18 +4,16 @@ import { el, bench, stack, panel, textArea, notice, copyButton, actions, toolcar
|
|
|
4
4
|
const bytes = (text) => new TextEncoder().encode(text).length;
|
|
5
5
|
|
|
6
6
|
const tile = (key, value) =>
|
|
7
|
-
el("div", { class: "
|
|
7
|
+
el("div", { class: "grid gap-0.5 rounded-r1 border border-orbit bg-deck-2 px-3.5 py-3" }, el("span", { class: "wrap-anywhere text-xl font-bold tracking-[-0.02em] tabular-nums" }, value), el("span", { class: "text-2xs font-semibold text-ink-3" }, key));
|
|
8
8
|
|
|
9
9
|
export function mount(slot) {
|
|
10
10
|
const source = textArea({
|
|
11
11
|
rows: 12,
|
|
12
|
-
class: "mvb-in mvb-in--area mvb-in--mono",
|
|
13
12
|
"aria-label": "JSON",
|
|
14
13
|
placeholder: "Paste JSON",
|
|
15
|
-
value: '{\n "hello": "world",\n "count": 3\n}'
|
|
16
|
-
});
|
|
17
|
-
const
|
|
18
|
-
const stats = el("div", { class: "mvb-stats" });
|
|
14
|
+
value: '{\n "hello": "world",\n "count": 3\n}'});
|
|
15
|
+
const result = textArea({ rows: 12, readonly: true, "aria-label": "Minified JSON" });
|
|
16
|
+
const stats = el("div", { class: "grid gap-2.5 [grid-template-columns:repeat(auto-fit,minmax(120px,1fr))]" });
|
|
19
17
|
const error = notice("error");
|
|
20
18
|
|
|
21
19
|
function run() {
|
|
@@ -47,8 +45,7 @@ export function mount(slot) {
|
|
|
47
45
|
stack(panel("JSON", source), error),
|
|
48
46
|
stack(panel("Minified", result), stats)
|
|
49
47
|
),
|
|
50
|
-
foot: actions(copyButton(() => result.value, "Copy result", "fill"))
|
|
51
|
-
});
|
|
48
|
+
foot: actions(copyButton(() => result.value, "Copy result", "fill"))});
|
|
52
49
|
slot.append(card.node);
|
|
53
50
|
run();
|
|
54
51
|
|
|
@@ -10,7 +10,7 @@ function stringifyCSV(rows, delimiter) {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export function mount(slot) {
|
|
13
|
-
const source = textArea({ rows: 12,
|
|
13
|
+
const source = textArea({ rows: 12, "aria-label": "JSON", placeholder: '[{"name":"Ada","role":"engineer"}]' });
|
|
14
14
|
const result = output({ rows: 12 });
|
|
15
15
|
const error = notice("error");
|
|
16
16
|
let current = "";
|
|
@@ -45,8 +45,7 @@ export function mount(slot) {
|
|
|
45
45
|
...records.map((record) => header.map((key) => {
|
|
46
46
|
const value = record[key];
|
|
47
47
|
return value && typeof value === "object" ? JSON.stringify(value) : value;
|
|
48
|
-
}))
|
|
49
|
-
];
|
|
48
|
+
}))];
|
|
50
49
|
current = stringifyCSV(rows, ",");
|
|
51
50
|
result.write(current);
|
|
52
51
|
}
|
|
@@ -61,8 +60,7 @@ export function mount(slot) {
|
|
|
61
60
|
foot: actions(
|
|
62
61
|
downloadButton(() => current, "data.csv", "Download CSV", "text/csv"),
|
|
63
62
|
copyButton(() => current, "Copy CSV", "fill")
|
|
64
|
-
)
|
|
65
|
-
});
|
|
63
|
+
)});
|
|
66
64
|
slot.append(card.node);
|
|
67
65
|
run();
|
|
68
66
|
|
|
@@ -55,11 +55,9 @@ function generate(data, rootName) {
|
|
|
55
55
|
export function mount(slot) {
|
|
56
56
|
const source = textArea({
|
|
57
57
|
rows: 12,
|
|
58
|
-
class: "mvb-in mvb-in--area mvb-in--mono",
|
|
59
58
|
"aria-label": "JSON",
|
|
60
59
|
placeholder: "Paste a JSON object or array",
|
|
61
|
-
value: '{\n "id": 1,\n "name": "Ada",\n "tags": ["dev"],\n "address": { "city": "London" }\n}'
|
|
62
|
-
});
|
|
60
|
+
value: '{\n "id": 1,\n "name": "Ada",\n "tags": ["dev"],\n "address": { "city": "London" }\n}'});
|
|
63
61
|
const nameInput = textInput({ value: "Root", "aria-label": "Root type name" });
|
|
64
62
|
const result = output({ rows: 16 });
|
|
65
63
|
const error = notice("error");
|
|
@@ -91,8 +89,7 @@ export function mount(slot) {
|
|
|
91
89
|
stack(panel("Root type name", nameInput), panel("JSON", source), error),
|
|
92
90
|
stack(panel("TypeScript", result))
|
|
93
91
|
),
|
|
94
|
-
foot: actions(copyButton(() => result.textContent, "Copy types", "fill"))
|
|
95
|
-
});
|
|
92
|
+
foot: actions(copyButton(() => result.textContent, "Copy types", "fill"))});
|
|
96
93
|
slot.append(card.node);
|
|
97
94
|
run();
|
|
98
95
|
|
|
@@ -12,7 +12,7 @@ function describe(data) {
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
export function mount(slot) {
|
|
15
|
-
const source = textArea({ rows: 12,
|
|
15
|
+
const source = textArea({ rows: 12, "aria-label": "JSON", placeholder: "Paste JSON" });
|
|
16
16
|
const report = output({ rows: 4 });
|
|
17
17
|
const error = notice("error");
|
|
18
18
|
|
|
@@ -38,8 +38,7 @@ export function mount(slot) {
|
|
|
38
38
|
stack(panel("JSON", source), error),
|
|
39
39
|
stack(panel("Result", report))
|
|
40
40
|
),
|
|
41
|
-
foot: actions(copyButton(() => report.textContent, "Copy result", "fill"))
|
|
42
|
-
});
|
|
41
|
+
foot: actions(copyButton(() => report.textContent, "Copy result", "fill"))});
|
|
43
42
|
slot.append(card.node);
|
|
44
43
|
run();
|
|
45
44
|
|
|
@@ -12,10 +12,10 @@ function decodeSegment(segment) {
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
export function mount(slot) {
|
|
15
|
-
const source = textArea({ rows: 4,
|
|
15
|
+
const source = textArea({ rows: 4, "aria-label": "Token", placeholder: "Paste a JWT" });
|
|
16
16
|
const headerOut = output({ rows: 4 });
|
|
17
17
|
const payloadOut = output({ rows: 8 });
|
|
18
|
-
const claims = el("div", { class: "
|
|
18
|
+
const claims = el("div", { class: "grid gap-px overflow-hidden rounded-r1 border border-orbit bg-orbit" });
|
|
19
19
|
const error = notice("error");
|
|
20
20
|
|
|
21
21
|
function render() {
|
|
@@ -49,9 +49,9 @@ export function mount(slot) {
|
|
|
49
49
|
const value = Number(payload[key]);
|
|
50
50
|
const when = Number.isFinite(value) ? new Date(value * 1000).toLocaleString() : String(payload[key]);
|
|
51
51
|
claims.append(
|
|
52
|
-
el("div", { class: "
|
|
53
|
-
el("span", { class: "
|
|
54
|
-
el("span", { class: "
|
|
52
|
+
el("div", { class: "grid gap-3 bg-deck px-3 py-[9px] [grid-template-columns:minmax(90px,34%)_minmax(0,1fr)]" },
|
|
53
|
+
el("span", { class: "wrap-anywhere text-2xs font-semibold text-ink-2" }, label),
|
|
54
|
+
el("span", { class: "wrap-anywhere font-mono text-2xs" }, when))
|
|
55
55
|
);
|
|
56
56
|
}
|
|
57
57
|
}
|
|
@@ -63,8 +63,7 @@ export function mount(slot) {
|
|
|
63
63
|
stack(panel("Token", source), error),
|
|
64
64
|
stack(panel("Header", headerOut), panel("Payload", payloadOut), claims)
|
|
65
65
|
),
|
|
66
|
-
foot: actions(copyButton(() => payloadOut.textContent, "Copy payload", "fill"))
|
|
67
|
-
});
|
|
66
|
+
foot: actions(copyButton(() => payloadOut.textContent, "Copy payload", "fill"))});
|
|
68
67
|
slot.append(card.node);
|
|
69
68
|
render();
|
|
70
69
|
|