Skip to content

Commit

Permalink
Signature: new component (#391)
Browse files Browse the repository at this point in the history
  • Loading branch information
robsontenorio committed Apr 23, 2024
1 parent 842a211 commit 30effef
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/MaryServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
use Mary\View\Components\Radio;
use Mary\View\Components\Range;
use Mary\View\Components\Select;
use Mary\View\Components\Signature;
use Mary\View\Components\Spotlight;
use Mary\View\Components\Stat;
use Mary\View\Components\Step;
Expand Down Expand Up @@ -152,6 +153,7 @@ public function registerComponents()
Blade::component($prefix . 'radio', Radio::class);
Blade::component($prefix . 'range', Range::class);
Blade::component($prefix . 'select', Select::class);
Blade::component($prefix . 'signature', Signature::class);
Blade::component($prefix . 'spotlight', Spotlight::class);
Blade::component($prefix . 'stat', Stat::class);
Blade::component($prefix . 'steps', Steps::class);
Expand Down
101 changes: 101 additions & 0 deletions src/View/Components/Signature.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<?php

namespace Mary\View\Components;

use Closure;
use Illuminate\Contracts\View\View;
use Illuminate\View\Component;

class Signature extends Component
{
public string $uuid;

public function __construct(
public ?string $height = '250',
public ?string $clearText = 'Clear',
public ?string $hint = null,
public ?array $config = [],

// Validations
public ?string $errorClass = 'text-red-500 label-text-alt p-1',

) {
$this->uuid = "mary" . md5(serialize($this));
}

public function modelName(): ?string
{
return $this->attributes->whereStartsWith('wire:model')->first();
}

public function setup(): string
{
return json_encode(array_merge([

], $this->config));
}

public function render(): View|Closure|string
{
return <<<'HTML'
<div
x-data="{
value: @entangle($attributes->wire('model')),
signature: null,
init() {
let canvas = document.getElementById('{{ $uuid }}signature')
this.signature = new SignaturePad(canvas, {{ $setup() }});
// Resize
const ratio = Math.max(window.devicePixelRatio || 1, 1);
canvas.width = canvas.offsetWidth * ratio;
canvas.height = canvas.offsetHeight * ratio;
canvas.getContext('2d').scale(ratio, ratio);
this.signature.fromData(this.signature.toData());
// Event
this.signature.addEventListener('endStroke', () => this.extract() );
},
extract() {
this.value = this.signature.toDataURL();
},
clear() {
this.signature.clear();
this.extract();
}
}"
wire:ignore
class="select-none touch-none block"
>
<div
{{
$attributes
->except("wire:model")
->class([
"border border-primary rounded-lg relative bg-white select-none touch-none block",
"!border-error" => $errors->has($modelName())
])
}}
}>
<canvas id="{{ $uuid }}signature" height="{{ $height }}" class="rounded-lg block w-full select-none touch-none"></canvas>
<!-- CLEAR BUTTON -->
<div class="absolute right-2 top-1/2 -translate-y-1/2 ">
<x-mary-button icon="o-backspace" :label="$clearText" @click="clear" class="btn-sm btn-ghost text-neutral" />
</div>
</div>
<!-- ERROR -->
@error($modelName())
<div class="{{ $errorClass }}" x-classes="text-red-500 label-text-alt p-1">{{ $message }}</div>
@enderror
<!-- HINT -->
@if($hint)
<div class="label-text-alt text-gray-400 p-1 pb-0">{{ $hint }}</div>
@endif
</div>
HTML;
}
}

0 comments on commit 30effef

Please sign in to comment.