@oclif/table 0.1.10 → 0.1.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.
@@ -1,4 +1,4 @@
1
- export declare const BORDER_STYLES: readonly ["all", "headers-only-with-outline", "headers-only-with-underline", "headers-only", "horizontal-with-outline", "horizontal", "none", "outline", "vertical-with-outline", "vertical"];
1
+ export declare const BORDER_STYLES: readonly ["all", "headers-only-with-outline", "headers-only-with-underline", "headers-only", "horizontal-with-outline", "horizontal", "none", "outline", "vertical-with-outline", "vertical-rows-with-outline", "vertical"];
2
2
  export type BorderStyle = (typeof BORDER_STYLES)[number];
3
3
  type Skeleton = {
4
4
  cross: string;
package/lib/skeletons.js CHANGED
@@ -8,6 +8,7 @@ export const BORDER_STYLES = [
8
8
  'none',
9
9
  'outline',
10
10
  'vertical-with-outline',
11
+ 'vertical-rows-with-outline',
11
12
  'vertical',
12
13
  ];
13
14
  export const BORDER_SKELETONS = {
@@ -317,6 +318,44 @@ export const BORDER_SKELETONS = {
317
318
  right: '',
318
319
  },
319
320
  },
321
+ 'vertical-rows-with-outline': {
322
+ data: {
323
+ cross: '│',
324
+ left: '│',
325
+ line: ' ',
326
+ right: '│',
327
+ },
328
+ footer: {
329
+ cross: '┴',
330
+ left: '└',
331
+ line: '─',
332
+ right: '┘',
333
+ },
334
+ header: {
335
+ cross: '─',
336
+ left: '┌',
337
+ line: '─',
338
+ right: '┐',
339
+ },
340
+ headerFooter: {
341
+ cross: '┬',
342
+ left: '├',
343
+ line: '─',
344
+ right: '┤',
345
+ },
346
+ heading: {
347
+ cross: ' ',
348
+ left: '│',
349
+ line: ' ',
350
+ right: '│',
351
+ },
352
+ separator: {
353
+ cross: '',
354
+ left: '',
355
+ line: '',
356
+ right: '',
357
+ },
358
+ },
320
359
  'vertical-with-outline': {
321
360
  data: {
322
361
  cross: '│',
package/lib/table.js CHANGED
@@ -82,7 +82,7 @@ function formatTextWithMargins({ horizontalAlignment, overflow, padding, value,
82
82
  // https://github.com/Shopify/cli/pull/995
83
83
  const valueWithNoZeroWidthChars = String(value).replaceAll('​', ' ');
84
84
  const spaceForText = width - padding * 2;
85
- if (stripAnsi(valueWithNoZeroWidthChars).length < spaceForText) {
85
+ if (stripAnsi(valueWithNoZeroWidthChars).length <= spaceForText) {
86
86
  const spaces = width - stripAnsi(valueWithNoZeroWidthChars).length;
87
87
  return {
88
88
  text: valueWithNoZeroWidthChars,
@@ -92,11 +92,34 @@ function formatTextWithMargins({ horizontalAlignment, overflow, padding, value,
92
92
  if (overflow === 'wrap') {
93
93
  const wrappedText = wrapAnsi(valueWithNoZeroWidthChars, spaceForText, { hard: true, trim: true, wordWrap: true });
94
94
  const { marginLeft, marginRight } = calculateMargins(width - determineWidthOfWrappedText(stripAnsi(wrappedText)));
95
- const text = wrappedText.replaceAll('\n', `${' '.repeat(marginRight)}\n${' '.repeat(marginLeft)}`);
95
+ const lines = wrappedText.split('\n').map((line, idx) => {
96
+ const { marginLeft: lineSpecificLeftMargin } = calculateMargins(width - stripAnsi(line).length);
97
+ if (horizontalAlignment === 'left') {
98
+ if (idx === 0) {
99
+ // if it's the first line, only add margin to the right side (The left margin will be applied later)
100
+ return `${line}${' '.repeat(marginRight)}`;
101
+ }
102
+ // if left alignment, add the overall margin to the left side and right sides
103
+ return `${' '.repeat(marginLeft)}${line}${' '.repeat(marginRight)}`;
104
+ }
105
+ if (horizontalAlignment === 'center') {
106
+ if (idx === 0) {
107
+ // if it's the first line, only add margin to the right side (The left margin will be applied later)
108
+ return `${line}${' '.repeat(marginRight)}`;
109
+ }
110
+ // if center alignment, add line specific margin to the left side and the overall margin to the right side
111
+ return `${' '.repeat(lineSpecificLeftMargin)}${line}${' '.repeat(marginRight)}`;
112
+ }
113
+ // right alignment
114
+ if (idx === 0) {
115
+ return `${' '.repeat(Math.max(0, lineSpecificLeftMargin - marginLeft))}${line}${' '.repeat(marginRight)}`;
116
+ }
117
+ return `${' '.repeat(lineSpecificLeftMargin)}${line}${' '.repeat(marginRight)}`;
118
+ });
96
119
  return {
97
120
  marginLeft,
98
121
  marginRight,
99
- text,
122
+ text: lines.join('\n'),
100
123
  };
101
124
  }
102
125
  const text = cliTruncate(valueWithNoZeroWidthChars, spaceForText, { position: determineTruncatePosition(overflow) });
@@ -107,7 +130,7 @@ function formatTextWithMargins({ horizontalAlignment, overflow, padding, value,
107
130
  };
108
131
  }
109
132
  export function Table(props) {
110
- const { data, filter, horizontalAlignment = 'left', maxWidth, noStyle = false, orientation = 'horizontal', overflow = 'truncate', padding = 1, sort, title, verticalAlignment = 'top', } = props;
133
+ const { data, filter, horizontalAlignment = 'left', maxWidth, noStyle = false, overflow = 'truncate', padding = 1, sort, title, verticalAlignment = 'top', } = props;
111
134
  const headerOptions = noStyle ? {} : { bold: true, color: 'blue', ...props.headerOptions };
112
135
  const borderStyle = noStyle ? 'none' : (props.borderStyle ?? 'all');
113
136
  const borderColor = noStyle ? undefined : props.borderColor;
@@ -165,26 +188,6 @@ export function Table(props) {
165
188
  props: borderProps,
166
189
  skeleton: BORDER_SKELETONS[config.borderStyle].separator,
167
190
  });
168
- if (orientation === 'vertical') {
169
- return (React.createElement(Box, { flexDirection: "column", width: determineWidthToUse(columns, config.maxWidth), paddingBottom: 1 },
170
- title && React.createElement(Text, { ...titleOptions }, title),
171
- processedData.map((row, index) => {
172
- // Calculate the hash of the row based on its value and position
173
- const key = `row-${sha1(row)}-${index}`;
174
- const maxKeyLength = Math.max(...Object.values(headings).map((c) => c.length));
175
- // Construct a row.
176
- return (React.createElement(Box, { key: key, borderTop: true, borderBottom: false, borderLeft: false, borderRight: false, flexDirection: "column", borderStyle: noStyle ? undefined : 'single', borderColor: borderColor }, columns.map((column) => {
177
- const value = (row[column.column] ?? '').toString();
178
- const keyName = (headings[column.key] ?? column.key).toString();
179
- const keyPadding = ' '.repeat(maxKeyLength - keyName.length + padding);
180
- return (React.createElement(Box, { key: `${key}-cell-${column.key}`, flexWrap: "wrap" },
181
- React.createElement(Text, { ...config.headerOptions },
182
- keyName,
183
- keyPadding),
184
- React.createElement(Text, { wrap: overflow }, value)));
185
- })));
186
- })));
187
- }
188
191
  return (React.createElement(Box, { flexDirection: "column", width: determineWidthToUse(columns, config.maxWidth) },
189
192
  title && React.createElement(Text, { ...titleOptions }, title),
190
193
  headerComponent({ columns, data: {}, key: 'header' }),
@@ -278,8 +281,8 @@ export function printTables(tables, options) {
278
281
  const columns = process.stdout.columns - (leftMargin + rightMargin);
279
282
  const processed = tables.map((table) => ({
280
283
  ...table,
281
- // adjust maxWidth to account for margin
282
- maxWidth: determineConfiguredWidth(table.maxWidth, columns),
284
+ // adjust maxWidth to account for margin and columnGap
285
+ maxWidth: determineConfiguredWidth(table.maxWidth, columns) - (options?.columnGap ?? 0) * tables.length,
283
286
  }));
284
287
  const instance = render(React.createElement(Container, { ...options }, processed.map((table) => (React.createElement(Table, { key: sha1(table), ...table })))));
285
288
  instance.unmount();
package/lib/types.d.ts CHANGED
@@ -76,7 +76,7 @@ export type TableOptions<T extends Record<string, unknown>> = {
76
76
  *
77
77
  * If you provide a number or percentage that is larger than the terminal width, it will default to the terminal width.
78
78
  *
79
- * If you provide a number or percentage that is too small to fit the table, it will default to the width of the table.
79
+ * If you provide a number or percentage that is too small to fit the table, it will default to the minimum width of the table.
80
80
  */
81
81
  maxWidth?: Percentage | number;
82
82
  /**
@@ -88,7 +88,7 @@ export type TableOptions<T extends Record<string, unknown>> = {
88
88
  */
89
89
  headerOptions?: HeaderOptions;
90
90
  /**
91
- * Border style for the table. Defaults to 'all'. Only applies to horizontal orientation.
91
+ * Border style for the table. Defaults to 'all'.
92
92
  */
93
93
  borderStyle?: BorderStyle;
94
94
  /**
@@ -96,7 +96,7 @@ export type TableOptions<T extends Record<string, unknown>> = {
96
96
  */
97
97
  borderColor?: SupportedColor;
98
98
  /**
99
- * Align data in columns. Defaults to 'left'. Only applies to horizontal orientation.
99
+ * Align data in columns. Defaults to 'left'.
100
100
  */
101
101
  horizontalAlignment?: HorizontalAlignment;
102
102
  /**
@@ -133,26 +133,7 @@ export type TableOptions<T extends Record<string, unknown>> = {
133
133
  */
134
134
  sort?: Sort<T>;
135
135
  /**
136
- * The orientation of the table. Defaults to 'horizontal'.
137
- *
138
- * If 'vertical', individual records will be displayed vertically in key:value pairs.
139
- *
140
- * @example
141
- * ```
142
- * ─────────────
143
- * Name Alice
144
- * Id 36329
145
- * Age 20
146
- * ─────────────
147
- * Name Bob
148
- * Id 49032
149
- * Age 21
150
- * ─────────────
151
- * ```
152
- */
153
- orientation?: 'horizontal' | 'vertical';
154
- /**
155
- * Vertical alignment of cell content. Defaults to 'top'. Only applies to horizontal orientation.
136
+ * Vertical alignment of cell content. Defaults to 'top'.
156
137
  */
157
138
  verticalAlignment?: VerticalAlignment;
158
139
  /**
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@oclif/table",
3
3
  "description": "Display table in terminal",
4
- "version": "0.1.10",
4
+ "version": "0.1.12",
5
5
  "author": "Salesforce",
6
- "bugs": "https://github.com/oclif/multi-stage-output/issues",
6
+ "bugs": "https://github.com/oclif/table/issues",
7
7
  "dependencies": {
8
8
  "@oclif/core": "^4",
9
9
  "@types/react": "^18.3.10",
@@ -20,7 +20,7 @@
20
20
  "@commitlint/config-conventional": "^19",
21
21
  "@oclif/prettier-config": "^0.2.1",
22
22
  "@types/chai": "^4.3.16",
23
- "@types/mocha": "^10.0.7",
23
+ "@types/mocha": "^10.0.8",
24
24
  "@types/node": "^18",
25
25
  "@types/object-hash": "^3.0.6",
26
26
  "@types/sinon": "^17.0.3",
@@ -52,7 +52,7 @@
52
52
  "files": [
53
53
  "/lib"
54
54
  ],
55
- "homepage": "https://github.com/oclif/core",
55
+ "homepage": "https://github.com/oclif/table",
56
56
  "keywords": [
57
57
  "oclif",
58
58
  "cli",
@@ -62,7 +62,7 @@
62
62
  "exports": {
63
63
  ".": "./lib/index.js"
64
64
  },
65
- "repository": "oclif/core",
65
+ "repository": "oclif/table",
66
66
  "publishConfig": {
67
67
  "access": "public"
68
68
  },