Skip to content

colinta/TeaUI

Repository files navigation

TeaUI

I wanted a curses-style fullscreen application framework that could be powered by React.

This repo is organized as a pnpm workspace. The main library is in packages/core, and the demo code is in apps/demo. There are also React and Preact renderers.

Demo: components

pnpm demo components

example of output

Demo: colors.ts

pnpm demo colors

example of output

Demo: inputs.ts

pnpm demo inputs.ts

example of output

Example using React

I'll use TypeScript's JSX support here, if you want to use something else go ahead.

tsconfig.json
{
  "include": ["./"],
  "exclude": [".dist/"],
  "compilerOptions": {
    "target": "esnext",
    "module": "commonjs",
    "moduleResolution": "node",
    "declaration": true,
    "sourceMap": true,
    "strict": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "noImplicitAny": true,
    "skipLibCheck": true,
    "allowJs": true,
    "outDir": ".dist",
    "jsx": "react"
  }
}
pnpm install @teaui/core @teaui/react react @types/react
index.tsx
import React, {useReducer} from 'react'
import {interceptConsoleLog} from '@teaui/core'
import {
  Box,
  Button,
  Stack,
  run,
} from '@teaui/react'

// Recommended:
interceptConsoleLog()

function App() {
  const [bang, goto10] = useReducer((state) => state + '!', '')

  return (
    <Box border="single">
      <Stack.down>
        First there was Ncurses{bang}
        <Button onClick={goto10}>Tell me more!</Button>
      </Stack.down>
    </Box>
  )
}

run(<App />)
pnpm tsc
node .dist/index.js

Example using core library

example.js
import {Screen, Box, Stack, Text, Button, interceptConsoleLog} from '@teaui/core'

// Recommended:
interceptConsoleLog()
// While the terminal is in full screen mode, you probably don't want to log
// debug info to stdout - it will appear wherever the cursor happens to be,
// and will clobber your output. You can mount the <ConsoleLog /> to view logs,
// otherwise when you exit (Ctrl-C) the logs will be flushed to stdout.

Screen.start(
  new Box({
    border: 'single',
    children: [
      Stack.down([
        new Text({text: 'Why is it called TeaUI?'}),
        new Button({title: 'Tell me!'}),
      ]),
    ],
  }),
)

Zero dependencies 🤔

Rather than including depencies like a reasonable person, I copied the code I needed (and their licenses, of course). I put these dependencies in as optionalDependencies so they still get the npm backlinks. I'm not stuck on having a zero-dependencies package, it's just how I did it. Let me know what you think in the comments section.

TODO / Improvements

get-east-asian-width is a much newer package, and sindresorhus is a prolific writer of terminal-related code, so switching to that seems like a good idea. YAGNI for now, but it's on the list.

Blessed is a very powerful library, but I'm not using ~80-90% of it. All I really need is goto XY, writeChar, flush along with the code that sets up raw-mode, mouse-events, resize events, etc. termbox2 maybe?

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 3

  •  
  •  
  •