@boba-cli/textarea 0.1.0-alpha.2

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/messages.ts","../src/types.ts","../src/model.ts"],"names":["CursorMode","last","merged"],"mappings":"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","file":"index.js","sourcesContent":["import clipboard from 'clipboardy'\nimport type { Cmd, Msg } from '@boba-cli/tea'\n\n/**\n * Clipboard paste content.\n * @public\n */\nexport class PasteMsg implements Msg {\n readonly _tag = 'textarea/paste'\n constructor(public readonly text: string) {}\n}\n\n/**\n * Clipboard read failed.\n * @public\n */\nexport class PasteErrorMsg implements Msg {\n readonly _tag = 'textarea/paste-error'\n constructor(public readonly error: unknown) {}\n}\n\n/**\n * Command to read from the system clipboard.\n * Resolves to a PasteMsg on success or PasteErrorMsg on failure.\n * @public\n */\nexport function pasteCommand(): Cmd<PasteMsg | PasteErrorMsg> {\n return async () => {\n try {\n const text = await clipboard.read()\n return new PasteMsg(text ?? '')\n } catch (error) {\n return new PasteErrorMsg(error)\n }\n }\n}\n","import { Style } from '@boba-cli/chapstick'\nimport { CursorMode } from '@boba-cli/cursor'\nimport { Binding, newBinding } from '@boba-cli/key'\n\n/**\n * Validation callback. Return an Error to indicate invalid input.\n * @public\n */\nexport type ValidateFunc = (value: string) => Error | null\n\n/**\n * Options for creating a textarea model.\n * @public\n */\nexport interface TextareaOptions {\n value?: string\n placeholder?: string\n charLimit?: number\n width?: number\n prompt?: string\n cursorMode?: CursorMode\n promptStyle?: Style\n textStyle?: Style\n placeholderStyle?: Style\n cursorStyle?: Style\n validate?: ValidateFunc\n maxHeight?: number\n maxWidth?: number\n showLineNumbers?: boolean\n lineNumberStyle?: Style\n endOfBufferCharacter?: string\n keyMap?: KeyMap\n}\n\n/**\n * Key bindings for textarea actions.\n * @public\n */\nexport interface KeyMap {\n characterLeft: Binding\n characterRight: Binding\n lineUp: Binding\n lineDown: Binding\n lineStart: Binding\n lineEnd: Binding\n insertNewline: Binding\n deleteCharBackward: Binding\n deleteCharForward: Binding\n deleteLine: Binding\n gotoLineStart: Binding\n gotoLineEnd: Binding\n paste: Binding\n}\n\n/**\n * Default key bindings (Vi-like arrows plus enter/backspace/delete).\n * @public\n */\nexport const defaultKeyMap: KeyMap = {\n characterLeft: newBinding({ keys: ['left'] }),\n characterRight: newBinding({ keys: ['right'] }),\n lineUp: newBinding({ keys: ['up', 'k'] }),\n lineDown: newBinding({ keys: ['down', 'j'] }),\n lineStart: newBinding({ keys: ['home', 'ctrl+a'] }),\n lineEnd: newBinding({ keys: ['end', 'ctrl+e'] }),\n insertNewline: newBinding({ keys: ['enter'] }),\n deleteCharBackward: newBinding({ keys: ['backspace', 'ctrl+h'] }),\n deleteCharForward: newBinding({ keys: ['delete', 'ctrl+d'] }),\n deleteLine: newBinding({ keys: ['ctrl+u'] }),\n gotoLineStart: newBinding({ keys: ['home'] }),\n gotoLineEnd: newBinding({ keys: ['end'] }),\n paste: newBinding({ keys: ['ctrl+v'] }),\n}\n\nexport { CursorMode }\n","import { Style } from '@boba-cli/chapstick'\nimport { CursorModel, CursorMode } from '@boba-cli/cursor'\nimport { matches } from '@boba-cli/key'\nimport { batch, type Cmd, type Msg, KeyMsg, KeyType } from '@boba-cli/tea'\nimport { newSanitizer } from '@boba-cli/runeutil'\nimport GraphemeSplitter from 'grapheme-splitter'\nimport { PasteErrorMsg, PasteMsg, pasteCommand } from './messages.js'\nimport {\n type KeyMap,\n type TextareaOptions,\n type ValidateFunc,\n defaultKeyMap,\n} from './types.js'\n\nconst splitter = new GraphemeSplitter()\nconst sanitizer = newSanitizer() // keep newlines, strip control/ansi\n\ntype Position = { line: number; column: number }\n\ntype State = {\n lines: string[]\n pos: Position\n focused: boolean\n width: number\n maxHeight: number\n maxWidth: number\n prompt: string\n promptStyle: Style\n textStyle: Style\n placeholderStyle: Style\n cursorStyle: Style\n lineNumberStyle: Style\n showLineNumbers: boolean\n endOfBufferCharacter: string\n validateFn?: ValidateFunc\n keyMap: KeyMap\n cursor: CursorModel\n error: Error | null\n scrollTop: number\n placeholder?: string\n}\n\n/**\n * Multi-line textarea model.\n * @public\n */\nexport class TextareaModel {\n readonly lines: string[]\n readonly pos: Position\n readonly focused: boolean\n readonly width: number\n readonly maxHeight: number\n readonly maxWidth: number\n readonly prompt: string\n readonly promptStyle: Style\n readonly textStyle: Style\n readonly placeholderStyle: Style\n readonly cursorStyle: Style\n readonly lineNumberStyle: Style\n readonly showLineNumbers: boolean\n readonly endOfBufferCharacter: string\n readonly validateFn?: ValidateFunc\n readonly keyMap: KeyMap\n readonly cursor: CursorModel\n readonly error: Error | null\n readonly scrollTop: number\n readonly placeholder?: string\n\n private constructor(state: State) {\n this.lines = state.lines\n this.pos = state.pos\n this.focused = state.focused\n this.width = state.width\n this.maxHeight = state.maxHeight\n this.maxWidth = state.maxWidth\n this.prompt = state.prompt\n this.promptStyle = state.promptStyle\n this.textStyle = state.textStyle\n this.placeholderStyle = state.placeholderStyle\n this.cursorStyle = state.cursorStyle\n this.lineNumberStyle = state.lineNumberStyle\n this.showLineNumbers = state.showLineNumbers\n this.endOfBufferCharacter = state.endOfBufferCharacter\n this.validateFn = state.validateFn\n this.keyMap = state.keyMap\n this.cursor = state.cursor\n this.error = state.error\n this.scrollTop = state.scrollTop\n this.placeholder = state.placeholder\n }\n\n /** Create a new textarea model. */\n static new(options: TextareaOptions = {}): TextareaModel {\n const rawValue = options.value ?? ''\n const sanitized = sanitize(rawValue)\n const lines = splitLines(sanitized)\n const cursorMode = options.cursorMode ?? CursorMode.Blink\n const textStyle = options.textStyle ?? new Style()\n const cursor = new CursorModel({\n style: options.cursorStyle ?? new Style(),\n textStyle,\n mode: cursorMode,\n focused: false,\n char: '▌',\n })\n\n const model = new TextareaModel({\n lines: lines.length > 0 ? lines : [''],\n pos: {\n line: Math.max(0, lines.length - 1),\n column: lines.length > 0 ? runeCount(last(lines) ?? '') : 0,\n },\n focused: false,\n width: options.width ?? 0,\n maxHeight: options.maxHeight ?? 0,\n maxWidth: options.maxWidth ?? 0,\n prompt: options.prompt ?? '',\n promptStyle: options.promptStyle ?? new Style(),\n textStyle,\n placeholderStyle: options.placeholderStyle ?? new Style(),\n cursorStyle: options.cursorStyle ?? new Style(),\n lineNumberStyle: options.lineNumberStyle ?? new Style(),\n showLineNumbers: options.showLineNumbers ?? false,\n endOfBufferCharacter: options.endOfBufferCharacter ?? '~',\n validateFn: options.validate,\n keyMap: options.keyMap ?? defaultKeyMap,\n cursor,\n error: null,\n scrollTop: 0,\n placeholder: options.placeholder,\n })\n\n return model.#withError(model.#runValidation(model.value()))\n }\n\n /** Initial command (none by default). */\n init(): Cmd<Msg> {\n return null\n }\n\n /** Full text value. */\n value(): string {\n return this.lines.join('\\n')\n }\n\n /** Number of lines. */\n lineCount(): number {\n return this.lines.length\n }\n\n /** Current line index (0-based). */\n currentLine(): number {\n return this.pos.line\n }\n\n /** Current column (grapheme index). */\n currentColumn(): number {\n return this.pos.column\n }\n\n /** Content of a line (empty string if out of bounds). */\n lineContent(line: number): string {\n return this.lines[line] ?? ''\n }\n\n /** Is textarea empty. */\n isEmpty(): boolean {\n return this.lines.length === 1 && this.lines[0]?.length === 0\n }\n\n /** Focus the textarea (enables key handling). */\n focus(): [TextareaModel, Cmd<Msg>] {\n if (this.focused) {\n return [this, null]\n }\n const [cursor, cmd] = this.cursor.focus()\n const next = this.#with({ focused: true, cursor })\n return [next, cmd]\n }\n\n /** Blur the textarea. */\n blur(): TextareaModel {\n if (!this.focused) {\n return this\n }\n return this.#with({ focused: false, cursor: this.cursor.blur() })\n }\n\n /** Move cursor to start of current line. */\n gotoLineStart(): TextareaModel {\n return this.#withPosition({ line: this.pos.line, column: 0 })\n }\n\n /** Move cursor to end of current line. */\n gotoLineEnd(): TextareaModel {\n const len = runeCount(this.lines[this.pos.line] ?? '')\n return this.#withPosition({ line: this.pos.line, column: len })\n }\n\n /** Move up n lines (default 1). */\n lineUp(n = 1): TextareaModel {\n const target = clamp(\n this.pos.line - Math.max(1, n),\n 0,\n this.lines.length - 1,\n )\n return this.#withPosition({ line: target, column: this.pos.column })\n }\n\n /** Move cursor left, possibly across lines. */\n cursorLeft(): TextareaModel {\n if (this.pos.column > 0) {\n return this.#withPosition({\n line: this.pos.line,\n column: this.pos.column - 1,\n })\n }\n if (this.pos.line > 0) {\n const prevLine = this.lines[this.pos.line - 1] ?? ''\n return this.#withPosition({\n line: this.pos.line - 1,\n column: runeCount(prevLine),\n })\n }\n return this\n }\n\n /** Move cursor right, possibly across lines. */\n cursorRight(): TextareaModel {\n const line = this.lines[this.pos.line] ?? ''\n const len = runeCount(line)\n if (this.pos.column < len) {\n return this.#withPosition({\n line: this.pos.line,\n column: this.pos.column + 1,\n })\n }\n if (this.pos.line < this.lines.length - 1) {\n return this.#withPosition({ line: this.pos.line + 1, column: 0 })\n }\n return this\n }\n\n /** Move down n lines (default 1). */\n lineDown(n = 1): TextareaModel {\n const target = clamp(\n this.pos.line + Math.max(1, n),\n 0,\n this.lines.length - 1,\n )\n return this.#withPosition({ line: target, column: this.pos.column })\n }\n\n /** Jump to a specific line (0-based). */\n gotoLine(line: number): TextareaModel {\n const target = clamp(line, 0, this.lines.length - 1)\n return this.#withPosition({ line: target, column: this.pos.column })\n }\n\n /** Insert text at cursor (supports multi-line). */\n insertRunes(text: string): TextareaModel {\n if (!text) {\n return this\n }\n const sanitized = sanitize(text)\n if (!sanitized) {\n return this\n }\n const parts = sanitized.split('\\n')\n const current = this.lines[this.pos.line] ?? ''\n const before = sliceGraphemes(current, 0, this.pos.column)\n const after = sliceGraphemes(current, this.pos.column)\n\n let nextLines: string[] = []\n if (parts.length === 1) {\n const merged = before + parts[0]! + after\n nextLines = replaceLine(this.lines, this.pos.line, merged)\n } else {\n const first = before + parts[0]!\n const last = parts[parts.length - 1]!\n const middle = parts.slice(1, -1)\n const tail = last + after\n\n nextLines = [\n ...this.lines.slice(0, this.pos.line),\n first,\n ...middle,\n tail,\n ...this.lines.slice(this.pos.line + 1),\n ]\n }\n\n const newLine = this.pos.line + (parts.length - 1)\n const newColumn =\n parts.length === 1\n ? this.pos.column + runeCount(parts[0]!)\n : runeCount(last(parts)!)\n\n return this.#withValue(nextLines, { line: newLine, column: newColumn })\n }\n\n /** Insert a newline at the cursor. */\n insertNewline(): TextareaModel {\n return this.insertRunes('\\n')\n }\n\n /** Delete character to the left (backspace). */\n deleteLeft(n = 1): TextareaModel {\n if (n <= 0) return this\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n let model: TextareaModel = this\n for (let i = 0; i < n; i++) {\n const next = model.#deleteLeftOnce()\n if (next === model) break\n model = next\n }\n return model\n }\n\n #deleteLeftOnce(): TextareaModel {\n if (this.pos.column > 0) {\n const line = this.lines[this.pos.line] ?? ''\n const before = sliceGraphemes(line, 0, this.pos.column - 1)\n const after = sliceGraphemes(line, this.pos.column)\n const merged = before + after\n return this.#withValue(replaceLine(this.lines, this.pos.line, merged), {\n line: this.pos.line,\n column: this.pos.column - 1,\n })\n }\n if (this.pos.line === 0) {\n return this\n }\n const prevLine = this.lines[this.pos.line - 1] ?? ''\n const current = this.lines[this.pos.line] ?? ''\n const mergedLine = prevLine + current\n const nextLines = [\n ...this.lines.slice(0, this.pos.line - 1),\n mergedLine,\n ...this.lines.slice(this.pos.line + 1),\n ]\n return this.#withValue(nextLines, {\n line: this.pos.line - 1,\n column: runeCount(prevLine),\n })\n }\n\n /** Delete character to the right (delete). */\n deleteRight(n = 1): TextareaModel {\n if (n <= 0) return this\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n let model: TextareaModel = this\n for (let i = 0; i < n; i++) {\n const next = model.#deleteRightOnce()\n if (next === model) break\n model = next\n }\n return model\n }\n\n #deleteRightOnce(): TextareaModel {\n const line = this.lines[this.pos.line] ?? ''\n const len = runeCount(line)\n if (this.pos.column < len) {\n const before = sliceGraphemes(line, 0, this.pos.column)\n const after = sliceGraphemes(line, this.pos.column + 1)\n const merged = before + after\n return this.#withValue(replaceLine(this.lines, this.pos.line, merged), {\n line: this.pos.line,\n column: this.pos.column,\n })\n }\n if (this.pos.line >= this.lines.length - 1) {\n return this\n }\n const nextLine = this.lines[this.pos.line + 1] ?? ''\n const merged = line + nextLine\n const nextLines = [\n ...this.lines.slice(0, this.pos.line),\n merged,\n ...this.lines.slice(this.pos.line + 2),\n ]\n return this.#withValue(nextLines, {\n line: this.pos.line,\n column: this.pos.column,\n })\n }\n\n /** Delete the current line. Keeps one empty line minimum. */\n deleteLine(): TextareaModel {\n if (this.lines.length === 1) {\n return this.reset()\n }\n const nextLines = this.lines.filter((_, i) => i !== this.pos.line)\n const nextLine = clamp(this.pos.line, 0, nextLines.length - 1)\n const nextColumn = clamp(\n this.pos.column,\n 0,\n runeCount(nextLines[nextLine] ?? ''),\n )\n return this.#withValue(nextLines, { line: nextLine, column: nextColumn })\n }\n\n /** Duplicate the current line below. */\n duplicateLine(): TextareaModel {\n const line = this.lines[this.pos.line] ?? ''\n const nextLines = [\n ...this.lines.slice(0, this.pos.line + 1),\n line,\n ...this.lines.slice(this.pos.line + 1),\n ]\n return this.#withValue(nextLines, {\n line: this.pos.line + 1,\n column: this.pos.column,\n })\n }\n\n /** Scroll up by n lines (no cursor move). */\n scrollUp(n = 1): TextareaModel {\n const nextScroll = clamp(\n this.scrollTop - Math.max(1, n),\n 0,\n this.maxScroll(),\n )\n return this.#with({ scrollTop: nextScroll })\n }\n\n /** Scroll down by n lines (no cursor move). */\n scrollDown(n = 1): TextareaModel {\n const nextScroll = clamp(\n this.scrollTop + Math.max(1, n),\n 0,\n this.maxScroll(),\n )\n return this.#with({ scrollTop: nextScroll })\n }\n\n /** Reset to empty content. */\n reset(): TextareaModel {\n return this.#withValue([''], { line: 0, column: 0 })\n }\n\n /** Set a new value (replaces all lines). */\n setValue(value: string): TextareaModel {\n const sanitized = sanitize(value ?? '')\n const lines = splitLines(sanitized)\n return this.#withValue(lines.length > 0 ? lines : [''], {\n line: Math.max(0, lines.length - 1),\n column: lines.length ? runeCount(last(lines) ?? '') : 0,\n })\n }\n\n /** Validation function setter. */\n setValidateFunc(fn: ValidateFunc): TextareaModel {\n const next = this.#with({ validateFn: fn })\n return next.#withError(next.#runValidation(next.value()))\n }\n\n /** Validate current value. */\n validate(): Error | null {\n return this.#runValidation(this.value())\n }\n\n /** Command to paste from clipboard. */\n paste(): [TextareaModel, Cmd<Msg>] {\n return [this, pasteCommand() as Cmd<Msg>]\n }\n\n /** Tea update loop. */\n update(msg: Msg): [TextareaModel, Cmd<Msg>] {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n let model: TextareaModel = this\n const cmds: Cmd<Msg>[] = []\n\n if (msg instanceof KeyMsg) {\n if (model.focused) {\n const [nextModel, cmd] = model.#handleKey(msg)\n model = nextModel\n if (cmd) cmds.push(cmd)\n }\n } else if (msg instanceof PasteMsg) {\n model = model.insertRunes(msg.text)\n } else if (msg instanceof PasteErrorMsg) {\n model = model.#withError(asError(msg.error))\n }\n\n const [cursor, cursorCmd] = model.cursor.update(msg)\n model = model.#with({ cursor })\n if (cursorCmd) {\n cmds.push(cursorCmd as Cmd<Msg>)\n }\n\n // Keep blink scheduling alive on movement: if the cursor changed columns/line,\n // ensure the cursor is visible (blink off) by toggling blink flag.\n if (\n msg instanceof KeyMsg &&\n (msg.key.type === KeyType.Left ||\n msg.key.type === KeyType.Right ||\n msg.key.type === KeyType.Home ||\n msg.key.type === KeyType.End)\n ) {\n const refreshed = model.cursor.withChar(\n model.cursor.isBlinkHidden() ? '▌' : model.cursor.char,\n )\n model = model.#with({ cursor: refreshed })\n }\n\n return [model, batch(...cmds)]\n }\n\n /** Render textarea with cursor and optional line numbers. */\n view(): string {\n if (this.isEmpty() && this.placeholder) {\n return this.#placeholderView()\n }\n\n const height = this.viewportHeight()\n const start = clamp(this.scrollTop, 0, Math.max(0, this.lineCount() - 1))\n const visible = this.lines.slice(start, start + height)\n\n const linesOut = visible.map((line, idx) => {\n const lineIndex = start + idx\n const isCursorLine = lineIndex === this.pos.line\n return this.#renderLine(line, lineIndex, isCursorLine)\n })\n\n const remaining = height - visible.length\n if (remaining > 0) {\n for (let i = 0; i < remaining; i++) {\n const filler = this.endOfBufferCharacter\n const prefix = this.#linePrefix(start + visible.length + i, false)\n linesOut.push(prefix + filler)\n }\n }\n\n return linesOut.join('\\n')\n }\n\n #handleKey(msg: KeyMsg): [TextareaModel, Cmd<Msg> | null] {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n let next: TextareaModel = this\n let cmd: Cmd<Msg> | null = null\n const keyMap = this.keyMap\n\n switch (true) {\n case matches(msg, keyMap.lineUp):\n next = next.lineUp()\n break\n case matches(msg, keyMap.lineDown):\n next = next.lineDown()\n break\n case matches(msg, keyMap.characterLeft):\n next = next.cursorLeft()\n break\n case matches(msg, keyMap.characterRight):\n next = next.cursorRight()\n break\n case matches(msg, keyMap.lineStart):\n case matches(msg, keyMap.gotoLineStart):\n next = next.gotoLineStart()\n break\n case matches(msg, keyMap.lineEnd):\n case matches(msg, keyMap.gotoLineEnd):\n next = next.gotoLineEnd()\n break\n case matches(msg, keyMap.insertNewline):\n next = next.insertNewline()\n break\n case matches(msg, keyMap.deleteCharBackward):\n next = next.deleteLeft()\n break\n case matches(msg, keyMap.deleteCharForward):\n next = next.deleteRight()\n break\n case matches(msg, keyMap.deleteLine):\n next = next.deleteLine()\n break\n case matches(msg, keyMap.paste):\n cmd = pasteCommand() as Cmd<Msg>\n break\n default:\n if (msg.key.type === KeyType.Enter) {\n next = next.insertNewline()\n } else if (\n (msg.key.type === KeyType.Runes || msg.key.type === KeyType.Space) &&\n !msg.key.alt\n ) {\n next = next.insertRunes(msg.key.runes)\n }\n break\n }\n\n return [next.#ensureCursorVisible(), cmd]\n }\n\n #placeholderView(): string {\n const prefix = this.#linePrefix(0, true)\n const graphemes = splitter.splitGraphemes(this.placeholder ?? '')\n const cursorChar = graphemes[0] ?? '▌'\n const rest = graphemes.slice(1).join('')\n const cursorView = this.cursor.withChar(cursorChar).view()\n const body = this.placeholderStyle.inline(true).render(rest)\n return prefix + cursorView + body\n }\n\n #renderLine(line: string, index: number, isCursorLine: boolean): string {\n const prefix = this.#linePrefix(index, isCursorLine)\n if (!isCursorLine) {\n return prefix + this.textStyle.inline(true).render(line)\n }\n const graphemes = splitter.splitGraphemes(line ?? '')\n const col = clamp(this.pos.column, 0, graphemes.length)\n const before = graphemes.slice(0, col).join('')\n const after = graphemes.slice(col).join('') // draw block over gap/char\n const cursorChar = '▌' // always show block cursor for visibility\n\n const beforeStyled = this.textStyle.inline(true).render(before)\n const afterStyled = this.textStyle.inline(true).render(after)\n const cursorView = this.cursor.withChar(cursorChar).view()\n\n return prefix + beforeStyled + cursorView + afterStyled\n }\n\n #linePrefix(lineIndex: number, _isCursorLine: boolean): string {\n const prompt = this.prompt\n ? this.promptStyle.inline(true).render(this.prompt)\n : ''\n const ln =\n this.showLineNumbers && this.lines.length > 0\n ? this.#renderLineNumber(lineIndex)\n : ''\n return ln + prompt\n }\n\n #renderLineNumber(lineIndex: number): string {\n const width = String(this.lines.length).length\n const num = String(lineIndex + 1).padStart(width, ' ')\n return this.lineNumberStyle.inline(true).render(`${num} `)\n }\n\n #runValidation(value: string): Error | null {\n return this.validateFn ? this.validateFn(value) : null\n }\n\n #withError(error: Error | null): TextareaModel {\n if (error === this.error) return this\n return this.#with({ error })\n }\n\n #withValue(lines: string[], pos: Position): TextareaModel {\n const normalized = lines.length > 0 ? lines : ['']\n const nextPos = this.#clampPosition(pos, normalized)\n const next = this.#with({\n lines: normalized,\n pos: nextPos,\n })\n return next\n .#withError(next.#runValidation(next.value()))\n .#ensureCursorVisible()\n }\n\n #withPosition(pos: Position): TextareaModel {\n return this.#withValue(this.lines, pos)\n }\n\n #with(patch: Partial<State>): TextareaModel {\n return new TextareaModel({\n lines: this.lines,\n pos: this.pos,\n focused: this.focused,\n width: this.width,\n maxHeight: this.maxHeight,\n maxWidth: this.maxWidth,\n prompt: this.prompt,\n promptStyle: this.promptStyle,\n textStyle: this.textStyle,\n placeholderStyle: this.placeholderStyle,\n cursorStyle: this.cursorStyle,\n lineNumberStyle: this.lineNumberStyle,\n showLineNumbers: this.showLineNumbers,\n endOfBufferCharacter: this.endOfBufferCharacter,\n validateFn: this.validateFn,\n keyMap: this.keyMap,\n cursor: this.cursor,\n error: this.error,\n scrollTop: this.scrollTop,\n placeholder: this.placeholder,\n ...patch,\n })\n }\n\n #clampPosition(pos: Position, lines: string[]): Position {\n const line = clamp(pos.line, 0, Math.max(0, lines.length - 1))\n const lineContent = lines[line] ?? ''\n const column = clamp(pos.column, 0, runeCount(lineContent))\n return { line, column }\n }\n\n #ensureCursorVisible(): TextareaModel {\n const height = this.viewportHeight()\n if (height <= 0) return this\n let top = this.scrollTop\n if (this.pos.line < top) {\n top = this.pos.line\n } else if (this.pos.line >= top + height) {\n top = this.pos.line - height + 1\n }\n top = clamp(top, 0, this.maxScroll())\n if (top === this.scrollTop) return this\n return this.#with({ scrollTop: top })\n }\n\n viewportHeight(): number {\n if (this.maxHeight && this.maxHeight > 0) {\n return this.maxHeight\n }\n return Math.max(1, this.lines.length)\n }\n\n maxScroll(): number {\n const height = this.viewportHeight()\n return Math.max(0, this.lines.length - height)\n }\n}\n\nfunction sanitize(value: string): string {\n return sanitizer.sanitize(value ?? '')\n}\n\nfunction splitLines(value: string): string[] {\n return value.split('\\n')\n}\n\nfunction sliceGraphemes(value: string, start: number, end?: number): string {\n const graphemes = splitter.splitGraphemes(value ?? '')\n return graphemes.slice(start, end).join('')\n}\n\nfunction runeCount(value: string): number {\n return splitter.countGraphemes(value ?? '')\n}\n\nfunction clamp(v: number, min: number, max: number): number {\n const lo = Math.min(min, max)\n const hi = Math.max(min, max)\n return Math.min(hi, Math.max(lo, v))\n}\n\nfunction last<T>(arr: T[]): T | undefined {\n return arr[arr.length - 1]\n}\n\nfunction replaceLine(lines: string[], index: number, value: string): string[] {\n return lines.map((l, i) => (i === index ? value : l))\n}\n\nfunction asError(err: unknown): Error {\n if (err instanceof Error) return err\n if (typeof err === 'string') return new Error(err)\n if (typeof err === 'number' || typeof err === 'boolean')\n return new Error(String(err))\n return new Error('textarea error')\n}\n"]}
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@boba-cli/textarea",
3
+ "description": "Multi-line text area component for Boba terminal UIs",
4
+ "version": "0.1.0-alpha.2",
5
+ "dependencies": {
6
+ "clipboardy": "^4.0.0",
7
+ "grapheme-splitter": "^1.0.4",
8
+ "@boba-cli/chapstick": "0.1.0-alpha.2",
9
+ "@boba-cli/key": "0.1.0-alpha.1",
10
+ "@boba-cli/cursor": "0.1.0-alpha.2",
11
+ "@boba-cli/tea": "0.1.0-alpha.1",
12
+ "@boba-cli/runeutil": "0.1.0-alpha.1"
13
+ },
14
+ "devDependencies": {
15
+ "typescript": "5.8.2",
16
+ "vitest": "^4.0.16"
17
+ },
18
+ "engines": {
19
+ "node": ">=20.0.0"
20
+ },
21
+ "exports": {
22
+ ".": {
23
+ "import": {
24
+ "types": "./dist/index.d.ts",
25
+ "default": "./dist/index.js"
26
+ },
27
+ "require": {
28
+ "types": "./dist/index.d.cts",
29
+ "default": "./dist/index.cjs"
30
+ }
31
+ },
32
+ "./package.json": "./package.json"
33
+ },
34
+ "files": [
35
+ "dist"
36
+ ],
37
+ "main": "./dist/index.cjs",
38
+ "module": "./dist/index.js",
39
+ "type": "module",
40
+ "types": "./dist/index.d.ts",
41
+ "scripts": {
42
+ "build": "tsup",
43
+ "check:api-report": "pnpm run generate:api-report",
44
+ "check:eslint": "pnpm run lint",
45
+ "generate:api-report": "api-extractor run --local",
46
+ "lint": "eslint \"{src,test}/**/*.{ts,tsx}\"",
47
+ "test": "vitest run"
48
+ }
49
+ }