|
| 1 | +<?php |
| 2 | + |
| 3 | +namespace Laravel\Prompts\Themes\Default\Concerns; |
| 4 | + |
| 5 | +use Illuminate\Support\Collection; |
| 6 | + |
| 7 | +trait DrawsTabs |
| 8 | +{ |
| 9 | + use InteractsWithStrings; |
| 10 | + |
| 11 | + /** |
| 12 | + * Render a row of tabs. |
| 13 | + * |
| 14 | + * @param Collection<int, string> $tabs |
| 15 | + */ |
| 16 | + protected function tabs( |
| 17 | + Collection $tabs, |
| 18 | + int $selected, |
| 19 | + int $width, |
| 20 | + string $color = 'cyan', |
| 21 | + ): string { |
| 22 | + $strippedWidth = fn (string $value): int => mb_strwidth($this->stripEscapeSequences($value)); |
| 23 | + |
| 24 | + $top_row = $tabs->map(fn($value, $key) => $key === $selected |
| 25 | + ? '╭' . str_repeat('─', $strippedWidth($value) + 2) . '╮' |
| 26 | + : str_repeat(' ', $strippedWidth($value) + 4) |
| 27 | + )->implode(''); |
| 28 | + |
| 29 | + $middle_row = $tabs->map(fn($value, $key) => $key === $selected |
| 30 | + ? "{$this->dim('│')} {$this->{$color}($value)} {$this->dim('│')}" |
| 31 | + : " {$value} " |
| 32 | + )->implode(''); |
| 33 | + |
| 34 | + $bottom_row = $tabs->map(fn($value, $key) => $key === $selected |
| 35 | + ? '┴' . str_repeat('─', $strippedWidth($value) + 2) . '┴' |
| 36 | + : str_repeat('─', $strippedWidth($value) + 4) |
| 37 | + )->implode(''); |
| 38 | + $bottom_row = $this->pad($bottom_row, $width, '─'); |
| 39 | + |
| 40 | + // automatic horizontal tab scrolling |
| 41 | + if ($strippedWidth($top_row) > $width) { |
| 42 | + $chars_to_kill = $strippedWidth($top_row) - $width; |
| 43 | + $percent = $selected / ($tabs->count() - 1); |
| 44 | + $left = (int) round($percent * $chars_to_kill); |
| 45 | + foreach ([&$top_row, &$middle_row, &$bottom_row] as &$row) { |
| 46 | + $row = mb_substr($row, $left, mb_strwidth($row) - $chars_to_kill); |
| 47 | + } |
| 48 | + } |
| 49 | + |
| 50 | + return collect([$this->dim($top_row), $middle_row, $this->dim($bottom_row)])->implode(PHP_EOL); |
| 51 | + } |
| 52 | +} |
0 commit comments