ntemoji

package module
v0.0.0-...-9bca157 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 25, 2026 License: MIT Imports: 7 Imported by: 0

README

ntemoji — Emoji picker and swatch keyboard overlay for Bubble Tea

Latest Release GoDoc Code Of Conduct

ntemoji is a Bubble Tea widget that provides a keyboard- and mouse-enabled emoji picker overlay keypad for terminal user interfaces (TUIs).

It features curated categories of TUI-safe, highly compatible emojis, support for custom palettes, search/filter capabilities, preset shortcuts, and positioning integration via bubble-overlay and bubblezone.

Try out the live WASM demo.

This module was inspired by the @madicen's bubble-color-picker library.

Quickstart

package main

import (
	"fmt"
	"os"

	"github.com/NimbleMarkets/ntemoji"
	tea "github.com/charmbracelet/bubbletea"
	zone "github.com/lrstanley/bubblezone"
)

type model struct {
	picker ntemoji.Model
	zm     *zone.Manager
}

func (m model) Init() tea.Cmd { return nil }

func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
	switch msg := msg.(type) {
	case tea.KeyMsg:
		if msg.String() == "q" || msg.String() == "ctrl+c" {
			return m, tea.Quit
		}
	case ntemoji.EmojiChangedMsg:
		fmt.Printf("Selected emoji: %s\n", msg.Emoji)
		return m, tea.Quit
	case ntemoji.EmojiCanceledMsg:
		return m, tea.Quit
	}

	var cmd tea.Cmd
	updated, cmd := m.picker.Update(msg)
	m.picker = updated.(ntemoji.Model)
	return m, cmd
}

func (m model) View() string {
	return m.zm.Scan(m.picker.View())
}

func main() {
	zm := zone.New()
	picker := ntemoji.New(
		ntemoji.WithInitialEmoji("🚀"),
		ntemoji.WithPresets([]string{"😀", "👍", "🔥", "✅", "❌"}),
		ntemoji.WithShowSearch(true),
	)
	picker.SetZoneManager(zm)

	p := tea.NewProgram(model{picker: picker, zm: zm}, tea.WithAltScreen(), tea.WithMouseAllMotion())
	if _, err := p.Run(); err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}

SwatchPicker (Popup Modal overlay)

The SwatchPicker is a small UI component representing the selected emoji with a dropdown arrow (e.g. 😀 ▼). Clicking it opens the full emoji keyboard popup centered on the button.

  1. Create the swatch: swatch := ntemoji.NewSwatchPicker("🚀", "Trigger")
  2. Setup bubblezone: swatch.SetZoneManager(zm)
  3. Set bounds & render: call swatch.SetBounds(row, col, width, height) and wrap with overlay rendering:
    mainView = swatch.ViewWithOverlay(mainView, width, height)
    return zm.Scan(mainView)
    
  4. Update: forward key and mouse events to the open swatch.

Keyboard & Mouse Interactions

  • Tab / Shift+Tab: Cycle focus among the Presets row, Search bar, Category selectors, and the Emoji grid.
  • Arrows / hjkl: Navigate selections within the active presets or the emoji grid. Changing focus to category selection and using ←/→ instantly switches category tabs.
  • Enter: Confirms the selected emoji and fires an EmojiChangedMsg.
  • Escape: Cancels selection and fires an EmojiCanceledMsg.
  • Mouse clicks: Clicking any category tab switches categories. Hovering over presets/grid items highlights them, and releasing the left-click selects the emoji.

Configuration Options

Construct the emoji picker with New(...Option):

Option Purpose
WithInitialEmoji(emoji) Sets the starting emoji (auto-focuses it in grid/presets).
WithPresets([]string) Shows a row of quick-select preset emojis above search/categories.
WithPalettes([]Palette) Supplies custom emoji lists and category tabs.
WithStyle(lipgloss.Style) Configures custom outer frame border and padding.
WithAutoDismiss(bool) When true, selection includes Dismiss: true to auto-hide the modal.
WithShowSearch(bool) Toggles the search input box for matching keywords.

TUI Emoji Compatibility & Box-Sizing

Emojis are generally 2 columns wide in terminal user interfaces. However, some emojis (such as those containing the variation selector \ufe0f, e.g., ⚠️ or 🌧️) report a width of 2 columns under standard Go string-width libraries (like Lip Gloss / uniseg), but render as only 1 column wide on standard terminal emulators.

When designing custom palettes or presets for terminal widgets like ntemoji, this discrepancy causes right-border layout alignment shifts (as the terminal renders the row narrower than Lip Gloss's box-sizing layout calculations).

To guarantee pixel-perfect rectangular borders in all terminal environments:

  • Only use standard 2-column emojis where lipgloss.Width and terminal rendering widths agree.
  • Avoid variation selectors (\ufe0f) in custom emoji palettes.
  • All default palettes in ntemoji are pre-curated to strictly include safe, matching 2-column emojis.

Demos

Built-in demo examples compile out-of-the-box:

# Run full-screen demo
task build-ex-simple
./bin/simple

# Run multi-swatch grid overlay demo
task build-ex-swatch
./bin/swatch

Vibe coded

This comment was inserted by a human. Except it wasn't, but then it was reviewed and I wrote this.

License

MIT License — Copyright (c) 2026 Neomantra Corp.


Made with ❤ and 🔥 by the team behind Nimble.Markets.

Documentation

Index

Constants

View Source
const (
	// === Smileys & Emotion ===
	EmojiGrinningFace      = "😀"
	EmojiGrinningWithEyes  = "😃"
	EmojiSmilingWithOpen   = "😄"
	EmojiGrinningSquinting = "😆"
	EmojiSmilingSweat      = "😅"
	EmojiTearsOfJoy        = "😂"
	EmojiRollingOnFloor    = "🤣"
	EmojiSmilingFace       = "😊"
	EmojiAngelFace         = "😇"
	EmojiSlightlySmiling   = "🙂"
	EmojiUpsideDown        = "🙃"
	EmojiWinkingFace       = "😉"
	EmojiRelievedFace      = "😌"
	EmojiHeartEyes         = "😍"
	EmojiSmilingWithHearts = "🥰"
	EmojiKissingFace       = "😘"
	EmojiThinkingFace      = "🤔"
	EmojiShushingFace      = "🤫"
	EmojiGrimacingFace     = "😬"
	EmojiZippedMouth       = "🤐"
	EmojiSweatFace         = "😓"
	EmojiCryingFace        = "😢"
	EmojiLoudlyCrying      = "😭"
	EmojiAngryFace         = "😠"
	EmojiRedAngryFace      = "😡"
	EmojiExplodingHead     = "🤯"
	EmojiHotFace           = "🥵"
	EmojiColdFace          = "🥶"
	EmojiSleepingFace      = "😴"
	EmojiNerdFace          = "🤓"
	EmojiCoolFace          = "😎"
	EmojiPartyFace         = "🥳"

	// === Hands & Gestures ===
	EmojiWave           = "👋"
	EmojiRaisedHand     = "✋"
	EmojiVulcanSalute   = "🖖"
	EmojiOkHand         = "👌"
	EmojiCrossedFingers = "🤞"
	EmojiThumbsUp       = "👍"
	EmojiThumbsDown     = "👎"
	EmojiClappingHands  = "👏"
	EmojiRaisedHands    = "🙌"
	EmojiFoldedHands    = "🙏"
	EmojiFlexedBiceps   = "💪"

	// === Animals & Nature ===
	EmojiCatFace       = "🐱"
	EmojiCat           = "🐈"
	EmojiDogFace       = "🐶"
	EmojiDog           = "🐕"
	EmojiFox           = "🦊"
	EmojiLion          = "🦁"
	EmojiTigerFace     = "🐯"
	EmojiMonkeyFace    = "🐵"
	EmojiCowFace       = "🐮"
	EmojiPigFace       = "🐷"
	EmojiFrog          = "🐸"
	EmojiOctopus       = "🐙"
	EmojiBee           = "🐝"
	EmojiBug           = "🐛"
	EmojiPenguin       = "🐧"
	EmojiOwl           = "🦉"
	EmojiTurtle        = "🐢"
	EmojiSnake         = "🐍"
	EmojiDolphin       = "🐬"
	EmojiTree          = "🌲"
	EmojiEvergreen     = "🌲"
	EmojiDeciduousTree = "🌳"
	EmojiCactus        = "🌵"
	EmojiMapleLeaf     = "🍁"
	EmojiSun           = "🌞"
	EmojiRainbow       = "🌈"
	EmojiSnowman       = "⛄"
	EmojiLightning     = "⚡"
	EmojiFire          = "🔥"
	EmojiWaterWave     = "🌊"
	EmojiGlobe         = "🌍"

	// === Food & Drink ===
	EmojiGreenApple   = "🍏"
	EmojiRedApple     = "🍎"
	EmojiBanana       = "🍌"
	EmojiWatermelon   = "🍉"
	EmojiGrapes       = "🍇"
	EmojiStrawberry   = "🍓"
	EmojiPizza        = "🍕"
	EmojiHamburger    = "🍔"
	EmojiFrenchFries  = "🍟"
	EmojiHotDog       = "🌭"
	EmojiTaco         = "🌮"
	EmojiPopcorn      = "🍿"
	EmojiRiceBall     = "🍙"
	EmojiSushi        = "🍣"
	EmojiIceCream     = "🍦"
	EmojiDoughnut     = "🍩"
	EmojiCookie       = "🍪"
	EmojiBirthdayCake = "🎂"
	EmojiCoffee       = "☕"
	EmojiTea          = "🍵"
	EmojiBeerMug      = "🍺"
	EmojiWineGlass    = "🍷"
	EmojiCocktail     = "🍸"

	// === Status, UI & Shapes ===
	EmojiCheckMarkButton = "✅"
	EmojiCrossMark       = "❌"
	EmojiWarning         = "🚨"
	EmojiInfo            = "📢"
	EmojiRedCircle       = "🔴"
	EmojiYellowCircle    = "🟡"
	EmojiGreenCircle     = "🟢"
	EmojiBlueCircle      = "🔵"
	EmojiPurpleCircle    = "🟣"
	EmojiBlackSquare     = "⬛"
	EmojiWhiteSquare     = "⬜"
	EmojiStopSign        = "🛑"
	EmojiConstruction    = "🚧"
	EmojiChequeredFlag   = "🏁"
	EmojiTriangularFlag  = "🚩"
	EmojiBell            = "🔔"
	EmojiMutedBell       = "🔕"
	EmojiMegaphone       = "📣"
	EmojiHourglass       = "⏳"
	EmojiHourglassEmpty  = "⌛"
	EmojiSpeechBalloon   = "💬"
	EmojiHeart           = "💖"
	EmojiBrokenHeart     = "💔"
	EmojiSparkles        = "✨"
	EmojiCollision       = "💥"
	EmojiRocket          = "🚀"

	// === Objects & Tools ===
	EmojiComputer        = "💻"
	EmojiDesktop         = "🖥️"
	EmojiFloppyDisk      = "💾"
	EmojiCamera          = "📷"
	EmojiFolder          = "📁"
	EmojiOpenFolder      = "📂"
	EmojiCalendar        = "📅"
	EmojiBarChart        = "📊"
	EmojiChartUp         = "📈"
	EmojiChartDown       = "📉"
	EmojiMemo            = "📝"
	EmojiEnvelope        = "📩"
	EmojiIncomingMail    = "📨"
	EmojiPackage         = "📦"
	EmojiGear            = "🔧"
	EmojiWrench          = "🔧"
	EmojiHammer          = "🔨"
	EmojiToolbox         = "🧰"
	EmojiKey             = "🔑"
	EmojiLock            = "🔒"
	EmojiUnlock          = "🔓"
	EmojiPaperclip       = "📎"
	EmojiLightBulb       = "💡"
	EmojiMagnifyingGlass = "🔍"

	// === Navigation ===
	EmojiArrowUp    = "🔼"
	EmojiArrowDown  = "🔽"
	EmojiArrowLeft  = "👈"
	EmojiArrowRight = "👉"
	EmojiRefresh    = "🔄"
)

Emoji constants for standard, widely supported TUI-friendly emojis. Using constants helps developers reference emojis programmatically by name.

NOTE: To ensure pixel-perfect TUI borders and layout alignment, all emojis defined here are strictly curated to have a visual width of 2 columns. Emojis containing variation selectors (like \ufe0f, e.g., ⚠️ or 🌧️) are avoided because they cause rendering conflicts: standard libraries (Lip Gloss / uniseg) report them as 2 columns, but terminal emulators render them as 1 column.

View Source
const (
	ZonePresets    = "picker-presets"
	ZoneCategories = "picker-categories"
	ZoneGrid       = "picker-grid"
	ZoneSearch     = "picker-search"
)

Variables

View Source
var DefaultPalettes = []Palette{
	{
		Name: "Smileys",
		Icon: EmojiGrinningFace,
		Emojis: []string{
			EmojiGrinningFace, EmojiGrinningWithEyes, EmojiSmilingWithOpen, EmojiGrinningSquinting,
			EmojiSmilingSweat, EmojiTearsOfJoy, EmojiRollingOnFloor, EmojiSmilingFace,
			EmojiAngelFace, EmojiSlightlySmiling, EmojiUpsideDown, EmojiWinkingFace,
			EmojiRelievedFace, EmojiHeartEyes, EmojiSmilingWithHearts, EmojiKissingFace,
			EmojiThinkingFace, EmojiShushingFace, EmojiGrimacingFace, EmojiZippedMouth,
			EmojiSweatFace, EmojiCryingFace, EmojiLoudlyCrying, EmojiAngryFace,
			EmojiRedAngryFace, EmojiExplodingHead, EmojiHotFace, EmojiColdFace,
			EmojiSleepingFace, EmojiNerdFace, EmojiCoolFace, EmojiPartyFace,
		},
	},
	{
		Name: "Gestures",
		Icon: EmojiThumbsUp,
		Emojis: []string{
			EmojiWave, EmojiRaisedHand, EmojiVulcanSalute, EmojiOkHand,
			EmojiCrossedFingers, EmojiThumbsUp, EmojiThumbsDown, EmojiClappingHands,
			EmojiRaisedHands, EmojiFoldedHands, EmojiFlexedBiceps,
		},
	},
	{
		Name: "Animals & Nature",
		Icon: EmojiCatFace,
		Emojis: []string{
			EmojiCatFace, EmojiCat, EmojiDogFace, EmojiDog,
			EmojiFox, EmojiLion, EmojiTigerFace, EmojiMonkeyFace,
			EmojiCowFace, EmojiPigFace, EmojiFrog, EmojiOctopus,
			EmojiBee, EmojiBug, EmojiPenguin, EmojiOwl,
			EmojiTurtle, EmojiSnake, EmojiDolphin, EmojiTree,
			EmojiDeciduousTree, EmojiCactus, EmojiMapleLeaf, EmojiSun,
			EmojiRainbow, EmojiSnowman, EmojiLightning, EmojiFire,
			EmojiWaterWave, EmojiGlobe,
		},
	},
	{
		Name: "Food & Drink",
		Icon: EmojiCoffee,
		Emojis: []string{
			EmojiGreenApple, EmojiRedApple, EmojiBanana, EmojiWatermelon,
			EmojiGrapes, EmojiStrawberry, EmojiPizza, EmojiHamburger,
			EmojiFrenchFries, EmojiHotDog, EmojiTaco, EmojiPopcorn,
			EmojiRiceBall, EmojiSushi, EmojiIceCream, EmojiDoughnut,
			EmojiCookie, EmojiBirthdayCake, EmojiCoffee, EmojiTea,
			EmojiBeerMug, EmojiWineGlass, EmojiCocktail,
		},
	},
	{
		Name: "Status & Shapes",
		Icon: EmojiGreenCircle,
		Emojis: []string{
			EmojiRedCircle, EmojiYellowCircle, EmojiGreenCircle, EmojiBlueCircle, EmojiPurpleCircle,
			EmojiBlackSquare, EmojiWhiteSquare, EmojiStopSign, EmojiConstruction,
			EmojiChequeredFlag, EmojiTriangularFlag, EmojiBell, EmojiMutedBell,
			EmojiMegaphone, EmojiHourglass, EmojiHourglassEmpty, EmojiSpeechBalloon,
			EmojiHeart, EmojiBrokenHeart, EmojiSparkles, EmojiCollision,
			EmojiRocket, EmojiCheckMarkButton, EmojiCrossMark, EmojiWarning, EmojiInfo,
		},
	},
	{
		Name: "Symbols & Tools",
		Icon: EmojiGear,
		Emojis: []string{
			EmojiGear, EmojiWrench, EmojiHammer, EmojiToolbox,
			EmojiKey, EmojiLock, EmojiUnlock, EmojiPackage,
			EmojiFolder, EmojiOpenFolder, EmojiCalendar, EmojiBarChart,
			EmojiChartUp, EmojiChartDown, EmojiMemo, EmojiEnvelope,
			EmojiIncomingMail, EmojiPaperclip, EmojiLightBulb, EmojiMagnifyingGlass,
		},
	},
	{
		Name: "Navigation",
		Icon: EmojiArrowRight,
		Emojis: []string{
			EmojiArrowUp, EmojiArrowDown, EmojiArrowLeft, EmojiArrowRight, EmojiRefresh,
		},
	},
}

DefaultPalettes is a list of curated TUI-safe emojis grouped by category.

View Source
var DefaultTheme = Theme{
	FrameBorder:      lipgloss.DoubleBorder(),
	FrameBorderColor: lipgloss.Color("93"),

	BorderFocusedColor:   lipgloss.Color("255"),
	BorderUnfocusedColor: lipgloss.Color("240"),

	TitleStyle: lipgloss.NewStyle().Bold(true),
	HelpStyle:  lipgloss.NewStyle().Foreground(lipgloss.Color("241")),

	ActiveTabStyle:   lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color("15")).Background(lipgloss.Color("57")),
	InactiveTabStyle: lipgloss.NewStyle().Foreground(lipgloss.Color("246")),

	SelectedCellStyle:          lipgloss.NewStyle().Background(lipgloss.Color("57")).Foreground(lipgloss.Color("255")).Bold(true),
	SelectedUnfocusedCellStyle: lipgloss.NewStyle().Background(lipgloss.Color("240")).Foreground(lipgloss.Color("255")),
	UnselectedCellStyle:        lipgloss.NewStyle(),
	SelectedPresetStyle:        lipgloss.NewStyle().Background(lipgloss.Color("238")).Foreground(lipgloss.Color("255")).Bold(true),
	UnselectedPresetStyle:      lipgloss.NewStyle(),

	SearchPromptStyle:      lipgloss.NewStyle().Foreground(lipgloss.Color("93")),
	SearchTextStyle:        lipgloss.NewStyle(),
	SearchPlaceholderStyle: lipgloss.NewStyle().Foreground(lipgloss.Color("240")),
	SearchCursorStyle:      lipgloss.NewStyle().Foreground(lipgloss.Color("93")),
}

DefaultTheme provides a dark, purple-accented modern theme.

View Source
var EmojiTags = map[string][]string{}/* 105 elements not displayed */

EmojiTags maps common emojis to searchable keywords.

Functions

func CellInModal

func CellInModal(x, y, top, left, width, height int) bool

CellInModal returns true if the coordinate (x, y) falls inside the modal bounds.

func MatchEmoji

func MatchEmoji(emoji, query string) bool

MatchEmoji returns true if the emoji matches the query based on tags.

func ModalCellSize

func ModalCellSize(s string) (width, height int)

ModalCellSize calculates the cell-width and cell-height of the modal content string.

func MouseToModalCoords

func MouseToModalCoords(screenX, screenY, overlayLeft, overlayTop int) (relX, relY int)

MouseToModalCoords converts screen coordinates to modal-relative coordinates.

func OverlayView

func OverlayView(bgView, modalView string, bgW, bgH, top, left int) string

OverlayView overlays the modalView content on top of the bgView at coordinates (top, left).

Types

type Config

type Config struct {
	InitialEmoji string
	Presets      []string
	Palettes     []Palette
	FrameStyle   lipgloss.Style
	CustomFrame  bool
	AutoDismiss  bool
	ShowSearch   bool
	Theme        Theme
}

Config holds the configuration options for the emoji picker.

type EmojiCanceledMsg

type EmojiCanceledMsg struct{}

EmojiCanceledMsg is emitted when the user cancels the picker (e.g. presses Esc).

type EmojiChangedMsg

type EmojiChangedMsg struct {
	Emoji   string // The selected emoji
	Dismiss bool   // Whether the picker should be dismissed automatically
}

EmojiChangedMsg is emitted when the user confirms their emoji selection.

type EmojiChosenMsg

type EmojiChosenMsg = EmojiChangedMsg

EmojiChosenMsg is an alias for EmojiChangedMsg for compatibility.

type Focus

type Focus int

Focus indicates which part of the picker is focused.

const (
	FocusPresets Focus = iota
	FocusSearch
	FocusCategories
	FocusGrid
)

type Model

type Model struct {
	Palettes     []Palette
	Presets      []string
	ActiveTab    int
	GridCursorX  int
	GridCursorY  int
	PresetCursor int
	Focus        Focus
	SearchInput  TextInput
	ShowSearch   bool
	AutoDismiss  bool
	Selected     string

	Width  int
	Height int

	GridCols int
	GridRows int

	Theme Theme
	// contains filtered or unexported fields
}

Model represents the emoji picker component state.

func New

func New(opts ...Option) Model

New constructs a new EmojiPicker Model with the given options.

func (Model) Init

func (m Model) Init() tea.Cmd

Init implements tea.Model.

func (Model) SelectedEmoji

func (m Model) SelectedEmoji() string

SelectedEmoji returns the emoji under the grid cursor.

func (*Model) SetZoneManager

func (m *Model) SetZoneManager(zm *zone.Manager)

SetZoneManager configures the zone manager for mouse hit testing.

func (Model) Update

func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd)

Update implements tea.Model.

func (Model) Value

func (m Model) Value() string

Value returns the currently selected emoji.

func (Model) View

func (m Model) View() tea.View

View renders the emoji picker UI.

func (Model) ViewSize

func (m Model) ViewSize() (width, height int)

ViewSize returns the size of the picker (width, height in cells).

type Option

type Option func(*Config)

Option configures an emoji picker.

func WithAutoDismiss

func WithAutoDismiss(dismiss bool) Option

WithAutoDismiss sets whether the picker emits EmojiChangedMsg with Dismiss=true to let the host immediately close/dismiss the picker.

func WithInitialEmoji

func WithInitialEmoji(emoji string) Option

WithInitialEmoji sets the starting emoji selection.

func WithPalettes

func WithPalettes(palettes []Palette) Option

WithPalettes sets custom emoji palettes for the picker.

func WithPresets

func WithPresets(emojis []string) Option

WithPresets configures a list of preset/recent emojis displayed at the top.

func WithShowSearch

func WithShowSearch(show bool) Option

WithShowSearch toggles the search input bar.

func WithStyle

func WithStyle(s lipgloss.Style) Option

WithStyle sets the style of the outer frame (border, padding, etc.).

func WithTheme

func WithTheme(theme Theme) Option

WithTheme configures a custom visual theme for the picker.

type Palette

type Palette struct {
	Name   string   // Display name of the category (e.g. "Smileys")
	Icon   string   // Single emoji representing the category tab
	Emojis []string // Slice of emojis in this palette
}

Palette represents a category of emojis for the picker.

type Placement

type Placement struct {
	// contains filtered or unexported fields
}

Placement represents the position of the overlay.

func Fixed

func Fixed(top, left int) Placement

Fixed returns a Placement configuration.

func (Placement) ClampedOrigin

func (p Placement) ClampedOrigin(modalW, modalH, bgW, bgH int) (top, left int)

ClampedOrigin returns topPad, leftPad centering/clamping the overlay on the background space.

type SwatchPicker

type SwatchPicker struct {
	// contains filtered or unexported fields
}

SwatchPicker represents a clickable UI element (emoji + arrow) that opens the emoji picker overlay modal when activated.

func NewSwatchPicker

func NewSwatchPicker(initialEmoji, label string) *SwatchPicker

NewSwatchPicker returns a new SwatchPicker instance.

func (*SwatchPicker) Emoji

func (s *SwatchPicker) Emoji() string

Emoji returns the active emoji value.

func (*SwatchPicker) Focused

func (s *SwatchPicker) Focused() bool

Focused returns whether the swatch is currently focused.

func (*SwatchPicker) Open

func (s *SwatchPicker) Open() bool

Open returns whether the modal is currently displayed.

func (*SwatchPicker) SetBounds

func (s *SwatchPicker) SetBounds(row, col, w, h int)

SetBounds sets where the swatch is positioned in terminal cells.

func (*SwatchPicker) SetEmoji

func (s *SwatchPicker) SetEmoji(e string)

SetEmoji sets the active emoji value.

func (*SwatchPicker) SetFocused

func (s *SwatchPicker) SetFocused(f bool)

SetFocused toggles highlight focus status.

func (*SwatchPicker) SetPickerOptions

func (s *SwatchPicker) SetPickerOptions(opts ...Option)

SetPickerOptions configures options that are passed to the EmojiPicker model when it opens.

func (*SwatchPicker) SetZoneManager

func (s *SwatchPicker) SetZoneManager(zm *zone.Manager)

SetZoneManager configures the bubblezone manager.

func (*SwatchPicker) Size

func (s *SwatchPicker) Size() (width, height int)

Size returns the display size of the swatch (width, height in cells).

func (*SwatchPicker) SwatchView

func (s *SwatchPicker) SwatchView() string

SwatchView renders the swatch preview (emoji + down arrow symbol).

func (*SwatchPicker) Update

func (s *SwatchPicker) Update(msg tea.Msg) (*SwatchPicker, tea.Cmd)

Update forwards tea.Msg events to the swatch picker.

func (*SwatchPicker) ViewWithOverlay

func (s *SwatchPicker) ViewWithOverlay(mainView string, viewWidth, viewHeight int) string

ViewWithOverlay renders the overlay modal on top of mainView when the picker is open.

type TextInput

type TextInput struct {
	Placeholder string
	Prompt      string

	PromptStyle      lipgloss.Style
	TextStyle        lipgloss.Style
	PlaceholderStyle lipgloss.Style
	CursorStyle      lipgloss.Style
	// contains filtered or unexported fields
}

TextInput is a lightweight, zero-dependency text input component for Go and Bubble Tea. It avoids importing external clipboard packages to keep compilation lightweight and CG0-free.

func NewTextInput

func NewTextInput() TextInput

NewTextInput constructs a TextInput model.

func (*TextInput) Blur

func (t *TextInput) Blur()

Blur blurs/unfocuses the input.

func (*TextInput) Focus

func (t *TextInput) Focus() tea.Cmd

Focus focuses the input.

func (*TextInput) Focused

func (t *TextInput) Focused() bool

Focused returns true if the input is currently focused.

func (*TextInput) SetValue

func (t *TextInput) SetValue(s string)

SetValue sets the text value of the input.

func (*TextInput) SetWidth

func (t *TextInput) SetWidth(w int)

SetWidth sets the character width constraint for the text input.

func (TextInput) Update

func (t TextInput) Update(msg tea.Msg) (TextInput, tea.Cmd)

Update handles keyboard messages to mutate the text input value and cursor.

func (*TextInput) Value

func (t *TextInput) Value() string

Value returns the current text value of the input.

func (TextInput) View

func (t TextInput) View() string

View renders the text input string.

type Theme

type Theme struct {
	// Outer frame styling
	FrameBorder      lipgloss.Border
	FrameBorderColor color.Color

	// Inner focus borders
	BorderFocusedColor   color.Color
	BorderUnfocusedColor color.Color

	// Text styling
	TitleStyle lipgloss.Style
	HelpStyle  lipgloss.Style

	// Tabs/Categories styling
	ActiveTabStyle   lipgloss.Style
	InactiveTabStyle lipgloss.Style

	// Emoji grid cell styling
	SelectedCellStyle          lipgloss.Style
	SelectedUnfocusedCellStyle lipgloss.Style
	UnselectedCellStyle        lipgloss.Style

	// Preset cell styling
	SelectedPresetStyle   lipgloss.Style
	UnselectedPresetStyle lipgloss.Style

	// Search text input styling
	SearchPromptStyle      lipgloss.Style
	SearchTextStyle        lipgloss.Style
	SearchPlaceholderStyle lipgloss.Style
	SearchCursorStyle      lipgloss.Style
}

Theme defines the visual styles for the emoji picker.

Directories

Path Synopsis
examples
simple command
Run with: go run ./examples/simple
Run with: go run ./examples/simple
swatch command
Run with: go run ./examples/swatch
Run with: go run ./examples/swatch

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL