@oclif/table 0.1.3 → 0.1.5
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.js +75 -28
- package/lib/types.d.ts +1 -1
- package/package.json +1 -1
package/lib/table.js
CHANGED
|
@@ -39,6 +39,73 @@ function determineWidthToUse(columns, configuredWidth) {
|
|
|
39
39
|
const tableWidth = columns.map((c) => c.width).reduce((a, b) => a + b) + columns.length + 1;
|
|
40
40
|
return tableWidth < configuredWidth ? configuredWidth : tableWidth;
|
|
41
41
|
}
|
|
42
|
+
function determineWidthOfWrappedText(text) {
|
|
43
|
+
const lines = text.split('\n');
|
|
44
|
+
return lines.reduce((max, line) => Math.max(max, line.length), 0);
|
|
45
|
+
}
|
|
46
|
+
function determineTruncatePosition(overflow) {
|
|
47
|
+
switch (overflow) {
|
|
48
|
+
case 'truncate-middle': {
|
|
49
|
+
return 'middle';
|
|
50
|
+
}
|
|
51
|
+
case 'truncate-start': {
|
|
52
|
+
return 'start';
|
|
53
|
+
}
|
|
54
|
+
case 'truncate-end': {
|
|
55
|
+
return 'end';
|
|
56
|
+
}
|
|
57
|
+
default: {
|
|
58
|
+
return 'end';
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function doStuffWithText({ horizontalAlignment, overflow, padding, value, width, }) {
|
|
63
|
+
function calculateMargins(spaces) {
|
|
64
|
+
let marginLeft;
|
|
65
|
+
let marginRight;
|
|
66
|
+
if (horizontalAlignment === 'left') {
|
|
67
|
+
marginLeft = padding;
|
|
68
|
+
marginRight = spaces - marginLeft;
|
|
69
|
+
}
|
|
70
|
+
else if (horizontalAlignment === 'center') {
|
|
71
|
+
marginLeft = Math.floor(spaces / 2);
|
|
72
|
+
marginRight = Math.ceil(spaces / 2);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
marginRight = padding;
|
|
76
|
+
marginLeft = spaces - marginRight;
|
|
77
|
+
}
|
|
78
|
+
return { marginLeft, marginRight };
|
|
79
|
+
}
|
|
80
|
+
// Some terminals don't play nicely with zero-width characters, so we replace them with spaces.
|
|
81
|
+
// https://github.com/sindresorhus/terminal-link/issues/18
|
|
82
|
+
// https://github.com/Shopify/cli/pull/995
|
|
83
|
+
const valueWithNoZeroWidthChars = String(value).replaceAll('', ' ');
|
|
84
|
+
const spaceForText = width - padding * 2;
|
|
85
|
+
if (stripAnsi(valueWithNoZeroWidthChars).length < spaceForText) {
|
|
86
|
+
const spaces = width - stripAnsi(valueWithNoZeroWidthChars).length;
|
|
87
|
+
return {
|
|
88
|
+
text: valueWithNoZeroWidthChars,
|
|
89
|
+
...calculateMargins(spaces),
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
if (overflow === 'wrap') {
|
|
93
|
+
const wrappedText = wrapAnsi(valueWithNoZeroWidthChars, spaceForText, { hard: true, trim: true, wordWrap: true });
|
|
94
|
+
const { marginLeft, marginRight } = calculateMargins(width - determineWidthOfWrappedText(wrappedText));
|
|
95
|
+
const text = wrappedText.replaceAll('\n', `${' '.repeat(marginRight)}\n${' '.repeat(marginLeft)}`);
|
|
96
|
+
return {
|
|
97
|
+
marginLeft,
|
|
98
|
+
marginRight,
|
|
99
|
+
text,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
const text = cliTruncate(valueWithNoZeroWidthChars, spaceForText, { position: determineTruncatePosition(overflow) });
|
|
103
|
+
const spaces = width - stripAnsi(text).length;
|
|
104
|
+
return {
|
|
105
|
+
text,
|
|
106
|
+
...calculateMargins(spaces),
|
|
107
|
+
};
|
|
108
|
+
}
|
|
42
109
|
export function Table(props) {
|
|
43
110
|
const { data, filter, horizontalAlignment = 'left', maxWidth, noStyle = false, orientation = 'horizontal', overflow = 'truncate', padding = 1, sort, title, verticalAlignment = 'top', } = props;
|
|
44
111
|
const headerOptions = noStyle ? {} : { bold: true, color: 'blue', ...props.headerOptions };
|
|
@@ -148,35 +215,15 @@ function row(config) {
|
|
|
148
215
|
return (React.createElement(config.cell, { key: key, column: colI, ...config.props }, skeleton.line.repeat(width)));
|
|
149
216
|
}
|
|
150
217
|
const key = `${props.key}-cell-${column.key}`;
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
stripAnsi(valueWithNoZeroWidthChars).length >= spaceForText
|
|
159
|
-
? overflow === 'wrap'
|
|
160
|
-
? wrapAnsi(valueWithNoZeroWidthChars, spaceForText, { hard: true, trim: true, wordWrap: false }).replaceAll('\n', `${' '.repeat(padding)}\n${' '.repeat(padding)}`)
|
|
161
|
-
: cliTruncate(valueWithNoZeroWidthChars, spaceForText)
|
|
162
|
-
: valueWithNoZeroWidthChars;
|
|
163
|
-
const spaces = overflow === 'wrap' ? width - stripAnsi(v).split('\n')[0].trim().length : width - stripAnsi(v).length;
|
|
164
|
-
let marginLeft;
|
|
165
|
-
let marginRight;
|
|
166
|
-
if (horizontalAlignment === 'left') {
|
|
167
|
-
marginLeft = padding;
|
|
168
|
-
marginRight = spaces - marginLeft;
|
|
169
|
-
}
|
|
170
|
-
else if (horizontalAlignment === 'center') {
|
|
171
|
-
marginLeft = Math.floor(spaces / 2);
|
|
172
|
-
marginRight = Math.ceil(spaces / 2);
|
|
173
|
-
}
|
|
174
|
-
else {
|
|
175
|
-
marginRight = padding;
|
|
176
|
-
marginLeft = spaces - marginRight;
|
|
177
|
-
}
|
|
218
|
+
const { marginLeft, marginRight, text } = doStuffWithText({
|
|
219
|
+
horizontalAlignment,
|
|
220
|
+
overflow,
|
|
221
|
+
padding,
|
|
222
|
+
value,
|
|
223
|
+
width,
|
|
224
|
+
});
|
|
178
225
|
const alignItems = verticalAlignment === 'top' ? 'flex-start' : verticalAlignment === 'center' ? 'center' : 'flex-end';
|
|
179
|
-
return (React.createElement(config.cell, { key: key, column: colI, alignItems, ...config.props }, `${skeleton.line.repeat(marginLeft)}${
|
|
226
|
+
return (React.createElement(config.cell, { key: key, column: colI, alignItems, ...config.props }, `${skeleton.line.repeat(marginLeft)}${text}${skeleton.line.repeat(marginRight)}`));
|
|
180
227
|
});
|
|
181
228
|
const height = data.map((d) => d.props.children.split('\n').length).reduce((a, b) => Math.max(a, b), 0);
|
|
182
229
|
const elements = intersperse((i) => {
|
package/lib/types.d.ts
CHANGED
|
@@ -51,7 +51,7 @@ export type HeaderOptions = TextOptions & {
|
|
|
51
51
|
*/
|
|
52
52
|
formatter?: HeaderFormatter;
|
|
53
53
|
};
|
|
54
|
-
type Overflow = 'wrap' | 'truncate';
|
|
54
|
+
export type Overflow = 'wrap' | 'truncate' | 'truncate-middle' | 'truncate-start' | 'truncate-end';
|
|
55
55
|
type SortOrder<T> = 'asc' | 'desc' | ((valueA: T, valueB: T) => number);
|
|
56
56
|
export type Sort<T> = {
|
|
57
57
|
[K in keyof T]?: SortOrder<T[K]>;
|