Вход Регистрация
Файл: vendor/laravel/prompts/src/AutoCompletePrompt.php
Строк: 140
<?php

namespace LaravelPrompts;

use 
Closure;
use 
IlluminateSupportCollection;

class 
AutoCompletePrompt extends Prompt
{
    use 
ConcernsTypedValue;

    
/**
     * The options for the autocomplete prompt.
     *
     * @var array<string>|Closure(string): (array<string>|Collection<int, string>)
     */
    
public array|Closure $options;

    protected 
string $match '';

    protected 
int $highlighted 0;

    
/**
     * @var array<string>|null
     */
    
protected ?array $matches null;

    
/**
     * Create a new AutoCompletePrompt instance.
     *
     * @param  array<string>|Collection<int, string>|Closure(string): (array<string>|Collection<int, string>)  $options
     */
    
public function __construct(
        public 
string $label,
        array|
Collection|Closure $options = [],
        public 
string $placeholder '',
        public 
string $default '',
        public 
bool|string $required false,
        public 
mixed $validate null,
        public 
string $hint '',
        public ?
Closure $transform null,
    ) {
        
$this->options $options instanceof Collection $options->all() : $options;

        
$this->on('key', function ($key) {
            if (
in_array($key, [Key::UPKey::UP_ARROW])) {
                
$matches $this->matches();

                if (
count($matches) > 0) {
                    
$this->highlighted = ($this->highlighted count($matches)) % count($matches);
                }

                return;
            }

            if (
in_array($key, [Key::DOWNKey::DOWN_ARROW])) {
                
$matches $this->matches();

                if (
count($matches) > 0) {
                    
$this->highlighted = ($this->highlighted 1) % count($matches);
                }

                return;
            }

            if (
$key === Key::TAB && $this->cursorPosition >= mb_strlen($this->typedValue)) {
                
$match $this->getMatch();

                if (
$match !== '' && mb_strlen($match) > mb_strlen($this->value())) {
                    
// Ghost text is showing — accept it
                    
$this->typedValue $match;
                    
$this->cursorPosition mb_strlen($match);
                } else {
                    
// No ghost text — request suggestions
                    
$this->matches null;
                    
$this->highlighted 0;
                }

                return;
            }

            if (
in_array($key, [Key::RIGHTKey::RIGHT_ARROW]) && $this->cursorPosition >= mb_strlen($this->typedValue)) {
                
$match $this->getMatch();

                if (
$match !== '') {
                    
$this->typedValue $match;
                    
$this->cursorPosition mb_strlen($match);
                }

                return;
            }

            
// Any other key resets the highlight and match cache
            
$this->highlighted 0;
            
$this->matches null;
        });

        
$this->trackTypedValue(
            
$default,
            
ignorefn ($key) => in_array($key, [Key::UPKey::UP_ARROWKey::DOWNKey::DOWN_ARROW]),
        );
    }

    
/**
     * Get the entered value with a virtual cursor.
     */
    
public function valueWithCursor(int $maxWidth): string
    
{
        if (
$this->value() === '') {
            return 
$this->dim($this->addCursor($this->placeholder0$maxWidth));
        }

        
$this->match $this->getMatch();

        
$ghostText '';

        if (
$this->match !== '' && mb_strlen($this->match) > mb_strlen($this->value())) {
            
$ghostText mb_substr($this->matchmb_strlen($this->value()));
        }

        
// When cursor is at the end and there's ghost text, make the first
        // ghost character the inverted cursor so it flows naturally.
        
if ($ghostText !== '' && $this->cursorPosition >= mb_strlen($this->value())) {
            
$cursorChar mb_substr($ghostText01);
            
$remainingGhost mb_substr($ghostText1);

            return 
$this->value()
                .
$this->inverse($cursorChar)
                .
$this->dim($remainingGhost);
        }

        return 
$this->addCursor(
            
$this->value(),
            
$this->cursorPosition,
            
$maxWidth
        
).$this->dim($ghostText);
    }

    
/**
     * Get the current matches for the typed value.
     *
     * @return array<string>
     */
    
public function matches(): array
    {
        if (
is_array($this->matches)) {
            return 
$this->matches;
        }

        if (
$this->options instanceof Closure) {
            
$options = ($this->options)($this->value());

            return 
$this->matches array_values($options instanceof Collection $options->all() : $options);
        }

        return 
$this->matches array_values(array_filter(
            
$this->options,
            
fn ($option) => str_starts_with(strtolower($option), strtolower($this->value())),
        ));
    }

    
/**
     * Get the current match.
     */
    
protected function getMatch(): string
    
{
        return 
$this->matches()[$this->highlighted] ?? '';
    }
}
Онлайн: 2
Реклама