Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions apps/web/app/docs/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const SECTIONS = [
{ id: "graphics", label: "Graphics" },
{ id: "themes", label: "Themes" },
{ id: "icons", label: "Icons" },
{ id: "emoji", label: "Emoji" },
{ id: "input", label: "Input" },
{ id: "testing", label: "Testing" },
{ id: "escape-hatches", label: "Escape hatches" },
Expand Down Expand Up @@ -361,6 +362,48 @@ setIconMode("nerd"); // for the whole app`}
<code className="font-mono text-white/80">hqtui.icon(&quot;mail&quot;)</code>.
</P>

<H2 id="emoji">Emoji</H2>
<P>
The <a className="underline" href="https://logicsrc.com/openemoji">OpenEmoji</a> pack is built in and
on by default: every standard emoji, 3,963 in Emoji 18.0, with its CLDR name, an{" "}
<code className="font-mono text-white/80">oe_</code> shortcode and search keywords.{" "}
<code className="font-mono text-white/80">emoji()</code> is the emoji where the terminal draws emoji and readable text where it
cannot: an emoticon where one fits, the name in brackets elsewhere.
</P>
<Code
className="mt-4"
code={`import { emoji, emojify, emojiSearch, setEmojiMode } from "@profullstack/hqtui";

ui.text(\`\${emoji("rocket")} shipped\`); // ๐Ÿš€ shipped [rocket] shipped as text
ui.text(emojify("deploy :tada: :+1:")); // deploy ๐ŸŽ‰ ๐Ÿ‘ deploy [party popper] +1
emoji("thumbs_up_t3"); // ๐Ÿ‘๐Ÿฝ skin tones are _t1 โ€ฆ _t5
emojiSearch("lol")[0].char; // ๐Ÿ˜‚ CLDR keywords
setEmojiMode("text"); // or HQTUI_EMOJI=emoji|text`}
/>
<P>
A name can be the shortcode (<code className="font-mono text-white/80">fire</code>, <code className="font-mono text-white/80">oe_fire</code>,{" "}
<code className="font-mono text-white/80">:fire:</code>), the CLDR name, a common alias (<code className="font-mono text-white/80">thumbsup</code>,{" "}
<code className="font-mono text-white/80">+1</code>) or the emoji itself. <code className="font-mono text-white/80">stringWidth</code> counts every emoji as two
columns, skin tones, flags, keycaps and ZWJ sequences included, so tables and borders stay aligned in
every port.
</P>
<P>
<strong>Our artwork in your terminal.</strong> A TUI cannot pick the terminal&apos;s font, so{" "}
<code className="font-mono text-white/80">hqtui fonts install</code> installs the OpenEmoji colour font and makes it the emoji
fallback: fontconfig on Linux (Alacritty, foot, GNOME Terminal and Konsole follow it; Kitty and WezTerm
get a one-line snippet) and <code className="font-mono text-white/80">~/Library/Fonts</code> on macOS, where Kitty, WezTerm and iTerm2
can use it and Terminal.app cannot. <code className="font-mono text-white/80">hqtui fonts status</code> checks it;{" "}
<code className="font-mono text-white/80">hqtui fonts remove</code> undoes it. Nothing is installed except by that command.
</P>
<P>
<strong>Inline artwork.</strong> With <code className="font-mono text-white/80">HQTUI_EMOJI_ART=1</code>,{" "}
<code className="font-mono text-white/80">await emojiImage(&quot;rocket&quot;)</code> draws the OpenEmoji PNG two cells wide in
Kitty and Ghostty (Kitty graphics) and iTerm2 and WezTerm (inline images), picking 128, 256 or 512 px
at twice the cell height, and falls back to the character everywhere else. In a browser terminal, load{" "}
<code className="font-mono text-white/80">openemoji.css</code> from the set and add <code className="font-mono text-white/80">OpenEmoji</code> to xterm.js&apos;s{" "}
<code className="font-mono text-white/80">fontFamily</code>.
</P>

<H2 id="input">Input</H2>
<P>
Keys arrive normalized โ€” <code className="font-mono text-white/80">&quot;ctrl+c&quot;</code>,{" "}
Expand Down
49 changes: 49 additions & 0 deletions packages/hqtui/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,55 @@ falls back to Unicode, and an unknown name draws nothing. `useIconPack()` swaps
in any other OpenIcon set. The table is generated from the set by
`scripts/generate-icons.ts`, for this library and the Rust, Go and Python ports.

## Emoji

The [OpenEmoji](https://logicsrc.com/openemoji) pack is built in and on by
default: every standard emoji (3,963 in Emoji 18.0) with its CLDR name, an
`oe_` shortcode and search keywords. `emoji()` is the emoji where the terminal
draws emoji and readable text where it cannot.

```ts
import { emoji, emojify, emojiSearch } from "@profullstack/hqtui";

ui.text(`${emoji("rocket")} shipped`); // ๐Ÿš€ shipped ([rocket] shipped as text)
ui.text(emojify("deploy :tada: :+1:")); // deploy ๐ŸŽ‰ ๐Ÿ‘ (deploy [party popper] +1)
emoji("thumbs_up_t3"); // ๐Ÿ‘๐Ÿฝ skin tones are _t1 โ€ฆ _t5
emojiSearch("lol")[0].char; // ๐Ÿ˜‚ CLDR keywords
```

A name can be the shortcode (`fire`, `oe_fire`, `:fire:`), the CLDR name, a
common alias (`thumbsup`, `+1`, `heart`) or the emoji itself. Text mode is an
emoticon where one fits (`:)`, `<3`, `:D`) and the name in brackets elsewhere;
it is chosen with `setEmojiMode()`, `HQTUI_EMOJI=emoji|text`, or detected (the
Linux console gets text). `stringWidth` counts every emoji as two columns,
skin tones, flags, keycaps and ZWJ sequences included, so tables and borders
stay aligned. The Rust, Go and Python ports carry the same table.

**Our artwork in your terminal.** A TUI cannot pick the terminal's font, so
`hqtui fonts install` installs the OpenEmoji colour font and makes it the
emoji fallback: fontconfig on Linux (Alacritty, foot, GNOME Terminal, Konsole
and others follow it; Kitty and WezTerm get a one-line snippet), and
`~/Library/Fonts` on macOS, where Kitty, WezTerm and iTerm2 can use it and
Terminal.app cannot. `hqtui fonts status` checks it, and `hqtui fonts remove`
undoes everything, restoring any file it replaced. Nothing is installed except
by that command.

**Inline artwork.** In terminals that show images, `await emojiImage("rocket")`
returns the escape sequence that draws the OpenEmoji PNG two cells wide: the
Kitty graphics protocol in Kitty and Ghostty, iTerm2 inline images in iTerm2
and WezTerm. It is off unless `HQTUI_EMOJI_ART=1` (or `{ art: true }`); the PNG
is picked from 128, 256 and 512 px at twice the cell height
(`queryCellSize()` or `HQTUI_CELL_PX=10x20`) and cached under
`~/.cache/hqtui/openemoji`. Everywhere else it returns the emoji character.

**In a browser terminal** (xterm.js), load the set's stylesheet and name the
family, so emoji draw with the same art:

```html
<link rel="stylesheet" href="https://raw.githubusercontent.com/profullstack/openemoji/main/openemoji.css">
<script>new Terminal({ fontFamily: '"JetBrains Mono", OpenEmoji, monospace' })</script>
```

## Testing your TUI

Terminal apps are usually untestable. Here they are not:
Expand Down
Loading
Loading