Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 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
5 changes: 5 additions & 0 deletions .changeset/floppy-laws-tan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@clack/prompts": patch
---

fix note component overflow bug
15 changes: 13 additions & 2 deletions packages/prompts/src/note.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,29 @@ import {
S_CORNER_TOP_RIGHT,
S_STEP_SUBMIT,
} from './common.js';
import { wrapAnsi } from "fast-wrap-ansi";
import process from "node:process";

export interface NoteOptions extends CommonOptions {
format?: (line: string) => string;
}

const defaultNoteFormatter = (line: string): string => color.dim(line);

const wrapWithFormat = (message: string, width: number, format: NoteOptions["format"]): string => {
const wrapMsg = wrapAnsi(message, width).split("\n");
const maxWidthNormal = wrapMsg.reduce((sum, ln) => Math.max(strip(ln).length, sum), 0);
const maxWidthFormat = wrapMsg.map(format).reduce((sum, ln) => Math.max(strip(ln).length, sum), 0);
const wrapWidth = width - (maxWidthFormat - maxWidthNormal);
return wrapAnsi(message, wrapWidth);
}

export const note = (message = '', title = '', opts?: NoteOptions) => {
const output: Writable = opts?.output ?? process.stdout;
const format = opts?.format ?? defaultNoteFormatter;
const lines = ['', ...message.split('\n').map(format), ''];
const wrapMsg = wrapWithFormat(message, output.columns - 6, format);
const lines = ['', ...wrapMsg.split('\n').map(format), ''];
const titleLen = strip(title).length;
const output: Writable = opts?.output ?? process.stdout;
const len =
Math.max(
lines.reduce((sum, ln) => {
Expand Down
126 changes: 126 additions & 0 deletions packages/prompts/test/__snapshots__/note.test.ts.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,68 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`note (isCI = false) > don't overflow 1`] = `
[
"│
◇ title ─────────────────────────────────────────────────────────────────╮
│ │
│ Eiusmod sint officia proident qui ex tempor laborum ut. Voluptate │
│ dolore excepteur sunt adipisicing laborum non ea elit. Consectetur │
│ exercitation ad laboris consectetur nisi minim labore culpa enim. │
│ Eiusmod duis minim velit mollit nisi. Laboris magna qui fugiat sit │
│ minim. Aliqua id aute sunt proident do tempor mollit nulla veniam │
│ exercitation est ipsum occaecat nostrud. Exercitation ullamco │
│ proident ex ut et in ut. │
│ Dolore magna proident id in magna quis. Sunt et laboris Lorem │
│ adipisicing nisi id proident qui enim laboris proident do. Fugiat eu │
│ commodo exercitation ipsum in aliquip ipsum magna consequat laborum. │
│ Id aute enim enim officia in do aliqua voluptate aute nulla proident. │
│ Mollit pariatur exercitation sit mollit in exercitation culpa │
│ deserunt sunt laboris aliquip cillum mollit ad. Aliquip exercitation │
│ adipisicing qui laboris ea do occaecat elit magna commodo sint │
│ adipisicing. │
│ Fugiat veniam non nostrud reprehenderit tempor quis officia ad │
│ reprehenderit. Veniam ut est irure est. Laboris reprehenderit dolor │
│ dolor id laborum nulla velit et in sunt aliquip. Culpa voluptate │
│ dolore enim ut incididunt dolor sint cupidatat enim. Irure sint │
│ consectetur minim velit aliquip consequat enim ex in sunt. │
│ │
├─────────────────────────────────────────────────────────────────────────╯
",
]
`;

exports[`note (isCI = false) > don't overflow with formatter 1`] = `
[
"│
◇ title ─────────────────────────────────────────────────────────────────╮
│ │
│ * Eiusmod sint officia proident qui ex tempor laborum ut. Voluptate * │
│ * dolore excepteur sunt adipisicing laborum non ea elit. * │
│ * Consectetur exercitation ad laboris consectetur nisi minim labore * │
│ * culpa enim. Eiusmod duis minim velit mollit nisi. Laboris magna * │
│ * qui fugiat sit minim. Aliqua id aute sunt proident do tempor * │
│ * mollit nulla veniam exercitation est ipsum occaecat nostrud. * │
│ * Exercitation ullamco proident ex ut et in ut. * │
│ * Dolore magna proident id in magna quis. Sunt et laboris Lorem * │
│ * adipisicing nisi id proident qui enim laboris proident do. Fugiat * │
│ * eu commodo exercitation ipsum in aliquip ipsum magna consequat * │
│ * laborum. Id aute enim enim officia in do aliqua voluptate aute * │
│ * nulla proident. Mollit pariatur exercitation sit mollit in * │
│ * exercitation culpa deserunt sunt laboris aliquip cillum mollit * │
│ * ad. Aliquip exercitation adipisicing qui laboris ea do occaecat * │
│ * elit magna commodo sint adipisicing. * │
│ * Fugiat veniam non nostrud reprehenderit tempor quis officia ad * │
│ * reprehenderit. Veniam ut est irure est. Laboris reprehenderit * │
│ * dolor dolor id laborum nulla velit et in sunt aliquip. Culpa * │
│ * voluptate dolore enim ut incididunt dolor sint cupidatat enim. * │
│ * Irure sint consectetur minim velit aliquip consequat enim ex in * │
│ * sunt. * │
│ │
├─────────────────────────────────────────────────────────────────────────╯
",
]
`;

exports[`note (isCI = false) > formatter which adds colors works 1`] = `
[
"│
Expand Down Expand Up @@ -53,6 +116,69 @@ exports[`note (isCI = false) > renders message with title 1`] = `
]
`;

exports[`note (isCI = true) > don't overflow 1`] = `
[
"│
◇ title ─────────────────────────────────────────────────────────────────╮
│ │
│ Eiusmod sint officia proident qui ex tempor laborum ut. Voluptate │
│ dolore excepteur sunt adipisicing laborum non ea elit. Consectetur │
│ exercitation ad laboris consectetur nisi minim labore culpa enim. │
│ Eiusmod duis minim velit mollit nisi. Laboris magna qui fugiat sit │
│ minim. Aliqua id aute sunt proident do tempor mollit nulla veniam │
│ exercitation est ipsum occaecat nostrud. Exercitation ullamco │
│ proident ex ut et in ut. │
│ Dolore magna proident id in magna quis. Sunt et laboris Lorem │
│ adipisicing nisi id proident qui enim laboris proident do. Fugiat eu │
│ commodo exercitation ipsum in aliquip ipsum magna consequat laborum. │
│ Id aute enim enim officia in do aliqua voluptate aute nulla proident. │
│ Mollit pariatur exercitation sit mollit in exercitation culpa │
│ deserunt sunt laboris aliquip cillum mollit ad. Aliquip exercitation │
│ adipisicing qui laboris ea do occaecat elit magna commodo sint │
│ adipisicing. │
│ Fugiat veniam non nostrud reprehenderit tempor quis officia ad │
│ reprehenderit. Veniam ut est irure est. Laboris reprehenderit dolor │
│ dolor id laborum nulla velit et in sunt aliquip. Culpa voluptate │
│ dolore enim ut incididunt dolor sint cupidatat enim. Irure sint │
│ consectetur minim velit aliquip consequat enim ex in sunt. │
│ │
├─────────────────────────────────────────────────────────────────────────╯
",
]
`;

exports[`note (isCI = true) > don't overflow with formatter 1`] = `
[
"│
◇ title ─────────────────────────────────────────────────────────────────╮
│ │
│ * Eiusmod sint officia proident qui ex tempor laborum ut. Voluptate * │
│ * dolore excepteur sunt adipisicing laborum non ea elit. * │
│ * Consectetur exercitation ad laboris consectetur nisi minim labore * │
│ * culpa enim. Eiusmod duis minim velit mollit nisi. Laboris magna * │
│ * qui fugiat sit minim. Aliqua id aute sunt proident do tempor * │
│ * mollit nulla veniam exercitation est ipsum occaecat nostrud. * │
│ * Exercitation ullamco proident ex ut et in ut. * │
│ * Dolore magna proident id in magna quis. Sunt et laboris Lorem * │
│ * adipisicing nisi id proident qui enim laboris proident do. Fugiat * │
│ * eu commodo exercitation ipsum in aliquip ipsum magna consequat * │
│ * laborum. Id aute enim enim officia in do aliqua voluptate aute * │
│ * nulla proident. Mollit pariatur exercitation sit mollit in * │
│ * exercitation culpa deserunt sunt laboris aliquip cillum mollit * │
│ * ad. Aliquip exercitation adipisicing qui laboris ea do occaecat * │
│ * elit magna commodo sint adipisicing. * │
│ * Fugiat veniam non nostrud reprehenderit tempor quis officia ad * │
│ * reprehenderit. Veniam ut est irure est. Laboris reprehenderit * │
│ * dolor dolor id laborum nulla velit et in sunt aliquip. Culpa * │
│ * voluptate dolore enim ut incididunt dolor sint cupidatat enim. * │
│ * Irure sint consectetur minim velit aliquip consequat enim ex in * │
│ * sunt. * │
│ │
├─────────────────────────────────────────────────────────────────────────╯
",
]
`;

exports[`note (isCI = true) > formatter which adds colors works 1`] = `
[
"│
Expand Down
29 changes: 29 additions & 0 deletions packages/prompts/test/note.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,33 @@ describe.each(['true', 'false'])('note (isCI = %s)', (isCI) => {

expect(output.buffer).toMatchSnapshot();
});

test('don\'t overflow', () => {
const lorem = [
"Eiusmod sint officia proident qui ex tempor laborum ut. Voluptate dolore excepteur sunt adipisicing laborum non ea elit. Consectetur exercitation ad laboris consectetur nisi minim labore culpa enim. Eiusmod duis minim velit mollit nisi. Laboris magna qui fugiat sit minim. Aliqua id aute sunt proident do tempor mollit nulla veniam exercitation est ipsum occaecat nostrud. Exercitation ullamco proident ex ut et in ut.",
"Dolore magna proident id in magna quis. Sunt et laboris Lorem adipisicing nisi id proident qui enim laboris proident do. Fugiat eu commodo exercitation ipsum in aliquip ipsum magna consequat laborum. Id aute enim enim officia in do aliqua voluptate aute nulla proident. Mollit pariatur exercitation sit mollit in exercitation culpa deserunt sunt laboris aliquip cillum mollit ad. Aliquip exercitation adipisicing qui laboris ea do occaecat elit magna commodo sint adipisicing.",
"Fugiat veniam non nostrud reprehenderit tempor quis officia ad reprehenderit. Veniam ut est irure est. Laboris reprehenderit dolor dolor id laborum nulla velit et in sunt aliquip. Culpa voluptate dolore enim ut incididunt dolor sint cupidatat enim. Irure sint consectetur minim velit aliquip consequat enim ex in sunt.",
];
prompts.note(lorem.join("\n"), 'title', {
input,
output: Object.assign(output, { columns: 75 }),
});

expect(output.buffer).toMatchSnapshot();
});

test('don\'t overflow with formatter', () => {
const lorem = [
"Eiusmod sint officia proident qui ex tempor laborum ut. Voluptate dolore excepteur sunt adipisicing laborum non ea elit. Consectetur exercitation ad laboris consectetur nisi minim labore culpa enim. Eiusmod duis minim velit mollit nisi. Laboris magna qui fugiat sit minim. Aliqua id aute sunt proident do tempor mollit nulla veniam exercitation est ipsum occaecat nostrud. Exercitation ullamco proident ex ut et in ut.",
"Dolore magna proident id in magna quis. Sunt et laboris Lorem adipisicing nisi id proident qui enim laboris proident do. Fugiat eu commodo exercitation ipsum in aliquip ipsum magna consequat laborum. Id aute enim enim officia in do aliqua voluptate aute nulla proident. Mollit pariatur exercitation sit mollit in exercitation culpa deserunt sunt laboris aliquip cillum mollit ad. Aliquip exercitation adipisicing qui laboris ea do occaecat elit magna commodo sint adipisicing.",
"Fugiat veniam non nostrud reprehenderit tempor quis officia ad reprehenderit. Veniam ut est irure est. Laboris reprehenderit dolor dolor id laborum nulla velit et in sunt aliquip. Culpa voluptate dolore enim ut incididunt dolor sint cupidatat enim. Irure sint consectetur minim velit aliquip consequat enim ex in sunt.",
];
prompts.note(lorem.join("\n"), 'title', {
format: (line) => colors.red(`* ${colors.cyan(line)} *`),
input,
output: Object.assign(output, { columns: 75 }),
});

expect(output.buffer).toMatchSnapshot();
});
});