@oclif/table 0.4.10 → 0.4.12

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.
package/lib/table.d.ts CHANGED
@@ -1,11 +1,12 @@
1
1
  import React from 'react';
2
2
  import { CellProps, ContainerProps, HorizontalAlignment, Overflow, TableOptions } from './types.js';
3
- export declare function formatTextWithMargins({ horizontalAlignment, overflow, padding, value, width, }: {
3
+ export declare function formatTextWithMargins({ horizontalAlignment, overflow, padding, trimWhitespace, value, width }: {
4
4
  overflow: Overflow;
5
5
  value: unknown;
6
6
  width: number;
7
7
  padding: number;
8
8
  horizontalAlignment: HorizontalAlignment;
9
+ trimWhitespace?: boolean;
9
10
  }): {
10
11
  text: string;
11
12
  marginLeft: number;
package/lib/table.js CHANGED
@@ -34,7 +34,7 @@ function determineTruncatePosition(overflow) {
34
34
  }
35
35
  }
36
36
  }
37
- export function formatTextWithMargins({ horizontalAlignment, overflow, padding, value, width, }) {
37
+ export function formatTextWithMargins({ horizontalAlignment, overflow, padding, trimWhitespace = true, value, width }) {
38
38
  function calculateMargins(spaces) {
39
39
  let marginLeft;
40
40
  let marginRight;
@@ -76,7 +76,7 @@ export function formatTextWithMargins({ horizontalAlignment, overflow, padding,
76
76
  if (overflow === 'wrap') {
77
77
  const wrappedText = wrapAnsi(valueWithNoZeroWidthChars, spaceForText, {
78
78
  hard: true,
79
- trim: true,
79
+ trim: trimWhitespace,
80
80
  wordWrap: true,
81
81
  }).replace(/^\n/, ''); // remove leading newline (wrapAnsi adds it to emojis)
82
82
  const { marginLeft, marginRight } = calculateMargins(width - determineWidthOfWrappedText(stripAnsi(wrappedText)));
@@ -114,7 +114,7 @@ export function formatTextWithMargins({ horizontalAlignment, overflow, padding,
114
114
  };
115
115
  }
116
116
  function setupTable(props) {
117
- const { data, filter, horizontalAlignment = 'left', maxWidth, noStyle = false, overflow = 'truncate', padding = 1, sort, title, verticalAlignment = 'top', width, } = props;
117
+ const { data, filter, horizontalAlignment = 'left', maxWidth, noStyle = false, overflow = 'truncate', padding = 1, sort, title, trimWhitespace, verticalAlignment = 'top', width, } = props;
118
118
  const headerOptions = noStyle ? {} : { bold: true, color: 'blue', ...props.headerOptions };
119
119
  const borderStyle = noStyle ? 'none' : (props.borderStyle ?? 'all');
120
120
  const borderColor = noStyle ? undefined : props.borderColor;
@@ -131,6 +131,7 @@ function setupTable(props) {
131
131
  maxWidth: tableWidth ?? determineConfiguredWidth(maxWidth),
132
132
  overflow,
133
133
  padding,
134
+ trimWhitespace,
134
135
  verticalAlignment,
135
136
  width: tableWidth,
136
137
  };
@@ -146,6 +147,7 @@ function setupTable(props) {
146
147
  borderProps,
147
148
  cell: Cell,
148
149
  skeleton: BORDER_SKELETONS[config.borderStyle].data,
150
+ trimWhitespace
149
151
  });
150
152
  const footerComponent = row({
151
153
  borderProps,
@@ -217,7 +219,7 @@ export function Table(props) {
217
219
  */
218
220
  function row(config) {
219
221
  // This is a component builder. We return a function.
220
- const { borderProps, skeleton } = config;
222
+ const { borderProps, skeleton, trimWhitespace } = config;
221
223
  return (props) => {
222
224
  const data = props.columns.map((column, colI) => {
223
225
  const { horizontalAlignment, overflow, padding, verticalAlignment, width } = column;
@@ -231,6 +233,7 @@ function row(config) {
231
233
  horizontalAlignment,
232
234
  overflow,
233
235
  padding,
236
+ trimWhitespace,
234
237
  value,
235
238
  width,
236
239
  });
@@ -316,19 +319,39 @@ function renderPlainTable(props) {
316
319
  const { columns, headings, processedData, title } = setupTable(props);
317
320
  if (title)
318
321
  console.log(title);
319
- const headerString = columns.reduce((acc, column) => {
322
+ // Process header columns the same way as data rows to handle multi-line headers
323
+ const headerColumnTexts = columns.map((column) => {
320
324
  const { horizontalAlignment, overflow, padding, width } = column;
321
325
  const { marginLeft, marginRight, text } = formatTextWithMargins({
322
326
  horizontalAlignment,
323
327
  overflow,
324
328
  padding,
329
+ trimWhitespace: props.trimWhitespace,
325
330
  value: headings[column.column] ?? column.column,
326
331
  width,
327
332
  });
328
- return `${acc}${' '.repeat(marginLeft)}${text}${' '.repeat(marginRight)}`;
329
- }, '');
330
- console.log(headerString);
331
- console.log('-'.repeat(headerString.length));
333
+ // Split the formatted text into lines
334
+ const lines = text.split('\n');
335
+ return lines.map((line) => `${' '.repeat(marginLeft)}${line.trimStart()}${' '.repeat(marginRight)}`);
336
+ });
337
+ // Find the maximum number of lines in any header column
338
+ const maxHeaderLines = Math.max(...headerColumnTexts.map((col) => col.length));
339
+ // Pad all header columns to have the same number of lines
340
+ const paddedHeaderColumns = headerColumnTexts.map((col, colIndex) => {
341
+ const column = columns[colIndex];
342
+ while (col.length < maxHeaderLines) {
343
+ col.push(' '.repeat(column.width)); // Add empty lines
344
+ }
345
+ return col;
346
+ });
347
+ // Print each line of the header
348
+ for (let lineIndex = 0; lineIndex < maxHeaderLines; lineIndex++) {
349
+ const lineToPrint = paddedHeaderColumns.map((col) => col[lineIndex]).join('');
350
+ console.log(lineToPrint);
351
+ }
352
+ // Calculate total width for the separator line
353
+ const totalWidth = columns.reduce((acc, column) => acc + column.width, 0);
354
+ console.log('-'.repeat(totalWidth));
332
355
  for (const row of processedData) {
333
356
  // Process all columns and get their formatted text
334
357
  const columnTexts = columns.map((column) => {
@@ -341,6 +364,7 @@ function renderPlainTable(props) {
341
364
  horizontalAlignment,
342
365
  overflow,
343
366
  padding,
367
+ trimWhitespace: props.trimWhitespace,
344
368
  value,
345
369
  width,
346
370
  });
package/lib/types.d.ts CHANGED
@@ -165,6 +165,11 @@ export type TableOptions<T extends Record<string, unknown>> = {
165
165
  * Title of the table. Displayed above the table.
166
166
  */
167
167
  title?: string;
168
+ /**
169
+ * Whether or not to trim the whitespace of row content
170
+ * default: true
171
+ */
172
+ trimWhitespace?: boolean;
168
173
  /**
169
174
  * Styling options for the title of the table.
170
175
  */
@@ -181,6 +186,7 @@ export type Config<T> = {
181
186
  maxWidth: number;
182
187
  overflow: Overflow;
183
188
  headerOptions: HeaderOptions;
189
+ trimWhitespace: boolean | undefined;
184
190
  borderStyle: BorderStyle;
185
191
  horizontalAlignment: HorizontalAlignment;
186
192
  verticalAlignment: VerticalAlignment;
@@ -206,6 +212,11 @@ export type RowConfig = {
206
212
  cross: string;
207
213
  line: string;
208
214
  };
215
+ /**
216
+ * Whether or not to trim the whitespace of row content
217
+ * default: true
218
+ */
219
+ trimWhitespace?: boolean;
209
220
  props?: Record<string, unknown>;
210
221
  borderProps: {
211
222
  color: SupportedColor | undefined;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@oclif/table",
3
3
  "description": "Display table in terminal",
4
- "version": "0.4.10",
4
+ "version": "0.4.12",
5
5
  "author": "Salesforce",
6
6
  "bugs": "https://github.com/oclif/table/issues",
7
7
  "dependencies": {
@@ -30,7 +30,7 @@
30
30
  "chai": "^4.5.0",
31
31
  "commitlint": "^19",
32
32
  "eslint": "^9.32.0",
33
- "eslint-config-oclif": "^6.0.87",
33
+ "eslint-config-oclif": "^6.0.89",
34
34
  "eslint-config-prettier": "^10.1.8",
35
35
  "eslint-config-xo": "^0.48.0",
36
36
  "eslint-config-xo-react": "^0.28.0",