Skip to content

Commit

Permalink
Toast exception API (#357)
Browse files Browse the repository at this point in the history
* Sidebar: better `collapse`

Try another approach to better positioning `collapse` button

* WIP

* Support throwing an exception which produces a toast error

* Add try and catch to the toast exceptions for more reliable code

* ToastException: apply same API from Toast Trait.

---------

Co-authored-by: Jed Jones <[email protected]>
Co-authored-by: jed <[email protected]>
  • Loading branch information
3 people authored Mar 27, 2024
1 parent ebd6dcc commit 601842d
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 41 deletions.
122 changes: 84 additions & 38 deletions src/Exceptions/ToastException.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,20 @@

namespace Mary\Exceptions;


use Exception;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Blade;

class ToastException extends Exception
{

protected string $type = 'info';

protected ?string $title = null;

protected ?string $description = null;

protected string $position = 'toast-top toast-middle';
protected string $position = 'toast-top toast-end';

protected string $icon = 'o-information-circle';

Expand All @@ -27,59 +25,108 @@ class ToastException extends Exception

protected bool $preventDefault = true;

public static function typedMessage(string $type, string $message, ?string $title = null): self
{
$instance = new self(message: $message, code: 500);
public static function typedMessage(
string $type,
string $title,
string $description = null,
string $position = 'toast-top toast-end',
string $icon = 'o-information-circle',
string $css = 'alert-info',
int $timeout = 3000
): self {
$instance = new self(message: $title, code: 500);

$instance->type = $type;
$instance->title = $title;
$instance->description = $description;
$instance->position = $position;
$instance->icon = $icon;
$instance->css = $css;
$instance->timeout = $timeout;

return $instance;
}

public static function info(string $message, ?string $title = null, array $options = []): self
{
$default = ['css' => 'alert-info', 'icon' => 'o-information-circle'];
return self::typedMessage(type: 'info', message: $message, title: $title)->options(
options: [...$default, ...$options]
public static function info(
string $title,
string $description = null,
string $position = 'toast-top toast-end',
string $icon = 'o-information-circle',
string $css = 'alert-info',
int $timeout = 3000,
): self {
return self::typedMessage(
type: 'info',
title: $title,
description: $description,
position: $position,
icon: $icon,
css: $css,
timeout: $timeout
);
}

public static function success(string $message, ?string $title = null, array $options = []): self
{
$default = ['css' => 'alert-success', 'icon' => 'o-check-circle'];
return self::typedMessage(type: 'success', message: $message, title: $title)->options(
options: [...$default, ...$options]
public static function success(
string $title,
string $description = null,
string $position = 'toast-top toast-end',
string $icon = 'o-check-circle',
string $css = 'alert-success',
int $timeout = 3000,
): self {
return self::typedMessage(
type: 'success',
title: $title,
description: $description,
position: $position,
icon: $icon,
css: $css,
timeout: $timeout
);
}

public static function error(string $message, ?string $title = null, array $options = []): self
{
$default = ['css' => 'alert-error', 'icon' => 'o-x-circle'];
return self::typedMessage(type: 'error', message: $message, title: $title)->options(
options: [...$default, ...$options]
public static function error(
string $title,
string $description = null,
string $position = 'toast-top toast-end',
string $icon = 'o-x-circle',
string $css = 'alert-error',
int $timeout = 3000,
): self {
return self::typedMessage(
type: 'error',
title: $title,
description: $description,
position: $position,
icon: $icon,
css: $css,
timeout: $timeout
);
}

public static function warning(string $message, ?string $title = null, array $options = []): self
{
$default = ['css' => 'alert-warning', 'icon' => 'o-exclamation-triangle'];
return self::typedMessage(type: 'warning', message: $message, title: $title)->options(
options: [...$default, ...$options]
public static function warning(
string $title,
string $description = null,
string $position = 'toast-top toast-end',
string $icon = 'o-exclamation-triangle',
string $css = 'alert-warning',
int $timeout = 3000,
): self {
return self::typedMessage(
type: 'warning',
title: $title,
description: $description,
position: $position,
icon: $icon,
css: $css,
timeout: $timeout
);
}

public function options(array $options): self
{
$this->position = $options['position'] ?? $this->position;
$this->icon = $options['icon'] ?? $this->icon;
$this->css = $options['css'] ?? $this->css;
$this->timeout = $options['timeout'] ?? $this->timeout;
$this->preventDefault = $options['preventDefault'] ?? $this->preventDefault;
return $this;
}

public function permitDefault(): self
{
$this->preventDefault = false;

return $this;
}

Expand All @@ -90,7 +137,7 @@ public function render(Request $request): JsonResponse|false
'toast' => [
'type' => $this->type,
'title' => $this->title,
'description' => $this->getMessage(),
'description' => $this->description,

'position' => $this->position,
'icon' => Blade::render("<x-mary-icon class='w-7 h-7' name='" . $this->icon . "' />"),
Expand All @@ -103,5 +150,4 @@ public function render(Request $request): JsonResponse|false

return false;
}

}
7 changes: 4 additions & 3 deletions src/View/Components/Toast.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,18 @@ class="toast !whitespace-normal rounded-md fixed cursor-pointer z-50"
<script>
window.toast = function(payload){
window.dispatchEvent(new CustomEvent('mary-toast', {detail: payload}))
}
}
document.addEventListener('livewire:init', () => {
Livewire.hook('request', ({fail}) => {
fail(({status, content, preventDefault}) => {
try {
let result = JSON.parse(content);
if (result?.toast && typeof window.toast === "function") {
window.toast(result);
}
if ((result?.prevent_default ?? false) === true) {
preventDefault();
}
Expand Down

0 comments on commit 601842d

Please sign in to comment.