diff --git a/src/Actions/ApplyBorder.php b/src/Actions/ApplyBorder.php new file mode 100644 index 0000000..b7688e9 --- /dev/null +++ b/src/Actions/ApplyBorder.php @@ -0,0 +1,62 @@ + '┌', + 'tr' => '┐', + 'bl' => '└', + 'br' => '┘', + ]; + + private const BORDER_ROUNDED = [ + 'tl' => '╭', + 'tr' => '╮', + 'bl' => '╰', + 'br' => '╯', + ]; + + // Todo support text alignment + + public static function format(string $text, int $padding = 2, bool $rounded = true): string + { + $lines = explode("\n", $text); + + $width = max(array_map('strlen', $lines)) + ($padding * 2) + 2; + + $borderStyle = $rounded ? self::BORDER_ROUNDED : self::BORDER_SQUARE; + $header = $borderStyle['tl'] . str_repeat('─', $width) . $borderStyle['tr']; + $footer = $borderStyle['bl'] . str_repeat('─', $width) . $borderStyle['br']; + + $lines = array_map(function (string $line) use ($width): string { + return self::formatLine($line, $width - 2); + }, $lines); + + $verticalPadding = (int) round($padding / 2); + if ($verticalPadding > 0) { + $lines = array_merge(array_fill(0, $verticalPadding, self::formatLine('', $width - 2)), $lines); + $lines = array_merge($lines, array_fill(0, $verticalPadding, self::formatLine('', $width - 2))); + } + + return implode("\n", array_merge([$header], $lines, [$footer])); + } + + private static function formatLine(string $line, int $width): string + { + $line = str_pad($line, $width, ' ', STR_PAD_BOTH); + + return '│ ' . $line . ' │'; + } +} diff --git a/src/ValueObjects/Styles.php b/src/ValueObjects/Styles.php index d7d98c8..267d05d 100644 --- a/src/ValueObjects/Styles.php +++ b/src/ValueObjects/Styles.php @@ -5,6 +5,7 @@ namespace Termwind\ValueObjects; use Closure; +use Termwind\Actions\ApplyBorder; use Termwind\Actions\StyleToMethod; use Termwind\Components\Element; use Termwind\Components\Hr; @@ -166,6 +167,18 @@ final public function bg(string $color, int $variant = 0): self ]]); } + /** + * Adds a border to the element. + */ + final public function border(string $color, int $variant = 0): self + { + $this->styleModifiers[__METHOD__] = static fn ($text): string => ApplyBorder::format($text); + + return $this->with(['colors' => [ + 'border' => $this->getColorVariant($color, $variant), + ]]); + } + /** * Adds a bold style to the element. */ diff --git a/tests/border.php b/tests/border.php new file mode 100644 index 0000000..0b8c69d --- /dev/null +++ b/tests/border.php @@ -0,0 +1,17 @@ + + Hello World! + + HTML); + + expect($html)->toBe(<<<'TEXT' + ╭──────────────────╮ + │ │ + │ Hello World! │ + │ │ + ╰──────────────────╯ + TEXT); +});