Skip to content

Commit

Permalink
Merge pull request #67 from Compositr/main
Browse files Browse the repository at this point in the history
Improve input prompt
  • Loading branch information
Elius94 authored Jun 27, 2023
2 parents 5fceb67 + 2076890 commit 31fa247
Show file tree
Hide file tree
Showing 9 changed files with 731 additions and 348 deletions.
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"eslint.validate": ["javascript"]
"eslint.validate": ["javascript"],
"files.eol": "\r\n"
}
1 change: 1 addition & 0 deletions examples/tcp_simulator.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ GUI.on("keypressed", (key) => {
id: "popupTypeMax",
title: "Type max value",
value: max,
placeholder: "100",
numeric: true
}).show().on("confirm", (_max) => {
max = _max
Expand Down
6 changes: 3 additions & 3 deletions src/components/Screen.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { EventEmitter } from "events"
import chalk, { BackgroundColorName, ForegroundColorName } from "chalk"
import { StyledElement, StyleObject } from "./Utils.js"
import { StyledElement, StyleObject, visibleLength } from "./Utils.js"
chalk.level = 3

/**
Expand Down Expand Up @@ -81,7 +81,7 @@ export class Screen extends EventEmitter {
const arg = args[i]
if (arg.text !== undefined) {
const txt = arg.text.toString()
const style: StyleIndexObject = { ...arg.style, index: [row.length, row.length + txt.length] }
const style: StyleIndexObject = { ...arg.style, index: [visibleLength(row), visibleLength(row) + visibleLength(txt)] }
newStyleIndex.push(style)
row += txt
}
Expand All @@ -90,7 +90,7 @@ export class Screen extends EventEmitter {

// Now recalculate the styleIndex for the current row mixing the old one with the new one
// Create a new styleIndex merging the old one with the new one
const mergedStyleIndex = this.mergeStyles(newStyleIndex, currentStyleIndex, this.cursor.x, row.length)
const mergedStyleIndex = this.mergeStyles(newStyleIndex, currentStyleIndex, this.cursor.x, visibleLength(row))

this.buffer[this.cursor.y].styleIndex = mergedStyleIndex
this.buffer[this.cursor.y].text = this.replaceAt(this.buffer[this.cursor.y].text, this.cursor.x, row)
Expand Down
130 changes: 82 additions & 48 deletions src/components/Utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,18 @@ import { BackgroundColorName, ForegroundColorName } from "chalk"
/**
* @typedef {string} HEX - The type of the HEX color.
* @example const hexColor = "#FF0000"
*
*
* @typedef {string} RGB - The type of the RGB color.
* @example const rgbColor = "rgb(255, 0, 0)"
*/
export type HEX = `#${string}`;
export type RGB = `rgb(${number}, ${number}, ${number})` | `rgb(${number},${number},${number})`;
export type RGB =
| `rgb(${number}, ${number}, ${number})`
| `rgb(${number},${number},${number})`;

/**
* @description The type containing all the possible styles for the text.
*
*
* @typedef {Object} StyleObject
* @prop {chalk.ForegroundColorName | HEX | RGB | ""} [color] - The color of the text taken from the chalk library.
* @prop {chalk.BackgroundColorName | HEX | RGB | ""} [backgroundColor] - The background color of the text taken from the chalk library.
Expand All @@ -24,47 +26,47 @@ export type RGB = `rgb(${number}, ${number}, ${number})` | `rgb(${number},${numb
* @prop {boolean} [hidden] - If the text is hidden.
* @prop {boolean} [strikethrough] - If the text is strikethrough.
* @prop {boolean} [overline] - If the text is overlined.
*
*
* @example const textStyle = { color: "red", backgroundColor: "blue", bold: true, italic: true }
*
* @export
* @interface StyleObject
*/
// @type definition
export interface StyleObject {
color?: ForegroundColorName | HEX | RGB | "";
bg?: BackgroundColorName | HEX | RGB | "";
italic?: boolean;
bold?: boolean;
dim?: boolean;
underline?: boolean;
inverse?: boolean;
hidden?: boolean;
strikethrough?: boolean;
overline?: boolean;
color?: ForegroundColorName | HEX | RGB | "";
bg?: BackgroundColorName | HEX | RGB | "";
italic?: boolean;
bold?: boolean;
dim?: boolean;
underline?: boolean;
inverse?: boolean;
hidden?: boolean;
strikethrough?: boolean;
overline?: boolean;
}

/**
* @description The type of the single styled text, stored in a line of the PageBuilder.
*
*
* @typedef {Object} StyledElement
* @prop {string} text - The text of the styled text.
* @prop {StyleObject} style - The style of the styled text.
*
*
* @example const styledText = { text: "Hello", style: { color: "red", backgroundColor: "blue", bold: true, italic: true } }
*
* @export
* @interface StyledElement
*/
// @type definition
export interface StyledElement {
text: string;
style: StyleObject;
text: string;
style: StyleObject;
}

/**
* @description The type containing all the possible styles for the text and the text on the same level. It's used on the higher level.
*
*
* @typedef {Object} SimplifiedStyledElement
* @prop {string} text - The text of the styled text.
* @prop {chalk.ForegroundColorName | HEX | RGB | ""} [color] - The color of the text taken from the chalk library.
Expand All @@ -77,25 +79,25 @@ export interface StyledElement {
* @prop {boolean} [hidden] - If the text is hidden.
* @prop {boolean} [strikethrough] - If the text is strikethrough.
* @prop {boolean} [overline] - If the text is overlined.
*
*
* @example const textStyle = { color: "red", backgroundColor: "blue", bold: true, italic: true }
*
* @export
* @interface SimplifiedStyledElement
*/
// @type definition
export interface SimplifiedStyledElement {
text: string;
color?: ForegroundColorName | HEX | RGB | "";
bg?: BackgroundColorName | HEX | RGB | "" | "";
italic?: boolean;
bold?: boolean;
dim?: boolean;
underline?: boolean;
inverse?: boolean;
hidden?: boolean;
strikethrough?: boolean;
overline?: boolean;
text: string;
color?: ForegroundColorName | HEX | RGB | "";
bg?: BackgroundColorName | HEX | RGB | "" | "";
italic?: boolean;
bold?: boolean;
dim?: boolean;
underline?: boolean;
inverse?: boolean;
hidden?: boolean;
strikethrough?: boolean;
overline?: boolean;
}

/**
Expand All @@ -106,11 +108,11 @@ export interface SimplifiedStyledElement {
*/
// @type definition
export interface PhisicalValues {
x: number
y: number
width: number
height: number
id?: number
x: number;
y: number;
width: number;
height: number;
id?: number;
}

/** @const {Object} boxChars - The characters used to draw the box. */
Expand Down Expand Up @@ -162,7 +164,7 @@ export const boxChars = {
start: "",
end: "",
color: "" as ForegroundColorName | HEX | RGB | "",
}
},
}

/**
Expand All @@ -172,12 +174,20 @@ export const boxChars = {
* @param {boolean} useWordBoundary - If true, the truncation will be done at the end of the word.
* @example CM.truncate("Hello world", 5, true) // "Hello..."
*/
export function truncate(str: string, n: number, useWordBoundary: boolean): string {
if (str.length <= n) { return str }
export function truncate(
str: string,
n: number,
useWordBoundary: boolean
): string {
if (visibleLength(str) <= n) {
return str
}
const subString = str.substring(0, n - 1) // the original check
return (useWordBoundary ?
subString.substring(0, subString.lastIndexOf(" ")) :
subString) + "…"
return (
(useWordBoundary
? subString.substring(0, subString.lastIndexOf(" "))
: subString) + "…"
)
}

/**
Expand All @@ -186,11 +196,13 @@ export function truncate(str: string, n: number, useWordBoundary: boolean): stri
* @export
* @param {StyledElement} styled
* @return {*} {SimplifiedStyledElement}
*
*
* @example const simplifiedStyledElement = styledToSimplifiedStyled({ text: "Hello world", style: { color: "red", backgroundColor: "blue", bold: true, italic: true } })
* // returns { text: "Hello world", color: "red", backgroundColor: "blue", bold: true, italic: true }
*/
export function styledToSimplifiedStyled(styled: StyledElement): SimplifiedStyledElement {
export function styledToSimplifiedStyled(
styled: StyledElement
): SimplifiedStyledElement {
return {
text: styled.text,
color: styled.style?.color,
Expand All @@ -212,11 +224,13 @@ export function styledToSimplifiedStyled(styled: StyledElement): SimplifiedStyle
* @export
* @param {SimplifiedStyledElement} simplifiedStyled
* @return {*} {StyledElement}
*
*
* @example const styledElement = simplifiedStyledToStyled({ text: "Hello world", color: "red", bold: true })
* // returns { text: "Hello world", style: { color: "red", bold: true } }
*/
export function simplifiedStyledToStyled(simplifiedStyled: SimplifiedStyledElement): StyledElement {
export function simplifiedStyledToStyled(
simplifiedStyled: SimplifiedStyledElement
): StyledElement {
return {
text: simplifiedStyled.text,
style: {
Expand All @@ -230,6 +244,26 @@ export function simplifiedStyledToStyled(simplifiedStyled: SimplifiedStyledEleme
hidden: simplifiedStyled?.hidden,
strikethrough: simplifiedStyled?.strikethrough,
overline: simplifiedStyled?.overline,
}
},
}
}
}

/**
* @description Count true visible length of a string
*
* @export
* @param {string} input
* @return {number}
*
* @author Vitalik Gordon (xpl)
*/
export function visibleLength(input: string): number {
// eslint-disable-next-line no-control-regex
const regex = new RegExp(
/* eslint-disable-next-line no-control-regex */
"[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-PRZcf-nqry=><]",
"g"
)
// Array.from is used to correctly count emojis
return Array.from(input.replace(regex, "")).length
}
Loading

0 comments on commit 31fa247

Please sign in to comment.