From dfb796e232f38790821ddbe0f47955fddde6934f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20L=C3=B6fgren?= <516549+ulken@users.noreply.github.com> Date: Fri, 24 Feb 2023 00:54:24 +0100 Subject: [PATCH 1/6] feat: add log --- packages/prompts/src/index.ts | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/packages/prompts/src/index.ts b/packages/prompts/src/index.ts index ca08cf3..cdf8571 100644 --- a/packages/prompts/src/index.ts +++ b/packages/prompts/src/index.ts @@ -38,6 +38,11 @@ const S_CORNER_TOP_RIGHT = s('╮', '+'); const S_CONNECT_LEFT = s('├', '+'); const S_CORNER_BOTTOM_RIGHT = s('╯', '+'); +const S_INFO = s('ℹ', 'i'); +const S_SUCCESS = s('✔', '√'); +const S_WARN = s('⚠', '!'); +const S_ERROR = s('✘', 'x'); + const symbol = (state: State) => { switch (state) { case 'initial': @@ -409,6 +414,27 @@ export const outro = (message = '') => { process.stdout.write(`${color.gray(S_BAR)}\n${color.gray(S_BAR_END)} ${message}\n\n`); }; +export type LogMessageOptions = { + symbol?: string; +}; +export const log = { + message: (message = '', { symbol = color.gray(S_BAR) }: LogMessageOptions = {}) => { + process.stdout.write(`${color.gray(S_BAR)}\n${symbol} ${message}\n`); + }, + info: (message: string) => { + log.message(message, { symbol: color.blue(S_INFO) }); + }, + success: (message: string) => { + log.message(message, { symbol: color.green(S_SUCCESS) }); + }, + warn: (message: string) => { + log.message(message, { symbol: color.yellow(S_WARN) }); + }, + error: (message: string) => { + log.message(message, { symbol: color.red(S_ERROR) }); + }, +}; + const frames = unicode ? ['◒', '◐', '◓', '◑'] : ['•', 'o', 'O', '0']; export const spinner = () => { -- 2.51.2 From 506608218c86bc10b11e0de2e9f0f9f3a69be13a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20L=C3=B6fgren?= <516549+ulken@users.noreply.github.com> Date: Sat, 25 Feb 2023 00:55:25 +0100 Subject: [PATCH 2/6] align log symbols Co-authored-by: Nate Moore --- packages/prompts/src/index.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/prompts/src/index.ts b/packages/prompts/src/index.ts index cdf8571..edec26f 100644 --- a/packages/prompts/src/index.ts +++ b/packages/prompts/src/index.ts @@ -38,10 +38,10 @@ const S_CORNER_TOP_RIGHT = s('╮', '+'); const S_CONNECT_LEFT = s('├', '+'); const S_CORNER_BOTTOM_RIGHT = s('╯', '+'); -const S_INFO = s('ℹ', 'i'); -const S_SUCCESS = s('✔', '√'); -const S_WARN = s('⚠', '!'); -const S_ERROR = s('✘', 'x'); +const S_INFO = s('●', '•'); +const S_SUCCESS = s('◆', '*'); +const S_WARN = s('▲', '!'); +const S_ERROR = s('■', 'x'); const symbol = (state: State) => { switch (state) { -- 2.51.2 From a9f6f02f9263f12b881158e8c396e37db2182164 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20L=C3=B6fgren?= <516549+ulken@users.noreply.github.com> Date: Sat, 25 Feb 2023 00:48:47 +0100 Subject: [PATCH 3/6] add `log.warning()` alias --- packages/prompts/src/index.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/prompts/src/index.ts b/packages/prompts/src/index.ts index edec26f..e36dab0 100644 --- a/packages/prompts/src/index.ts +++ b/packages/prompts/src/index.ts @@ -430,6 +430,10 @@ export const log = { warn: (message: string) => { log.message(message, { symbol: color.yellow(S_WARN) }); }, + /** alias for `log.warn()`. */ + warning: (message: string) => { + log.warn(message); + }, error: (message: string) => { log.message(message, { symbol: color.red(S_ERROR) }); }, -- 2.51.2 From 7413febcd33ac6b31bb82c70eea4ea037e667100 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20L=C3=B6fgren?= <516549+ulken@users.noreply.github.com> Date: Sat, 25 Feb 2023 00:54:17 +0100 Subject: [PATCH 4/6] only print one newline for empty message --- packages/prompts/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/prompts/src/index.ts b/packages/prompts/src/index.ts index e36dab0..8ac1aa1 100644 --- a/packages/prompts/src/index.ts +++ b/packages/prompts/src/index.ts @@ -419,7 +419,7 @@ export type LogMessageOptions = { }; export const log = { message: (message = '', { symbol = color.gray(S_BAR) }: LogMessageOptions = {}) => { - process.stdout.write(`${color.gray(S_BAR)}\n${symbol} ${message}\n`); + process.stdout.write(`${color.gray(S_BAR)}\n` + message ? `${symbol} ${message}\n` : ''); }, info: (message: string) => { log.message(message, { symbol: color.blue(S_INFO) }); -- 2.51.2 From a0d8d4fc4158221cdc7b42fb4b11ac3529312677 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20L=C3=B6fgren?= <516549+ulken@users.noreply.github.com> Date: Sat, 25 Feb 2023 01:04:04 +0100 Subject: [PATCH 5/6] handle multiline text --- packages/prompts/src/index.ts | 41 +++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/packages/prompts/src/index.ts b/packages/prompts/src/index.ts index 8ac1aa1..67b2d2e 100644 --- a/packages/prompts/src/index.ts +++ b/packages/prompts/src/index.ts @@ -345,19 +345,27 @@ export const multiselect = [], Value extends Primi i === 0 ? `${color.yellow(S_BAR_END)} ${color.yellow(ln)}` : ` ${ln}` ) .join('\n'); - return `${title}${color.yellow(S_BAR)} ${this.options - .map((option, i) => { - const selected = this.value.includes(option.value); - const active = i === this.cursor; - if (active && selected) { - return opt(option, 'active-selected'); - } - if (selected) { - return opt(option, 'selected'); - } - return opt(option, active ? 'active' : 'inactive'); - }) - .join(`\n${color.yellow(S_BAR)} `)}\n${footer}\n`; + return ( + title + + color.yellow(S_BAR) + + ' ' + + this.options + .map((option, i) => { + const selected = this.value.includes(option.value); + const active = i === this.cursor; + if (active && selected) { + return opt(option, 'active-selected'); + } + if (selected) { + return opt(option, 'selected'); + } + return opt(option, active ? 'active' : 'inactive'); + }) + .join(`\n${color.yellow(S_BAR)} `) + + '\n' + + footer + + '\n' + ); } default: { return `${title}${color.cyan(S_BAR)} ${this.options @@ -419,7 +427,12 @@ export type LogMessageOptions = { }; export const log = { message: (message = '', { symbol = color.gray(S_BAR) }: LogMessageOptions = {}) => { - process.stdout.write(`${color.gray(S_BAR)}\n` + message ? `${symbol} ${message}\n` : ''); + const parts = [`${color.gray(S_BAR)}`]; + if (message) { + const [firstLine, ...lines] = message.split('\n'); + parts.push(`${symbol} ${firstLine}`, ...lines.map((ln) => `${color.gray(S_BAR)} ${ln}`)); + } + process.stdout.write(`${parts.join('\n')}\n`); }, info: (message: string) => { log.message(message, { symbol: color.blue(S_INFO) }); -- 2.51.2 From 165a1b3a58e087d0b3fc4d2da4538fdcfe2099fc Mon Sep 17 00:00:00 2001 From: Nate Moore Date: Fri, 24 Feb 2023 18:44:20 -0600 Subject: [PATCH 6/6] Create .changeset/hot-candles-repeat.md --- .changeset/hot-candles-repeat.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/hot-candles-repeat.md diff --git a/.changeset/hot-candles-repeat.md b/.changeset/hot-candles-repeat.md new file mode 100644 index 0000000..6a0f8e3 --- /dev/null +++ b/.changeset/hot-candles-repeat.md @@ -0,0 +1,5 @@ +--- +"@clack/prompts": minor +--- + +Add `log` APIs. Supports `log.info`, `log.success`, `log.warn`, and `log.error`. For low-level control, `log.message` is also exposed. -- 2.51.2