({
cursor,
options,
style,
output = process.stdout,
maxItems = Number.POSITIVE_INFINITY,
columnPadding = 0,
rowPadding = 4,
}: LimitOptionsParams<TOption>)
| 94 | * ``` |
| 95 | */ |
| 96 | export const limitOptions = <TOption>({ |
| 97 | cursor, |
| 98 | options, |
| 99 | style, |
| 100 | output = process.stdout, |
| 101 | maxItems = Number.POSITIVE_INFINITY, |
| 102 | columnPadding = 0, |
| 103 | rowPadding = 4, |
| 104 | }: LimitOptionsParams<TOption>): string[] => { |
| 105 | const columns = getColumns(output); |
| 106 | const maxWidth = columns - columnPadding; |
| 107 | const rows = getRows(output); |
| 108 | const overflowFormat = styleText('dim', '...'); |
| 109 | |
| 110 | const outputMaxItems = Math.max(rows - rowPadding, 0); |
| 111 | // We clamp to minimum 5 because anything less doesn't make sense UX wise |
| 112 | const computedMaxItems = Math.max(Math.min(maxItems, outputMaxItems), 5); |
| 113 | let slidingWindowLocation = 0; |
| 114 | |
| 115 | if (cursor >= computedMaxItems - 3) { |
| 116 | slidingWindowLocation = Math.max( |
| 117 | Math.min(cursor - computedMaxItems + 3, options.length - computedMaxItems), |
| 118 | 0 |
| 119 | ); |
| 120 | } |
| 121 | |
| 122 | let shouldRenderTopEllipsis = computedMaxItems < options.length && slidingWindowLocation > 0; |
| 123 | let shouldRenderBottomEllipsis = |
| 124 | computedMaxItems < options.length && slidingWindowLocation + computedMaxItems < options.length; |
| 125 | |
| 126 | const slidingWindowLocationEnd = Math.min( |
| 127 | slidingWindowLocation + computedMaxItems, |
| 128 | options.length |
| 129 | ); |
| 130 | const lineGroups: Array<string[]> = []; |
| 131 | let lineCount = 0; |
| 132 | if (shouldRenderTopEllipsis) { |
| 133 | lineCount++; |
| 134 | } |
| 135 | if (shouldRenderBottomEllipsis) { |
| 136 | lineCount++; |
| 137 | } |
| 138 | |
| 139 | const slidingWindowLocationWithEllipsis = |
| 140 | slidingWindowLocation + (shouldRenderTopEllipsis ? 1 : 0); |
| 141 | const slidingWindowLocationEndWithEllipsis = |
| 142 | slidingWindowLocationEnd - (shouldRenderBottomEllipsis ? 1 : 0); |
| 143 | |
| 144 | for (let i = slidingWindowLocationWithEllipsis; i < slidingWindowLocationEndWithEllipsis; i++) { |
| 145 | const wrappedLines = wrapAnsi(style(options[i], i === cursor), maxWidth, { |
| 146 | hard: true, |
| 147 | trim: false, |
| 148 | }).split('\n'); |
| 149 | lineGroups.push(wrappedLines); |
| 150 | lineCount += wrappedLines.length; |
| 151 | } |
| 152 | |
| 153 | if (lineCount > outputMaxItems) { |
no test coverage detected