()
| 136 | output: opts.output, |
| 137 | validate: opts.validate, |
| 138 | render() { |
| 139 | const hasGuide = opts.withGuide ?? settings.withGuide; |
| 140 | // Title and message display |
| 141 | const headings = hasGuide |
| 142 | ? [`${styleText('gray', S_BAR)}`, `${symbol(this.state)} ${opts.message}`] |
| 143 | : [`${symbol(this.state)} ${opts.message}`]; |
| 144 | const userInput = this.userInput; |
| 145 | const options = this.options; |
| 146 | const placeholder = opts.placeholder; |
| 147 | const showPlaceholder = userInput === '' && placeholder !== undefined; |
| 148 | const opt = (option: Option<Value>, state: 'inactive' | 'active' | 'disabled') => { |
| 149 | const label = getLabel(option); |
| 150 | const hint = |
| 151 | option.hint && option.value === this.focusedValue |
| 152 | ? styleText('dim', ` (${option.hint})`) |
| 153 | : ''; |
| 154 | switch (state) { |
| 155 | case 'active': |
| 156 | return `${styleText('green', S_RADIO_ACTIVE)} ${label}${hint}`; |
| 157 | case 'inactive': |
| 158 | return `${styleText('dim', S_RADIO_INACTIVE)} ${styleText('dim', label)}`; |
| 159 | case 'disabled': |
| 160 | return `${styleText('gray', S_RADIO_INACTIVE)} ${styleText(['strikethrough', 'gray'], label)}`; |
| 161 | } |
| 162 | }; |
| 163 | |
| 164 | // Handle different states |
| 165 | switch (this.state) { |
| 166 | case 'submit': { |
| 167 | // Show selected value |
| 168 | const selected = getSelectedOptions(this.selectedValues, options); |
| 169 | const label = |
| 170 | selected.length > 0 ? ` ${styleText('dim', selected.map(getLabel).join(', '))}` : ''; |
| 171 | const submitPrefix = hasGuide ? styleText('gray', S_BAR) : ''; |
| 172 | return `${headings.join('\n')}\n${submitPrefix}${label}`; |
| 173 | } |
| 174 | |
| 175 | case 'cancel': { |
| 176 | const userInputText = userInput |
| 177 | ? ` ${styleText(['strikethrough', 'dim'], userInput)}` |
| 178 | : ''; |
| 179 | const cancelPrefix = hasGuide ? styleText('gray', S_BAR) : ''; |
| 180 | return `${headings.join('\n')}\n${cancelPrefix}${userInputText}`; |
| 181 | } |
| 182 | |
| 183 | default: { |
| 184 | const barStyle = this.state === 'error' ? 'yellow' : 'cyan'; |
| 185 | const guidePrefix = hasGuide ? `${styleText(barStyle, S_BAR)} ` : ''; |
| 186 | const guidePrefixEnd = hasGuide ? styleText(barStyle, S_BAR_END) : ''; |
| 187 | // Display cursor position - show plain text in navigation mode |
| 188 | let searchText = ''; |
| 189 | if (this.isNavigating || showPlaceholder) { |
| 190 | const searchTextValue = showPlaceholder ? placeholder : userInput; |
| 191 | searchText = searchTextValue !== '' ? ` ${styleText('dim', searchTextValue)}` : ''; |
| 192 | } else { |
| 193 | searchText = ` ${this.userInputWithCursor}`; |
| 194 | } |
| 195 |
nothing calls this directly
no test coverage detected