ecklf 1.0.0 → 1.0.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/dist/App.js +1 -1
- package/dist/Greeting.js +38 -39
- package/dist/cli.js +1 -1
- package/package.json +1 -1
package/dist/App.js
CHANGED
|
@@ -79,7 +79,7 @@ export const App = () => {
|
|
|
79
79
|
const d = data;
|
|
80
80
|
const projects = d.projects;
|
|
81
81
|
const current = projects[selected];
|
|
82
|
-
return (_jsxs(Box, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [_jsxs(Box, { flexDirection: "row", children: [_jsxs(Box, { flexDirection: "column", flexGrow: 1,
|
|
82
|
+
return (_jsxs(Box, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [_jsxs(Box, { flexDirection: "row", children: [_jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [_jsx(Box, { height: 1, children: _jsx(Greeting, {}) }), _jsx(Text, { bold: true, color: "whiteBright", children: d.name }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { color: "gray", children: d.tagline }), _jsx(Text, { color: "gray", children: d.subtitle })] })] }), _jsx(Box, { width: 28, height: 14, justifyContent: "flex-end", children: _jsx(Knot, { cols: 26, rows: 14 }) })] }), _jsxs(Box, { marginTop: 1, marginBottom: 1, children: [_jsx(Text, { bold: true, color: "whiteBright", children: "Projects" }), _jsxs(Text, { color: "gray", children: [" ", d.source === "live" ? "● live" : "○ offline"] })] }), _jsx(Box, { flexDirection: "column", children: projects.map((p, i) => {
|
|
83
83
|
const active = i === selected;
|
|
84
84
|
return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { children: [_jsx(Text, { color: active ? ACCENT : "gray", children: active ? "❯ " : " " }), _jsx(Text, { bold: true, color: active ? "whiteBright" : "white", children: p.title })] }), active && (_jsx(Box, { marginLeft: 2, children: _jsx(Text, { color: "gray", dimColor: true, children: p.description }) }))] }, p.github));
|
|
85
85
|
}) }), mode === "action" && (_jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsxs(Text, { color: "gray", children: ["Open ", _jsx(Text, { color: "whiteBright", children: current.title }), " \u2192"] }), _jsxs(Box, { marginTop: 0, children: [_jsx(Text, { color: actionChoice === 0 ? "black" : ACCENT, backgroundColor: actionChoice === 0 ? ACCENT : undefined, children: " Website " }), _jsx(Text, { children: " " }), _jsx(Text, { color: actionChoice === 1 ? "black" : ACCENT, backgroundColor: actionChoice === 1 ? ACCENT : undefined, children: " GitHub " })] })] })), opened && mode === "list" && (_jsxs(Box, { marginTop: 1, children: [_jsx(Text, { color: "greenBright", children: "\u2197 opened " }), _jsx(Text, { color: "gray", children: opened })] })), _jsx(Box, { marginTop: 1, children: mode === "list" ? (_jsx(Text, { color: "gray", dimColor: true, children: "\u2191/\u2193 navigate \u00B7 \u21B5 open\u2026 \u00B7 w website \u00B7 g github \u00B7 q quit" })) : (_jsx(Text, { color: "gray", dimColor: true, children: "\u2190/\u2192 choose \u00B7 \u21B5 confirm \u00B7 esc back" })) })] }));
|
package/dist/Greeting.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useEffect, useRef, useState } from "react";
|
|
3
2
|
import { Text } from "ink";
|
|
3
|
+
import { useClock } from "./hooks.js";
|
|
4
4
|
// Multi-language greetings, cycled with a typewriter effect — mirrors the
|
|
5
5
|
// animated headline on ecklf.com.
|
|
6
6
|
const GREETINGS = [
|
|
@@ -17,46 +17,45 @@ const GREETINGS = [
|
|
|
17
17
|
"Hej",
|
|
18
18
|
"Merhaba",
|
|
19
19
|
];
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
setPhase("holding");
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
else if (phase === "holding") {
|
|
45
|
-
schedule(() => setPhase("deleting"), 1400);
|
|
46
|
-
}
|
|
47
|
-
else {
|
|
48
|
-
if (text.length > 0) {
|
|
49
|
-
schedule(() => setText(word.slice(0, text.length - 1)), 45);
|
|
20
|
+
const TYPE_MS = 110; // per character while typing
|
|
21
|
+
const DELETE_MS = 50; // per character while deleting
|
|
22
|
+
const HOLD_MS = 1300; // pause once fully typed
|
|
23
|
+
/**
|
|
24
|
+
* Derive the typewriter state purely from elapsed time. Driven by a single
|
|
25
|
+
* clock so there is no setTimeout/re-render race.
|
|
26
|
+
*/
|
|
27
|
+
function compute(ms) {
|
|
28
|
+
let t = ms;
|
|
29
|
+
let i = 0;
|
|
30
|
+
// Walk through words until we land inside the current cycle.
|
|
31
|
+
// Guard against runaway loops by bounding iterations.
|
|
32
|
+
for (let guard = 0; guard < 100000; guard++) {
|
|
33
|
+
const word = GREETINGS[i % GREETINGS.length];
|
|
34
|
+
const typeDur = word.length * TYPE_MS;
|
|
35
|
+
const deleteDur = word.length * DELETE_MS;
|
|
36
|
+
const cycle = typeDur + HOLD_MS + deleteDur;
|
|
37
|
+
if (t < cycle) {
|
|
38
|
+
if (t < typeDur) {
|
|
39
|
+
const chars = Math.floor(t / TYPE_MS) + 1;
|
|
40
|
+
return { text: word.slice(0, Math.min(chars, word.length)), word };
|
|
50
41
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
setPhase("typing");
|
|
42
|
+
if (t < typeDur + HOLD_MS) {
|
|
43
|
+
return { text: word, word };
|
|
54
44
|
}
|
|
45
|
+
const dt = t - typeDur - HOLD_MS;
|
|
46
|
+
const removed = Math.floor(dt / DELETE_MS) + 1;
|
|
47
|
+
const len = Math.max(0, word.length - removed);
|
|
48
|
+
return { text: word.slice(0, len), word };
|
|
55
49
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
50
|
+
t -= cycle;
|
|
51
|
+
i++;
|
|
52
|
+
}
|
|
53
|
+
return { text: "", word: GREETINGS[0] };
|
|
54
|
+
}
|
|
55
|
+
export const Greeting = () => {
|
|
56
|
+
const seconds = useClock(20);
|
|
57
|
+
const ms = seconds * 1000;
|
|
58
|
+
const { text } = compute(ms);
|
|
59
|
+
const cursorOn = Math.floor(seconds * 2) % 2 === 0;
|
|
61
60
|
return (_jsxs(Text, { bold: true, color: "white", children: [text, _jsx(Text, { color: "cyanBright", children: cursorOn ? "▋" : " " })] }));
|
|
62
61
|
};
|
package/dist/cli.js
CHANGED
package/package.json
CHANGED