Last active
November 3, 2025 16:20
-
-
Save thegedge/491768543f5b7bffa2f51ee6b59b3db2 to your computer and use it in GitHub Desktop.
Generator-based TUI exploration
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const Root = () => Row( | |
| Logo, | |
| Column( | |
| Row(Spinner, "Loading..."), | |
| "Press q to quit", | |
| ), | |
| ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| export const Row = (...children: Element[]) => { | |
| return styled({ display: "flex", flexDirection: "row", gap: 1 }, children); | |
| }; | |
| export const Column = (...children: Element[]) => { | |
| return styled({ display: "flex", flexDirection: "column", gap: 1 }, children); | |
| }; | |
| // `styled` is the way we can inform the renderer of layout things, allowing components to remain more "pure" | |
| // | |
| // If you did want to pass in "props" to a component, just add more arguments! | |
| // You're in control, because this is just regular JavaScript. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const Spinner = async function* (frames = DEFAULT_FRAMES) { | |
| for (let frameIndex = 0; ; frameIndex = ++frameIndex % frames.length) { | |
| yield frames[frameIndex]; | |
| await new Promise((resolve) => setTimeout(resolve, 100)); | |
| } | |
| }; | |
| // No "re-render", so all the vars exist for the lifetime of the component | |
| // (i.e., no need for `useState` / `useMemo`) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| export const Spinner = (props: { frames?: string[] }) => { | |
| const frames = props.frames ?? DEFAULT_FRAMES; | |
| const [frameIndex, setFrameIndex] = useState(0); | |
| useEffect(() => { | |
| const interval = setInterval(() => { | |
| setFrameIndex((frameIndex + 1) % frames.length); | |
| }, 100); | |
| return () => clearInterval(interval); | |
| }); | |
| return <>frames[frameIndex]</>; | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment