@oclif/table 0.1.2 → 0.1.4

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 CHANGED
@@ -39,6 +39,94 @@ 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 wrapText(text, spaceForText, width, padding) {
47
+ const wrappedText = wrapAnsi(text, spaceForText, { hard: true, trim: true, wordWrap: true });
48
+ if (wrappedText.includes('\n')) {
49
+ const widthOfWrappedText = determineWidthOfWrappedText(wrappedText);
50
+ const rightPadding = width - widthOfWrappedText - padding * 2;
51
+ // return wrappedText.replaceAll('\n', `${' '.repeat(padding)}\n${' '.repeat(rightPadding)}`)
52
+ // return wrappedText
53
+ const final = wrappedText.replaceAll('\n', `${' '.repeat(rightPadding)}\n${' '.repeat(padding)}`);
54
+ console.log({
55
+ final,
56
+ padding,
57
+ rightPadding,
58
+ spaceForText,
59
+ width,
60
+ widthOrWrappedText: widthOfWrappedText,
61
+ wrappedText,
62
+ });
63
+ return final;
64
+ }
65
+ return wrappedText.replaceAll('\n', `${' '.repeat(padding)}\n${' '.repeat(padding)}`);
66
+ }
67
+ function determineTruncatePosition(overflow) {
68
+ switch (overflow) {
69
+ case 'truncate-middle': {
70
+ return 'middle';
71
+ }
72
+ case 'truncate-start': {
73
+ return 'start';
74
+ }
75
+ case 'truncate-end': {
76
+ return 'end';
77
+ }
78
+ default: {
79
+ return 'end';
80
+ }
81
+ }
82
+ }
83
+ function doStuffWithText({ horizontalAlignment, overflow, padding, value, width, }) {
84
+ function calculateMargins(spaces) {
85
+ let marginLeft;
86
+ let marginRight;
87
+ if (horizontalAlignment === 'left') {
88
+ marginLeft = padding;
89
+ marginRight = spaces - marginLeft;
90
+ }
91
+ else if (horizontalAlignment === 'center') {
92
+ marginLeft = Math.floor(spaces / 2);
93
+ marginRight = Math.ceil(spaces / 2);
94
+ }
95
+ else {
96
+ marginRight = padding;
97
+ marginLeft = spaces - marginRight;
98
+ }
99
+ return { marginLeft, marginRight };
100
+ }
101
+ // Some terminals don't play nicely with zero-width characters, so we replace them with spaces.
102
+ // https://github.com/sindresorhus/terminal-link/issues/18
103
+ // https://github.com/Shopify/cli/pull/995
104
+ const valueWithNoZeroWidthChars = String(value).replaceAll('​', ' ');
105
+ const spaceForText = width - padding * 2;
106
+ if (stripAnsi(valueWithNoZeroWidthChars).length < spaceForText) {
107
+ const spaces = width - stripAnsi(valueWithNoZeroWidthChars).length;
108
+ return {
109
+ text: valueWithNoZeroWidthChars,
110
+ ...calculateMargins(spaces),
111
+ };
112
+ }
113
+ if (overflow === 'wrap') {
114
+ const wrappedText = wrapAnsi(valueWithNoZeroWidthChars, spaceForText, { hard: true, trim: true, wordWrap: true });
115
+ const { marginLeft, marginRight } = calculateMargins(width - determineWidthOfWrappedText(wrappedText));
116
+ const text = wrappedText.replaceAll('\n', `${' '.repeat(marginRight)}\n${' '.repeat(marginLeft)}`);
117
+ return {
118
+ marginLeft,
119
+ marginRight,
120
+ text,
121
+ };
122
+ }
123
+ const text = cliTruncate(valueWithNoZeroWidthChars, spaceForText, { position: determineTruncatePosition(overflow) });
124
+ const spaces = width - stripAnsi(text).length;
125
+ return {
126
+ text,
127
+ ...calculateMargins(spaces),
128
+ };
129
+ }
42
130
  export function Table(props) {
43
131
  const { data, filter, horizontalAlignment = 'left', maxWidth, noStyle = false, orientation = 'horizontal', overflow = 'truncate', padding = 1, sort, title, verticalAlignment = 'top', } = props;
44
132
  const headerOptions = noStyle ? {} : { bold: true, color: 'blue', ...props.headerOptions };
@@ -148,35 +236,15 @@ function row(config) {
148
236
  return (React.createElement(config.cell, { key: key, column: colI, ...config.props }, skeleton.line.repeat(width)));
149
237
  }
150
238
  const key = `${props.key}-cell-${column.key}`;
151
- // Some terminals don't play nicely with zero-width characters, so we replace them with spaces.
152
- // https://github.com/sindresorhus/terminal-link/issues/18
153
- // https://github.com/Shopify/cli/pull/995
154
- const valueWithNoZeroWidthChars = String(value).replaceAll('​', ' ');
155
- const spaceForText = width - padding * 2;
156
- const v =
157
- // if the visible length of the value is greater than the column width, truncate or wrap
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
- }
239
+ const { marginLeft, marginRight, text } = doStuffWithText({
240
+ horizontalAlignment,
241
+ overflow,
242
+ padding,
243
+ value,
244
+ width,
245
+ });
178
246
  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)}${v}${skeleton.line.repeat(marginRight)}`));
247
+ return (React.createElement(config.cell, { key: key, column: colI, alignItems, ...config.props }, `${skeleton.line.repeat(marginLeft)}${text}${skeleton.line.repeat(marginRight)}`));
180
248
  });
181
249
  const height = data.map((d) => d.props.children.split('\n').length).reduce((a, b) => Math.max(a, b), 0);
182
250
  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]>;
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.1.2",
4
+ "version": "0.1.4",
5
5
  "author": "Salesforce",
6
6
  "bugs": "https://github.com/oclif/multi-stage-output/issues",
7
7
  "dependencies": {
@@ -35,7 +35,7 @@
35
35
  "eslint-config-xo-react": "^0.27.0",
36
36
  "eslint-plugin-react": "^7.34.3",
37
37
  "eslint-plugin-react-hooks": "^4.6.2",
38
- "husky": "^9.1.3",
38
+ "husky": "^9.1.6",
39
39
  "ink-testing-library": "^4.0.0",
40
40
  "lint-staged": "^15",
41
41
  "mocha": "^10.7.3",