Skip to content

Commit

Permalink
Add new Callout form component
Browse files Browse the repository at this point in the history
Introduces a new collapsible form component named Callout in the Filament Toolbox, with customizability options such as icon characteristics and content display methods. The component contains properties and methods to provision display options like Markdown or HTML content, icon color selection, and more.
  • Loading branch information
rhiannonjourney committed Apr 12, 2024
1 parent 9a03027 commit 74379b7
Show file tree
Hide file tree
Showing 2 changed files with 226 additions and 0 deletions.
86 changes: 86 additions & 0 deletions resources/views/forms/components/callout.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<div
@if ($isCollapsible())
x-data="{ isCollapsed: {{ $isCollapsed() ? 'true' : 'false' }} }"
x-on:open-form-section.window="if ($event.detail.id == $el.id) isCollapsed = false"
x-on:collapse-form-section.window="if ($event.detail.id == $el.id) isCollapsed = true"
x-on:toggle-form-section.window="if ($event.detail.id == $el.id) isCollapsed = ! isCollapsed"
x-on:expand-concealing-component.window="
if ($event.detail.id === $el.id) {
isCollapsed = false
$el.scrollIntoView({ behavior: 'smooth', block: 'start' })
}
"
@endif
id="{{ $getId() }}"
{{ $attributes->merge($getExtraAttributes())->class([
'bg-gray-100 rounded-xl border-gray-300',
'dark:bg-gray-900' => config('forms.dark_mode'),
]) }}
>
<div
@class([
'flex items-center px-4 py-2 bg-gray-100 rtl:space-x-reverse overflow-hidden rounded-t-xl filament-forms-section-header-wrapper',
'dark:bg-gray-900' => config('forms.dark_mode'),
])
@if ($isCollapsible())
x-bind:class="{ 'rounded-b-xl': isCollapsed }"
@endif
>
@if($icon = $getIcon())
@php
$iconColor = match ($getIconColor()) {
'danger' => 'text-danger-500',
'primary' => 'text-primary-500',
'success' => 'text-success-500',
'warning' => 'text-warning-500',
default => 'text-gray-700',
};
@endphp
<x-dynamic-component
:component="$icon"
:class="'w-6 h-6 mr-3' . ' ' . $iconColor"
/>
@endif

<div class="flex-1 filament-forms-section-header">
<h3 class="text-xl font-bold tracking-tight">
{{ $getHeading() }}
</h3>
</div>

@if ($isCollapsible())
<button x-on:click="isCollapsed = ! isCollapsed"
x-bind:class="{
'-rotate-180': !isCollapsed,
}" type="button"
@class([
'flex items-center justify-center w-8 h-8 transform rounded-full text-primary-500 hover:bg-gray-500/5 focus:bg-primary-500/10 focus:outline-none',
'-rotate-180' => ! $isCollapsed(),
])
>
<svg class="h-4 w-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/>
</svg>
</button>
@endif
</div>

<div
@if ($isCollapsible())
x-bind:class="{ 'invisible h-0 !m-0 overflow-y-hidden': isCollapsed }"
x-bind:aria-expanded="(! isCollapsed).toString()"
@if ($isCollapsed()) x-cloak @endif
@endif
class=""
>
<div class="px-4 pb-2">
<div @class([
"prose max-w-none",
"dark:text-gray-100 dark:prose-strong:text-gray-100 dark:prose-strong:font-bold" => config('forms.dark_mode'),
])>
{{ $getContent() }}
</div>
</div>
</div>
</div>
140 changes: 140 additions & 0 deletions src/Forms/Components/Callout.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
<?php

namespace UnexpectedJourney\FilamentToolbox\Forms\Components;

use Closure;
use Filament\Forms\Components\Component;
use Filament\Forms\Components\Concerns\CanBeCollapsed;
use Illuminate\Contracts\Support\Htmlable;
use Illuminate\Support\HtmlString;
use Illuminate\Support\Str;

class Callout extends Component
{
use CanBeCollapsed;

protected string $view = 'toolbox::forms.components.callout';

protected string | Htmlable | Closure | null $content = null;

protected string | Closure | null $heading = null;

protected bool $isMarkdown = false;

protected bool $isHtml = false;

protected string | Closure | null $icon = null;

protected string | Closure | null $iconColor = null;

final public function __construct(string | Closure | null $heading = null)
{
$this->heading($heading);
}

public static function make(string | Closure | null $heading = null): static
{
$static = app(static::class, ['heading' => $heading]);
$static->configure();

return $static;
}

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

$this->columnSpan('full');
}

public function warning(): static
{
$this->iconColor('warning');
$this->icon('heroicon-o-exclamation-triangle');

return $this;
}

public function help(): static
{
$this->collapsed(true);
$this->icon('heroicon-o-question-mark-circle');
$this->iconColor('primary');

return $this;
}

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

return $this;
}

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

return $this;
}

public function getContent(): string | Htmlable | null
{
$content = $this->evaluate($this->content);

if ($this->isHtml) {
return $content instanceof Htmlable
? $content
: new HtmlString($content);
}

if ($this->isMarkdown) {
return new HtmlString(Str::markdown($content));
}

return $content;
}

public function getHeading(): ?string
{
return $this->evaluate($this->heading);
}

public function markdown(bool $markdown = true): static
{
$this->isMarkdown = $markdown;

return $this;
}

public function html(bool $html = true): static
{
$this->isHtml = $html;

return $this;
}

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

return $this;
}

public function getIcon(): ?string
{
return $this->evaluate($this->icon);
}

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

return $this;
}

public function getIconColor(): ?string
{
return $this->evaluate($this->iconColor);
}
}

0 comments on commit 74379b7

Please sign in to comment.