Skip to content

Commit

Permalink
Merge pull request #11 from rawilk/cleanup-actions
Browse files Browse the repository at this point in the history
  • Loading branch information
rawilk authored Jan 22, 2024
2 parents 0cfed7c + 901497e commit 887a486
Show file tree
Hide file tree
Showing 7 changed files with 167 additions and 306 deletions.
53 changes: 53 additions & 0 deletions src/Actions/CopyToClipboardAction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

declare(strict_types=1);

namespace Rawilk\FilamentPasswordInput\Actions;

use Filament\Forms\Components\Actions\Action;
use Filament\Forms\Components\Component;
use Filament\Support\Facades\FilamentIcon;
use Illuminate\Support\Js;

class CopyToClipboardAction extends Action
{
protected function setUp(): void
{
parent::setUp();

$this->label(__('filament-password-input::password.actions.copy.tooltip'));

$this->icon(FilamentIcon::resolve('filament-password-input::copy') ?? 'heroicon-m-clipboard');

$this->color('gray');

$this->alpineClickHandler(function (Component $component) {
$copyDuration = Js::from(
rescue(
callback: fn () => $component->getCopyMessageDuration(),

Check failure on line 27 in src/Actions/CopyToClipboardAction.php

View workflow job for this annotation

GitHub Actions / phpstan

Call to an undefined method Filament\Forms\Components\Component::getCopyMessageDuration().
rescue: fn () => 2000,
report: false,
)
);

$copyMessage = Js::from(
rescue(
callback: fn () => $component->getCopyMessage(),

Check failure on line 35 in src/Actions/CopyToClipboardAction.php

View workflow job for this annotation

GitHub Actions / phpstan

Call to an undefined method Filament\Forms\Components\Component::getCopyMessage().
rescue: fn () => __('filament::components/copyable.messages.copied'),
report: false,
)
);

return <<<JS
const text = \$wire.get('{$component->getStatePath()}');
window.navigator.clipboard.writeText(text);
\$tooltip({$copyMessage}, { theme: \$store.theme, timeout: {$copyDuration} });
JS;
});
}

public static function getDefaultName(): ?string
{
return 'copyToClipboard';
}
}
73 changes: 73 additions & 0 deletions src/Actions/RegeneratePasswordAction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?php

declare(strict_types=1);

namespace Rawilk\FilamentPasswordInput\Actions;

use Closure;
use Filament\Actions\Concerns\CanCustomizeProcess;
use Filament\Forms\Components\Actions\Action;
use Filament\Forms\Components\Component;
use Filament\Forms\Set;
use Filament\Support\Facades\FilamentIcon;
use Illuminate\Support\Str;

class RegeneratePasswordAction extends Action
{
use CanCustomizeProcess;

protected const DEFAULT_MAX_LENGTH = 32;

protected bool|Closure|null $notifyOnSuccess = null;

protected function setUp(): void
{
parent::setUp();

$this->label(__('filament-password-input::password.actions.regenerate.tooltip'));

$this->icon(FilamentIcon::resolve('filament-password-input::regenerate') ?? 'heroicon-o-key');

$this->color('gray');

$this->successNotificationTitle(__('filament-password-input::password.actions.regenerate.success_message'));

$this->action(function (Set $set, Component $component) {
$secret = $this->process(function (Component $component) {
$maxLength = rescue(
callback: fn () => $component->getNewPasswordLength() ?? static::DEFAULT_MAX_LENGTH,

Check failure on line 38 in src/Actions/RegeneratePasswordAction.php

View workflow job for this annotation

GitHub Actions / phpstan

Call to an undefined method Filament\Forms\Components\Component::getNewPasswordLength().
rescue: fn () => static::DEFAULT_MAX_LENGTH,
report: false,
);

return Str::password(max(3, $maxLength));
});

// Not sure if I'm doing something wrong here, but using ->getStatePath()
// doesn't work here, but using ->getName() sets the correct path
// to set the value.
$set($component->getName(), $secret);

Check failure on line 49 in src/Actions/RegeneratePasswordAction.php

View workflow job for this annotation

GitHub Actions / phpstan

Call to an undefined method Filament\Forms\Components\Component::getName().

if ($this->shouldNotifyOnSuccess()) {
$this->success();
}
});
}

public static function getDefaultName(): ?string
{
return 'regeneratePassword';
}

public function notifyOnSuccess(bool|Closure $condition = true): static
{
$this->notifyOnSuccess = $condition;

return $this;
}

public function shouldNotifyOnSuccess(): bool
{
return $this->evaluate($this->notifyOnSuccess) ?? true;
}
}
99 changes: 13 additions & 86 deletions src/Concerns/CanCopyToClipboard.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,30 @@
namespace Rawilk\FilamentPasswordInput\Concerns;

use Closure;
use Filament\Forms\Components\Actions\Action;
use Illuminate\Support\HtmlString;
use Illuminate\Support\Js;
use Rawilk\FilamentPasswordInput\Actions\CopyToClipboardAction;

/**
* This will behave very similar to filament's CanBeCopied trait.
*
* Big difference is we determine the state from the input's current
* value instead of defining it with php.
* @mixin \Filament\Forms\Components\TextInput
*/
trait CanCopyToClipboard
{
protected bool|Closure $isCopyable = false;

protected string|Closure|null $copyMessage = null;

protected int|Closure|null $copyMessageDuration = null;

protected string|Closure|null $copyIcon = null;

protected string|Closure|array|null $copyIconColor = null;
public function copyable(
bool|Closure $condition = true,
string|array|Closure|null $color = null,
): static {
$action = CopyToClipboardAction::make()->visible($condition);

protected string|Closure|null $copyTooltip = null;
if ($color) {
$action->color($color);
}

public function copyable(bool|Closure $condition = true): static
{
$this->isCopyable = $condition;
$this->suffixActions([
$action,
]);

return $this;
}
Expand All @@ -50,32 +47,6 @@ public function copyMessageDuration(int|Closure|null $duration): static
return $this;
}

public function copyIcon(string|Closure|null $icon): static
{
$this->copyIcon = $icon;

return $this;
}

public function copyIconColor(string|Closure|array|null $color): static
{
$this->copyIconColor = $color;

return $this;
}

public function copyTooltip(string|Closure|null $tooltip): static
{
$this->copyTooltip = $tooltip;

return $this;
}

public function isCopyable(): bool
{
return (bool) $this->evaluate($this->isCopyable);
}

public function getCopyMessage(): string
{
return $this->evaluate($this->copyMessage) ?? __('filament::components/copyable.messages.copied');
Expand All @@ -85,48 +56,4 @@ public function getCopyMessageDuration(): int
{
return $this->evaluate($this->copyMessageDuration) ?? 2000;
}

public function getCopyIcon(): string
{
return $this->evaluate($this->copyIcon) ?? 'heroicon-m-clipboard';
}

public function getCopyIconColor(): string|array|null
{
return $this->evaluate($this->copyIconColor);
}

public function getCopyTooltip(): string
{
return $this->evaluate($this->copyTooltip) ?? __('filament-password-input::password.actions.copy.tooltip');
}

public function getCopyToClipboardAction(): Action
{
$copyDuration = Js::from($this->getCopyMessageDuration());
$copyMessage = Js::from($this->getCopyMessage());
$tooltip = $this->getCopyTooltip();

$action = Action::make('copyToClipboard')
->livewireClickHandlerEnabled(false)
->icon($this->getCopyIcon())
->iconButton()
->tooltip($tooltip)
->label($tooltip)
->extraAttributes([
'x-on:click' => new HtmlString(<<<JS
const text = \$wire.get('{$this->getStatePath()}');
window.navigator.clipboard.writeText(text);
\$tooltip({$copyMessage}, { theme: \$store.theme, timeout: {$copyDuration} });
JS),
// IMO it's weird when the title and tooltip show at the same time...
'title' => '',
]);

if ($color = $this->getCopyIconColor()) {
$action->color($color);
}

return $action;
}
}
Loading

0 comments on commit 887a486

Please sign in to comment.