mevebu 1.3.0 → 1.4.1
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 +1658 -2079
- package/mevebu/app/tailwind.src.css +161 -1127
- package/mevebu/index.html +2 -2
- package/mevebu/libs/js/core.js +245 -96
- 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 +2 -3
- 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 +10 -11
- 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 +5 -7
- 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 +6 -7
- 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 +6 -8
- 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 +8 -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/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-inspector.js +8 -9
- 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 +5 -9
- 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
|
@@ -12,14 +12,14 @@ export function mount(slot) {
|
|
|
12
12
|
const saved = readPin(PIN, {});
|
|
13
13
|
const counts = new Map();
|
|
14
14
|
|
|
15
|
-
const listWrap = el("div", { class: "
|
|
16
|
-
const stats = el("div", { class: "
|
|
15
|
+
const listWrap = el("div", { class: "max-h-80 overflow-auto" });
|
|
16
|
+
const stats = el("div", { class: "grid gap-2.5 [grid-template-columns:repeat(auto-fit,minmax(120px,1fr))]" });
|
|
17
17
|
const note = notice("note");
|
|
18
18
|
note.write("Values are generic. Match them to your currency.");
|
|
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 readCount = (value) => {
|
|
25
25
|
const input = counts.get(value);
|
|
@@ -40,7 +40,7 @@ export function mount(slot) {
|
|
|
40
40
|
el("th", {}, fmt(value)),
|
|
41
41
|
el("td", {}, fmt(readCount(value))),
|
|
42
42
|
el("td", {}, fmt(value * readCount(value)))));
|
|
43
|
-
listWrap.replaceChildren(el("table", { class: "
|
|
43
|
+
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" },
|
|
44
44
|
el("thead", {}, el("tr", {}, el("th", {}, "Value"), el("th", {}, "Count"), el("th", {}, "Subtotal"))),
|
|
45
45
|
el("tbody", {}, ...rows)));
|
|
46
46
|
const pieces = DENOMINATIONS.reduce((sum, value) => sum + readCount(value), 0);
|
|
@@ -63,8 +63,7 @@ export function mount(slot) {
|
|
|
63
63
|
() => DENOMINATIONS.map((value) => `${fmt(value)} x ${readCount(value)} = ${fmt(value * readCount(value))}`).join("\n"),
|
|
64
64
|
"Copy count",
|
|
65
65
|
"fill"
|
|
66
|
-
))
|
|
67
|
-
});
|
|
66
|
+
))});
|
|
68
67
|
slot.append(card.node);
|
|
69
68
|
render();
|
|
70
69
|
|
|
@@ -20,15 +20,15 @@ export function mount(slot) {
|
|
|
20
20
|
[{ value: "in", label: "In" }, { value: "out", label: "Out" }],
|
|
21
21
|
{ value: "in", label: "Direction", onChange: (next) => { type = next; } }
|
|
22
22
|
);
|
|
23
|
-
const listWrap = el("div", { class: "
|
|
24
|
-
const stats = el("div", { class: "
|
|
23
|
+
const listWrap = el("div", { class: "max-h-80 overflow-auto" });
|
|
24
|
+
const stats = el("div", { class: "grid gap-2.5 [grid-template-columns:repeat(auto-fit,minmax(120px,1fr))]" });
|
|
25
25
|
|
|
26
26
|
const addButton = button("Add", { icon: "plus", kind: "fill" });
|
|
27
27
|
|
|
28
28
|
const save = () => writePin(PIN, { opening: Number(opening.value) || 0, entries });
|
|
29
|
-
const tile = (key, value) => el("div", { class: "
|
|
30
|
-
el("span", { class: "
|
|
31
|
-
el("span", { class: "
|
|
29
|
+
const tile = (key, value) => el("div", { class: "grid gap-0.5 rounded-r1 border border-orbit bg-deck-2 px-3.5 py-3" },
|
|
30
|
+
el("span", { class: "wrap-anywhere text-xl font-bold tracking-[-0.02em] tabular-nums" }, String(value)),
|
|
31
|
+
el("span", { class: "text-2xs font-semibold text-ink-3" }, key));
|
|
32
32
|
|
|
33
33
|
function totals() {
|
|
34
34
|
let balance = Number(opening.value) || 0;
|
|
@@ -69,7 +69,7 @@ export function mount(slot) {
|
|
|
69
69
|
el("td", {}, fmt(balance)),
|
|
70
70
|
el("td", {}, removeButton(entry)));
|
|
71
71
|
});
|
|
72
|
-
listWrap.replaceChildren(el("table", { class: "
|
|
72
|
+
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" },
|
|
73
73
|
el("thead", {}, el("tr", {}, el("th", {}, "Label"), el("th", {}, "In"), el("th", {}, "Out"), el("th", {}, "Balance"), el("th", {}, ""))),
|
|
74
74
|
el("tbody", {}, ...rows)));
|
|
75
75
|
}
|
|
@@ -113,8 +113,7 @@ export function mount(slot) {
|
|
|
113
113
|
copyButton(() => totals().lines.join("\n"), "Copy summary"),
|
|
114
114
|
downloadButton(() => csv(), "cash-flow.csv", "Save CSV", "text/csv"),
|
|
115
115
|
addButton
|
|
116
|
-
)
|
|
117
|
-
});
|
|
116
|
+
)});
|
|
118
117
|
slot.append(card.node);
|
|
119
118
|
render();
|
|
120
119
|
|
|
@@ -5,8 +5,8 @@ const DAY = 86400000;
|
|
|
5
5
|
const pad = (value) => String(value).padStart(2, "0");
|
|
6
6
|
|
|
7
7
|
function tile(label) {
|
|
8
|
-
const value = el("span", { class: "
|
|
9
|
-
const node = el("div", { class: "
|
|
8
|
+
const value = el("span", { class: "wrap-anywhere text-xl font-bold tracking-[-0.02em] tabular-nums" }, "-");
|
|
9
|
+
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));
|
|
10
10
|
node.set = (text) => { value.textContent = text; };
|
|
11
11
|
return node;
|
|
12
12
|
}
|
|
@@ -16,14 +16,13 @@ export function mount(slot) {
|
|
|
16
16
|
const dateField = textInput({
|
|
17
17
|
type: "date",
|
|
18
18
|
value: `${soon.getFullYear()}-${pad(soon.getMonth() + 1)}-${pad(soon.getDate())}`,
|
|
19
|
-
"aria-label": "Expiry date"
|
|
20
|
-
});
|
|
19
|
+
"aria-label": "Expiry date"});
|
|
21
20
|
const warnField = numberInput({ min: "1", max: "365", value: "30", "aria-label": "Warn threshold in days" });
|
|
22
21
|
|
|
23
22
|
const daysTile = tile("Days left");
|
|
24
23
|
const weeksTile = tile("Weeks left");
|
|
25
24
|
const statusTile = tile("Status");
|
|
26
|
-
const stats = el("div", { class: "
|
|
25
|
+
const stats = el("div", { class: "grid gap-2.5 [grid-template-columns:repeat(auto-fit,minmax(120px,1fr))]" }, daysTile, weeksTile, statusTile);
|
|
27
26
|
const status = notice("note");
|
|
28
27
|
const error = notice("error");
|
|
29
28
|
let summary = "";
|
|
@@ -70,8 +69,7 @@ export function mount(slot) {
|
|
|
70
69
|
),
|
|
71
70
|
stack(stats, status)
|
|
72
71
|
),
|
|
73
|
-
foot: actions(copyButton(() => summary, "Copy summary", "fill"))
|
|
74
|
-
});
|
|
72
|
+
foot: actions(copyButton(() => summary, "Copy summary", "fill"))});
|
|
75
73
|
slot.append(card.node);
|
|
76
74
|
run();
|
|
77
75
|
|
|
@@ -5,12 +5,11 @@ const GROUPS = [
|
|
|
5
5
|
{ key: "added", label: "Added" },
|
|
6
6
|
{ key: "changed", label: "Changed" },
|
|
7
7
|
{ key: "fixed", label: "Fixed" },
|
|
8
|
-
{ key: "removed", label: "Removed" }
|
|
9
|
-
];
|
|
8
|
+
{ key: "removed", label: "Removed" }];
|
|
10
9
|
|
|
11
10
|
export function mount(slot) {
|
|
12
|
-
const version = textInput({ value: "1.0.0",
|
|
13
|
-
const date = el("input", { class: "
|
|
11
|
+
const version = textInput({ value: "1.0.0", mono: true, "aria-label": "Version" });
|
|
12
|
+
const date = el("input", { class: "min-w-0 rounded-r1 border border-orbit bg-deck text-ink transition-[border-color,box-shadow] duration-150 placeholder:text-ink-3 hover:border-orbit-hard focus:border-jade focus:outline-none focus:ring-3 focus:ring-jade-soft w-full min-h-[var(--ctl)] px-3 py-2.5 text-base", type: "date", value: new Date().toISOString().slice(0, 10), "aria-label": "Date" });
|
|
14
13
|
const fields = GROUPS.map((group) => ({ ...group, area: textArea({ rows: 3, "aria-label": group.label }) }));
|
|
15
14
|
const out = output({ rows: 16 });
|
|
16
15
|
let text = "";
|
|
@@ -37,8 +36,7 @@ export function mount(slot) {
|
|
|
37
36
|
stack(panel("Version", version), panel("Date", date), ...fields.map((group) => panel(group.label, group.area))),
|
|
38
37
|
stack(panel("Changelog", out))
|
|
39
38
|
),
|
|
40
|
-
foot: actions(copyButton(() => text, "Copy Markdown", "fill"))
|
|
41
|
-
});
|
|
39
|
+
foot: actions(copyButton(() => text, "Copy Markdown", "fill"))});
|
|
42
40
|
slot.append(card.node);
|
|
43
41
|
run();
|
|
44
42
|
|
|
@@ -6,8 +6,8 @@ const chars = (text) => [...text].length;
|
|
|
6
6
|
const withoutSpaces = (text) => [...text.replace(/\s/g, "")].length;
|
|
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" }, "0");
|
|
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,11 +19,11 @@ export function mount(slot) {
|
|
|
19
19
|
const totalTile = tile("Characters");
|
|
20
20
|
const noSpaceTile = tile("Without spaces");
|
|
21
21
|
const wordsTile = tile("Words");
|
|
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))]" }, totalTile, noSpaceTile, wordsTile);
|
|
23
23
|
|
|
24
|
-
const meter = el("div", { class: "
|
|
24
|
+
const meter = el("div", { class: "h-2 overflow-hidden rounded-full bg-deck-2", role: "img", "aria-label": "Character limit" }, el("div", { class: "h-full w-0 rounded-full bg-orbit-hard transition-[width,background-color] duration-150 data-[level=weak]:bg-danger data-[level=ok]:bg-star data-[level=strong]:bg-jade" }));
|
|
25
25
|
const limitNote = notice("note");
|
|
26
|
-
const fill = meter.
|
|
26
|
+
const fill = meter.firstElementChild;
|
|
27
27
|
|
|
28
28
|
let counts = { total: 0, noSpace: 0, words: 0 };
|
|
29
29
|
|
|
@@ -31,8 +31,7 @@ export function mount(slot) {
|
|
|
31
31
|
return [
|
|
32
32
|
`${counts.total} characters`,
|
|
33
33
|
`${counts.noSpace} without spaces`,
|
|
34
|
-
`${counts.words} words
|
|
35
|
-
].join("\n");
|
|
34
|
+
`${counts.words} words`].join("\n");
|
|
36
35
|
}
|
|
37
36
|
|
|
38
37
|
function run() {
|
|
@@ -40,8 +39,7 @@ export function mount(slot) {
|
|
|
40
39
|
counts = {
|
|
41
40
|
total: chars(text),
|
|
42
41
|
noSpace: withoutSpaces(text),
|
|
43
|
-
words: text.trim() ? text.trim().split(/\s+/).length : 0
|
|
44
|
-
};
|
|
42
|
+
words: text.trim() ? text.trim().split(/\s+/).length : 0};
|
|
45
43
|
totalTile.set(String(counts.total));
|
|
46
44
|
noSpaceTile.set(String(counts.noSpace));
|
|
47
45
|
wordsTile.set(String(counts.words));
|
|
@@ -50,11 +48,11 @@ export function mount(slot) {
|
|
|
50
48
|
if (limit > 0) {
|
|
51
49
|
const ratio = counts.total / limit;
|
|
52
50
|
fill.style.width = `${Math.min(100, ratio * 100)}%`;
|
|
53
|
-
fill.
|
|
51
|
+
fill.dataset.level = ratio > 1 ? "weak" : ratio > 0.8 ? "ok" : "strong";
|
|
54
52
|
limitNote.write(ratio > 1 ? `${counts.total - limit} over the limit.` : `${limit - counts.total} characters left.`);
|
|
55
53
|
} else {
|
|
56
54
|
fill.style.width = "0%";
|
|
57
|
-
fill.
|
|
55
|
+
delete fill.dataset.level;
|
|
58
56
|
limitNote.write("");
|
|
59
57
|
}
|
|
60
58
|
}
|
|
@@ -69,8 +67,7 @@ export function mount(slot) {
|
|
|
69
67
|
stack(panel("Text", source), panel("Character limit", limitField)),
|
|
70
68
|
stack(stats, meter, limitNote)
|
|
71
69
|
),
|
|
72
|
-
foot: actions(clearButton, copyButton(summary, "Copy summary", "fill"))
|
|
73
|
-
});
|
|
70
|
+
foot: actions(clearButton, copyButton(summary, "Copy summary", "fill"))});
|
|
74
71
|
slot.append(card.node);
|
|
75
72
|
run();
|
|
76
73
|
|
|
@@ -9,16 +9,16 @@ export function mount(slot) {
|
|
|
9
9
|
let list = Array.isArray(saved) ? saved : [];
|
|
10
10
|
|
|
11
11
|
const entry = textInput({ placeholder: "New item", "aria-label": "New item" });
|
|
12
|
-
const listWrap = el("div", { class: "
|
|
13
|
-
const stats = el("div", { class: "
|
|
12
|
+
const listWrap = el("div", { class: "max-h-80 overflow-auto" });
|
|
13
|
+
const stats = el("div", { class: "grid gap-2.5 [grid-template-columns:repeat(auto-fit,minmax(120px,1fr))]" });
|
|
14
14
|
|
|
15
15
|
const addButton = button("Add", { icon: "plus", kind: "fill" });
|
|
16
16
|
const clearDone = button("Clear finished", { icon: "trash" });
|
|
17
17
|
const copyList = copyButton(() => listText(), "Copy list");
|
|
18
18
|
|
|
19
|
-
const tile = (key, value) => el("div", { class: "
|
|
20
|
-
el("span", { class: "
|
|
21
|
-
el("span", { class: "
|
|
19
|
+
const tile = (key, value) => el("div", { class: "grid gap-0.5 rounded-r1 border border-orbit bg-deck-2 px-3.5 py-3" },
|
|
20
|
+
el("span", { class: "wrap-anywhere text-xl font-bold tracking-[-0.02em] tabular-nums" }, String(value)),
|
|
21
|
+
el("span", { class: "text-2xs font-semibold text-ink-3" }, key));
|
|
22
22
|
|
|
23
23
|
const save = () => writePin(PIN, list);
|
|
24
24
|
|
|
@@ -75,8 +75,7 @@ export function mount(slot) {
|
|
|
75
75
|
stack(panel("New item", entry)),
|
|
76
76
|
stack(stats, panel("Items", listWrap))
|
|
77
77
|
),
|
|
78
|
-
foot: actions(copyList, clearDone, addButton)
|
|
79
|
-
});
|
|
78
|
+
foot: actions(copyList, clearDone, addButton)});
|
|
80
79
|
slot.append(card.node);
|
|
81
80
|
renderList();
|
|
82
81
|
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import { el, bench, stack, panel, textArea, notice, copyButton, actions, toolcard } from "../core.js";
|
|
3
3
|
|
|
4
4
|
function tile(label) {
|
|
5
|
-
const value = el("span", { class: "
|
|
6
|
-
const node = el("div", { class: "
|
|
5
|
+
const value = el("span", { class: "wrap-anywhere text-xl font-bold tracking-[-0.02em] tabular-nums" }, "0");
|
|
6
|
+
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));
|
|
7
7
|
node.set = (text) => { value.textContent = text; };
|
|
8
8
|
return node;
|
|
9
9
|
}
|
|
@@ -47,8 +47,8 @@ export function mount(slot) {
|
|
|
47
47
|
const refsTile = tile("References");
|
|
48
48
|
const missingTile = tile("Missing");
|
|
49
49
|
const unusedTile = tile("Unused");
|
|
50
|
-
const stats = el("div", { class: "
|
|
51
|
-
const tableWrap = el("div", { class: "
|
|
50
|
+
const stats = el("div", { class: "grid gap-2.5 [grid-template-columns:repeat(auto-fit,minmax(120px,1fr))]" }, citedTile, refsTile, missingTile, unusedTile);
|
|
51
|
+
const tableWrap = el("div", { class: "max-h-80 overflow-auto" });
|
|
52
52
|
const note = notice("note");
|
|
53
53
|
note.write("A number match does not prove the reference is correct.");
|
|
54
54
|
let report = "";
|
|
@@ -66,14 +66,13 @@ export function mount(slot) {
|
|
|
66
66
|
|
|
67
67
|
const rows = [
|
|
68
68
|
...missing.map((n) => [n, "Cited, no reference"]),
|
|
69
|
-
...unused.map((n) => [n, "Reference, not cited"])
|
|
70
|
-
];
|
|
69
|
+
...unused.map((n) => [n, "Reference, not cited"])];
|
|
71
70
|
if (!body.value.trim() && !list.value.trim()) {
|
|
72
|
-
tableWrap.replaceChildren(el("p", { class: "
|
|
71
|
+
tableWrap.replaceChildren(el("p", { class: "border-s-[3px] border-transparent ps-2 text-sm text-ink-3" }, "Paste the text and the reference list."));
|
|
73
72
|
} else if (!rows.length) {
|
|
74
|
-
tableWrap.replaceChildren(el("p", { class: "
|
|
73
|
+
tableWrap.replaceChildren(el("p", { class: "border-s-[3px] border-transparent ps-2 text-sm text-ink-3" }, "Every number matches."));
|
|
75
74
|
} else {
|
|
76
|
-
tableWrap.replaceChildren(el("table", { class: "
|
|
75
|
+
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
76
|
el("thead", {}, el("tr", {}, el("th", {}, "Number"), el("th", {}, "Problem"))),
|
|
78
77
|
el("tbody", {}, ...rows.map((row) => el("tr", {},
|
|
79
78
|
el("th", {}, String(row[0])),
|
|
@@ -84,8 +83,7 @@ export function mount(slot) {
|
|
|
84
83
|
|
|
85
84
|
report = [
|
|
86
85
|
...missing.map((n) => `${n}: cited, no reference`),
|
|
87
|
-
...unused.map((n) => `${n}: reference, not cited`)
|
|
88
|
-
].join("\n");
|
|
86
|
+
...unused.map((n) => `${n}: reference, not cited`)].join("\n");
|
|
89
87
|
}
|
|
90
88
|
|
|
91
89
|
body.addEventListener("input", run);
|
|
@@ -96,8 +94,7 @@ export function mount(slot) {
|
|
|
96
94
|
stack(panel("Text with citations", body), panel("Reference list", list), note),
|
|
97
95
|
stack(stats, panel("Problems", tableWrap))
|
|
98
96
|
),
|
|
99
|
-
foot: actions(copyButton(() => report, "Copy problems", "fill"))
|
|
100
|
-
});
|
|
97
|
+
foot: actions(copyButton(() => report, "Copy problems", "fill"))});
|
|
101
98
|
slot.append(card.node);
|
|
102
99
|
run();
|
|
103
100
|
|
|
@@ -7,8 +7,8 @@ const TOSS_MS = 400;
|
|
|
7
7
|
|
|
8
8
|
/** A tally tile. The value is the node the tool writes to. */
|
|
9
9
|
function tile(key) {
|
|
10
|
-
const value = el("span", { class: "
|
|
11
|
-
const row = el("div", { class: "
|
|
10
|
+
const value = el("span", { class: "wrap-anywhere text-xl font-bold tracking-[-0.02em] tabular-nums" }, "0");
|
|
11
|
+
const row = 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" }, key));
|
|
12
12
|
return { row, value };
|
|
13
13
|
}
|
|
14
14
|
|
|
@@ -19,12 +19,12 @@ export function mount(slot) {
|
|
|
19
19
|
let tails = Number(saved.tails) || 0;
|
|
20
20
|
let timer = 0;
|
|
21
21
|
|
|
22
|
-
const coin = el("div", { class: "
|
|
23
|
-
const verdict = el("p", { class: "
|
|
22
|
+
const coin = el("div", { class: "grid size-32 select-none place-items-center rounded-full bg-jade text-display font-bold text-on-jade data-[toss]:animate-toss", role: "img", "aria-label": "Coin, not flipped yet" }, "?");
|
|
23
|
+
const verdict = el("p", { class: "text-lg font-bold tracking-[-0.01em] min-h-7", "aria-live": "polite" });
|
|
24
24
|
const headsTile = tile("Heads");
|
|
25
25
|
const tailsTile = tile("Tails");
|
|
26
26
|
const totalTile = tile("Total");
|
|
27
|
-
const stats = el("div", { class: "
|
|
27
|
+
const stats = el("div", { class: "grid gap-2.5 [grid-template-columns:repeat(auto-fit,minmax(120px,1fr))]" }, headsTile.row, tailsTile.row, totalTile.row);
|
|
28
28
|
|
|
29
29
|
function render(decision) {
|
|
30
30
|
verdict.textContent = decision;
|
|
@@ -40,9 +40,9 @@ export function mount(slot) {
|
|
|
40
40
|
|
|
41
41
|
flipButton.addEventListener("click", () => {
|
|
42
42
|
clearTimeout(timer);
|
|
43
|
-
coin.
|
|
43
|
+
delete coin.dataset.toss;
|
|
44
44
|
void coin.offsetWidth;
|
|
45
|
-
coin.
|
|
45
|
+
coin.dataset.toss = "";
|
|
46
46
|
timer = setTimeout(() => {
|
|
47
47
|
const isHeads = randomInt(2) === 0;
|
|
48
48
|
if (isHeads) heads++;
|
|
@@ -65,16 +65,14 @@ export function mount(slot) {
|
|
|
65
65
|
stack(panel("Coin", coin)),
|
|
66
66
|
stack(panel("Result", verdict), stats)
|
|
67
67
|
),
|
|
68
|
-
foot: actions(resetButton, flipButton)
|
|
69
|
-
});
|
|
68
|
+
foot: actions(resetButton, flipButton)});
|
|
70
69
|
slot.append(card.node);
|
|
71
70
|
render("");
|
|
72
71
|
|
|
73
72
|
return {
|
|
74
73
|
unmount() {
|
|
75
74
|
clearTimeout(timer);
|
|
76
|
-
}
|
|
77
|
-
};
|
|
75
|
+
}};
|
|
78
76
|
}
|
|
79
77
|
|
|
80
78
|
export default { mount };
|
|
@@ -70,12 +70,12 @@ function luminance({ r, g, b }) {
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
export function mount(slot) {
|
|
73
|
-
const anyField = textInput({ value: "#F5B942",
|
|
73
|
+
const anyField = textInput({ value: "#F5B942", mono: true, "aria-label": "Any color" });
|
|
74
74
|
const picker = colorInput({ value: "#f5b942", "aria-label": "Pick a color" });
|
|
75
|
-
const swatch = el("div", { class: "
|
|
75
|
+
const swatch = el("div", { class: "h-14 rounded-r1 border border-orbit-hard bg-deck-2" });
|
|
76
76
|
|
|
77
77
|
const readonly = (label) => {
|
|
78
|
-
const field = textInput({ readonly: true,
|
|
78
|
+
const field = textInput({ readonly: true, mono: true, "aria-label": `${label}, press to copy` });
|
|
79
79
|
const wrap = panel(label, field);
|
|
80
80
|
wrap.style.cursor = "pointer";
|
|
81
81
|
wrap.addEventListener("click", async () => {
|
|
@@ -91,7 +91,7 @@ export function mount(slot) {
|
|
|
91
91
|
const cssField = readonly("CSS variable");
|
|
92
92
|
|
|
93
93
|
const error = notice("error");
|
|
94
|
-
const reading = el("p", { class: "
|
|
94
|
+
const reading = el("p", { class: "border-s-[3px] border-transparent ps-2 text-sm text-ink-3" });
|
|
95
95
|
|
|
96
96
|
// `from` names the control the value came from. The text field is never
|
|
97
97
|
// rewritten while it is being typed into: "#abc" is valid shorthand one
|
|
@@ -136,14 +136,13 @@ export function mount(slot) {
|
|
|
136
136
|
const card = toolcard({
|
|
137
137
|
body: bench(
|
|
138
138
|
stack(
|
|
139
|
-
panel("Color", el("div", { class: "
|
|
139
|
+
panel("Color", el("div", { class: "flex min-w-0 flex-wrap items-center gap-2" }, picker, anyField)),
|
|
140
140
|
error,
|
|
141
141
|
panel(null, swatch),
|
|
142
142
|
reading
|
|
143
143
|
),
|
|
144
144
|
stack(hexField, rgbField, hslField, cssField)
|
|
145
|
-
)
|
|
146
|
-
});
|
|
145
|
+
)});
|
|
147
146
|
slot.append(card.node);
|
|
148
147
|
read("#F5B942", "init");
|
|
149
148
|
|
|
@@ -59,7 +59,7 @@ function palette(hex, scheme) {
|
|
|
59
59
|
|
|
60
60
|
export function mount(slot) {
|
|
61
61
|
const picker = colorInput({ value: "#f5b942", "aria-label": "Base color" });
|
|
62
|
-
const swatches = el("div", { class: "
|
|
62
|
+
const swatches = el("div", { class: "grid gap-2 [grid-template-columns:repeat(auto-fit,minmax(96px,1fr))]" });
|
|
63
63
|
let colors = [];
|
|
64
64
|
let scheme = "analogous";
|
|
65
65
|
|
|
@@ -67,8 +67,7 @@ export function mount(slot) {
|
|
|
67
67
|
[
|
|
68
68
|
{ value: "analogous", label: "Analogous" },
|
|
69
69
|
{ value: "complementary", label: "Complementary" },
|
|
70
|
-
{ value: "monochrome", label: "Monochrome" },
|
|
71
|
-
],
|
|
70
|
+
{ value: "monochrome", label: "Monochrome" }],
|
|
72
71
|
{ value: scheme, label: "Scheme", onChange: (value) => { scheme = value; paint(); } }
|
|
73
72
|
);
|
|
74
73
|
|
|
@@ -82,9 +81,9 @@ export function mount(slot) {
|
|
|
82
81
|
...colors.map((hex) =>
|
|
83
82
|
el(
|
|
84
83
|
"button",
|
|
85
|
-
{ class: "
|
|
86
|
-
el("span", { class: "
|
|
87
|
-
el("span", { class: "
|
|
84
|
+
{ class: "grid cursor-pointer gap-1.5 rounded-r1 border border-orbit bg-deck p-2 text-start transition-colors duration-150 hover:border-jade", type: "button", onclick: () => copyOne(hex) },
|
|
85
|
+
el("span", { class: "h-[52px] rounded-lg border border-orbit-hard", style: `background:${hex}` }),
|
|
86
|
+
el("span", { class: "font-mono text-2xs text-ink-2" }, hex)
|
|
88
87
|
)
|
|
89
88
|
)
|
|
90
89
|
);
|
|
@@ -99,8 +98,7 @@ export function mount(slot) {
|
|
|
99
98
|
),
|
|
100
99
|
foot: actions(
|
|
101
100
|
copyButton(() => colors.map((hex, i) => `--color-${i + 1}: ${hex};`).join("\n"), "Copy CSS variables", "fill")
|
|
102
|
-
)
|
|
103
|
-
});
|
|
101
|
+
)});
|
|
104
102
|
slot.append(card.node);
|
|
105
103
|
paint();
|
|
106
104
|
|
|
@@ -32,13 +32,13 @@ function toHsl({ r, g, b }) {
|
|
|
32
32
|
|
|
33
33
|
export function mount(slot) {
|
|
34
34
|
const picker = colorInput({ value: "#f5b942", "aria-label": "Pick a color" });
|
|
35
|
-
const hexInput = textInput({ value: "#F5B942",
|
|
36
|
-
const swatch = el("div", { class: "
|
|
35
|
+
const hexInput = textInput({ value: "#F5B942", mono: true, "aria-label": "Hex value" });
|
|
36
|
+
const swatch = el("div", { class: "h-14 rounded-r1 border border-orbit-hard bg-deck-2" });
|
|
37
37
|
const error = notice("error");
|
|
38
38
|
let current = "#f5b942";
|
|
39
39
|
|
|
40
40
|
const readonly = (label) => {
|
|
41
|
-
const field = textInput({ readonly: true,
|
|
41
|
+
const field = textInput({ readonly: true, mono: true, "aria-label": `${label}, press to copy` });
|
|
42
42
|
const wrap = panel(label, field);
|
|
43
43
|
wrap.style.cursor = "pointer";
|
|
44
44
|
wrap.addEventListener("click", async () => {
|
|
@@ -82,8 +82,7 @@ export function mount(slot) {
|
|
|
82
82
|
foot: actions(
|
|
83
83
|
copyButton(() => `--color: ${current};`, "Copy CSS"),
|
|
84
84
|
copyButton(() => current, "Copy hex", "fill")
|
|
85
|
-
)
|
|
86
|
-
});
|
|
85
|
+
)});
|
|
87
86
|
slot.append(card.node);
|
|
88
87
|
read("#F5B942", false);
|
|
89
88
|
|
|
@@ -19,7 +19,7 @@ export function mount(slot) {
|
|
|
19
19
|
{ value: "Idea", label: "Status", onChange: (next) => { status = next; } }
|
|
20
20
|
);
|
|
21
21
|
|
|
22
|
-
const listWrap = el("div", { class: "
|
|
22
|
+
const listWrap = el("div", { class: "max-h-80 overflow-auto" });
|
|
23
23
|
const addButton = button("Add", { icon: "plus", kind: "fill" });
|
|
24
24
|
|
|
25
25
|
const save = () => writePin(PIN, { entries });
|
|
@@ -46,7 +46,7 @@ export function mount(slot) {
|
|
|
46
46
|
el("td", {}, entry.platform || ""),
|
|
47
47
|
el("td", {}, entry.status),
|
|
48
48
|
el("td", {}, removeButton(entry))));
|
|
49
|
-
listWrap.replaceChildren(el("table", { class: "
|
|
49
|
+
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" },
|
|
50
50
|
el("thead", {}, el("tr", {},
|
|
51
51
|
el("th", {}, "Date"), el("th", {}, "Topic"), el("th", {}, "Platform"), el("th", {}, "Status"), el("th", {}, ""))),
|
|
52
52
|
el("tbody", {}, ...rows)));
|
|
@@ -100,8 +100,7 @@ export function mount(slot) {
|
|
|
100
100
|
downloadButton(() => csv(), "content-calendar.csv", "Save CSV", "text/csv"),
|
|
101
101
|
downloadButton(() => markdown(), "content-calendar.md", "Save Markdown", "text/markdown"),
|
|
102
102
|
addButton
|
|
103
|
-
)
|
|
104
|
-
});
|
|
103
|
+
)});
|
|
105
104
|
slot.append(card.node);
|
|
106
105
|
render();
|
|
107
106
|
|
|
@@ -31,19 +31,19 @@ export function mount(slot) {
|
|
|
31
31
|
const bgPicker = colorInput({ value: "#ffffff", "aria-label": "Background color" });
|
|
32
32
|
|
|
33
33
|
const kvRow = (key) => {
|
|
34
|
-
const value = el("span", { class: "
|
|
35
|
-
return { v: value, node: el("div", { class: "
|
|
34
|
+
const value = el("span", { class: "wrap-anywhere font-mono text-2xs" }, "-");
|
|
35
|
+
return { v: value, node: el("div", { class: "grid gap-3 bg-deck px-3 py-[9px] [grid-template-columns:minmax(90px,34%)_minmax(0,1fr)]" }, el("span", { class: "wrap-anywhere text-2xs font-semibold text-ink-2" }, key), value) };
|
|
36
36
|
};
|
|
37
37
|
const ratioRow = kvRow("Contrast ratio");
|
|
38
38
|
const normalAA = kvRow("Normal text AA");
|
|
39
39
|
const normalAAA = kvRow("Normal text AAA");
|
|
40
40
|
const largeAA = kvRow("Large text AA");
|
|
41
41
|
const largeAAA = kvRow("Large text AAA");
|
|
42
|
-
const list = el("div", { class: "
|
|
42
|
+
const list = el("div", { class: "grid gap-px overflow-hidden rounded-r1 border border-orbit bg-orbit" }, ratioRow.node, normalAA.node, normalAAA.node, largeAA.node, largeAAA.node);
|
|
43
43
|
|
|
44
44
|
const sample = el(
|
|
45
45
|
"div",
|
|
46
|
-
{ class: "
|
|
46
|
+
{ class: "w-full rounded-lg border border-orbit bg-deck px-[18px] py-4" },
|
|
47
47
|
el("p", { style: "margin:0 0 8px;font-size:20px;font-weight:700" }, "Large text sample"),
|
|
48
48
|
el("p", { style: "margin:0;font-size:15px" }, "Normal text sample for the contrast reading.")
|
|
49
49
|
);
|
|
@@ -82,8 +82,7 @@ export function mount(slot) {
|
|
|
82
82
|
stack(panel("Text color", textPicker), panel("Background color", bgPicker)),
|
|
83
83
|
stack(sample, list)
|
|
84
84
|
),
|
|
85
|
-
foot: actions(swap, copyButton(() => reading, "Copy result", "fill"))
|
|
86
|
-
});
|
|
85
|
+
foot: actions(swap, copyButton(() => reading, "Copy result", "fill"))});
|
|
87
86
|
slot.append(card.node);
|
|
88
87
|
update();
|
|
89
88
|
|
|
@@ -38,8 +38,7 @@ const FIELDS = [
|
|
|
38
38
|
["hour", "Hour", "0-23", "*"],
|
|
39
39
|
["day", "Day of month", "1-31", "*"],
|
|
40
40
|
["month", "Month", "1-12", "*"],
|
|
41
|
-
["weekday", "Day of week", "0-6", "*"]
|
|
42
|
-
];
|
|
41
|
+
["weekday", "Day of week", "0-6", "*"]];
|
|
43
42
|
|
|
44
43
|
export function mount(slot) {
|
|
45
44
|
const inputs = {};
|
|
@@ -49,8 +48,8 @@ export function mount(slot) {
|
|
|
49
48
|
return panel(label, input, hint);
|
|
50
49
|
});
|
|
51
50
|
|
|
52
|
-
const expression = textInput({ readonly: true,
|
|
53
|
-
const reading = el("p", { class: "
|
|
51
|
+
const expression = textInput({ readonly: true, mono: true, "aria-label": "Cron expression" });
|
|
52
|
+
const reading = el("p", { class: "border-s-[3px] border-transparent ps-2 text-sm text-ink-3" });
|
|
54
53
|
const error = notice("error");
|
|
55
54
|
|
|
56
55
|
function run() {
|
|
@@ -80,8 +79,7 @@ export function mount(slot) {
|
|
|
80
79
|
stack(...controls, error),
|
|
81
80
|
stack(panel("Expression", expression), panel("Reading", reading))
|
|
82
81
|
),
|
|
83
|
-
foot: actions(reset, copyButton(() => expression.value, "Copy expression", "fill"))
|
|
84
|
-
});
|
|
82
|
+
foot: actions(reset, copyButton(() => expression.value, "Copy expression", "fill"))});
|
|
85
83
|
slot.append(card.node);
|
|
86
84
|
run();
|
|
87
85
|
|
|
@@ -3,11 +3,11 @@ import { el, bench, stack, rangeInput, output, copyButton, actions, toolcard } f
|
|
|
3
3
|
|
|
4
4
|
function slider(label, { min, max, step, value, unit }) {
|
|
5
5
|
const input = rangeInput({ min, max, step, value, "aria-label": label });
|
|
6
|
-
const val = el("span", { class: "
|
|
6
|
+
const val = el("span", { class: "text-end font-mono text-2xs text-ink-2" }, `${value}${unit}`);
|
|
7
7
|
const node = el(
|
|
8
8
|
"div",
|
|
9
|
-
{ class: "
|
|
10
|
-
el("span", { class: "
|
|
9
|
+
{ class: "grid items-center gap-2.5 [grid-template-columns:88px_minmax(0,1fr)_62px] max-[45rem]:[grid-template-columns:minmax(0,1fr)_62px]" },
|
|
10
|
+
el("span", { class: "text-2xs font-semibold text-ink-2 max-[45rem]:col-span-2" }, label),
|
|
11
11
|
input,
|
|
12
12
|
val
|
|
13
13
|
);
|
|
@@ -24,7 +24,7 @@ export function mount(slot) {
|
|
|
24
24
|
|
|
25
25
|
const sample = el(
|
|
26
26
|
"div",
|
|
27
|
-
{ class: "
|
|
27
|
+
{ class: "w-full rounded-lg border border-orbit bg-deck px-[18px] py-4" },
|
|
28
28
|
el("p", { style: "margin:0" }, "The quick brown fox jumps over the lazy dog.")
|
|
29
29
|
);
|
|
30
30
|
const code = output();
|
|
@@ -55,8 +55,7 @@ export function mount(slot) {
|
|
|
55
55
|
stack(min, preferred, max),
|
|
56
56
|
stack(sample, code)
|
|
57
57
|
),
|
|
58
|
-
foot: actions(copyButton(() => `font-size: ${clampValue()};`, "Copy CSS", "fill"))
|
|
59
|
-
});
|
|
58
|
+
foot: actions(copyButton(() => `font-size: ${clampValue()};`, "Copy CSS", "fill"))});
|
|
60
59
|
slot.append(card.node);
|
|
61
60
|
update();
|
|
62
61
|
|