Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@
"larastan/larastan": "^2.9.1",
"orchestra/testbench": "^9",
"laravel/pint": "^1.14",
"rector/rector": "^1.0"
"rector/rector": "^1.0",
"livewire/livewire": "^3.4"
},
"suggest": {
"laravel/livewire": "Required for Livewire layout support."
},
"autoload": {
"psr-4": {
Expand Down
21 changes: 19 additions & 2 deletions src/Html/Enums/LayoutPosition.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,25 @@

namespace Yajra\DataTables\Html\Enums;

use Illuminate\Support\Str;

enum LayoutPosition: string
{
case Start = 'Start';
case End = 'End';
case Top = 'top';
case TopStart = 'topStart';
case TopEnd = 'topEnd';
case Bottom = 'bottom';
case BottomStart = 'bottomStart';
case BottomEnd = 'bottomEnd';

public function withOrder(?int $order): string
{
if ($order && $order > 0) {
$parts = Str::of($this->value)->ucsplit();

return $parts->shift().$order.$parts->first();
}

return $this->value;
}
}
123 changes: 89 additions & 34 deletions src/Html/Layout.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,14 @@

namespace Yajra\DataTables\Html;

use Illuminate\Contracts\Support\Renderable;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\Fluent;
use Illuminate\Support\Traits\Macroable;
use Illuminate\View\Component;
use InvalidArgumentException;
use Livewire\Livewire;
use Throwable;
use Yajra\DataTables\Html\Enums\LayoutPosition;

class Layout extends Fluent
Expand All @@ -17,79 +23,128 @@ public static function make(array $options = []): static
return new static($options);
}

public function topStart(string|array|null $options, int $order = 0): static
public function top(array|string|null $options, ?int $order = null): static
{
return $this->top($options, $order, LayoutPosition::Start);
$this->attributes[LayoutPosition::Top->withOrder($order)] = $options;

return $this;
}

public function top(array|string|null $options, ?int $order = null, ?LayoutPosition $position = null): static
public function topStart(string|array|null $options, ?int $order = null): static
{
if ($order > 0) {
$this->attributes["top{$order}{$position?->value}"] = $options;
} else {
$this->attributes["top{$position?->value}"] = $options;
}
$this->attributes[LayoutPosition::TopStart->withOrder($order)] = $options;

return $this;
}

public function topEnd(string|array|null $options, int $order = 0): static
public function topEnd(string|array|null $options, ?int $order = null): static
{
return $this->top($options, $order, LayoutPosition::End);
$this->attributes[LayoutPosition::TopEnd->withOrder($order)] = $options;

return $this;
}

public function topEndView(string $selector, int $order = 0): static
public function topView(string $selector, ?int $order = null): static
{
return $this->topView($selector, $order, LayoutPosition::End);
return $this->top($this->renderCustomElement($selector), $order);
}

public function topView(string $selector, int $order = 0, ?LayoutPosition $position = null): static
public function topStartView(string $selector, ?int $order = null): static
{
$script = "function() { return $('{$selector}').html(); }";
return $this->topStart($this->renderCustomElement($selector), $order);
}

return $this->top($script, $order, $position);
public function topEndView(string $selector, ?int $order = null): static
{
return $this->topEnd($this->renderCustomElement($selector), $order);
}

public function bottomStartView(string $selector, int $order = 0): static
public function bottom(array|string|null $options, ?int $order = null): static
{
return $this->bottomView($selector, $order, LayoutPosition::Start);
$this->attributes[LayoutPosition::Bottom->withOrder($order)] = $options;

return $this;
}

public function bottomView(string $selector, int $order = 0, ?LayoutPosition $position = null): static
public function bottomStart(string|array|null $options, ?int $order = null): static
{
$script = "function() { return $('{$selector}').html(); }";
$this->attributes[LayoutPosition::BottomStart->withOrder($order)] = $options;

return $this->bottom($script, $order, $position);
return $this;
}

public function bottom(array|string|null $options, ?int $order = null, ?LayoutPosition $position = null): static
public function bottomEnd(string|array|null $options, ?int $order = null): static
{
if ($order > 0) {
$this->attributes["bottom{$order}{$position?->value}"] = $options;
} else {
$this->attributes["bottom{$position?->value}"] = $options;
}
$this->attributes[LayoutPosition::BottomEnd->withOrder($order)] = $options;

return $this;
}

public function bottomEndView(string $selector, int $order = 0): static
public function bottomView(string $selector, ?int $order = null): static
{
return $this->bottomView($selector, $order, LayoutPosition::End);
return $this->bottom($this->renderCustomElement($selector), $order);
}

public function topStartView(string $selector, int $order = 0): static
public function bottomStartView(string $selector, ?int $order = null): static
{
return $this->topView($selector, $order, LayoutPosition::Start);
return $this->bottomStart($this->renderCustomElement($selector), $order);
}

public function bottomStart(string|array|null $options, int $order = 0): static
public function bottomEndView(string $selector, ?int $order = null): static
{
return $this->bottom($options, $order, LayoutPosition::Start);
return $this->bottomEnd($this->renderCustomElement($selector), $order);
}

/**
* @throws Throwable
*/
public function addView(
Component|Renderable|string $view,
LayoutPosition $layoutPosition,
?int $order = null
): static {
if ($view instanceof Component) {
$view = Blade::renderComponent($view);
}

$html = $view instanceof Renderable ? $view->render() : Blade::render($view);

$element = json_encode($html);

if ($element === false) {
throw new InvalidArgumentException("Cannot render view [$html] to json.");
}

$this->attributes[$layoutPosition->withOrder($order)] = $this->renderCustomElement($element, false);

return $this;
}

public function bottomEnd(string|array|null $options, int $order = 0): static
/**
* @param class-string $component
*
* @throws Throwable
*/
public function addLivewire(
string $component,
LayoutPosition $layoutPosition,
?int $order = null
): static {
$html = json_encode(Livewire::mount($component));

if ($html === false) {
throw new InvalidArgumentException("Cannot render Livewire component [$component] to json.");
}

$this->attributes[$layoutPosition->withOrder($order)] = $this->renderCustomElement($html, false);

return $this;
}

private function renderCustomElement(string $element, bool $asJsSelector = true): string
{
return $this->bottom($options, $order, LayoutPosition::End);
$html = $asJsSelector ? "$('{$element}').html()" : $element;

return "function() { return $html; }";
}
}
Loading