Skip to content

Commit 18d68b6

Browse files
authored
Merge pull request #219 from ejgandelaberon/master
feat: Allow passing view and livewire components to layout builder
2 parents 1c8b2a0 + 86d04fc commit 18d68b6

File tree

9 files changed

+315
-45
lines changed

9 files changed

+315
-45
lines changed

composer.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,11 @@
2525
"larastan/larastan": "^2.9.1",
2626
"orchestra/testbench": "^9",
2727
"laravel/pint": "^1.14",
28-
"rector/rector": "^1.0"
28+
"rector/rector": "^1.0",
29+
"livewire/livewire": "^3.4"
30+
},
31+
"suggest": {
32+
"laravel/livewire": "Required for Livewire layout support."
2933
},
3034
"autoload": {
3135
"psr-4": {

src/Html/Enums/LayoutPosition.php

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,25 @@
44

55
namespace Yajra\DataTables\Html\Enums;
66

7+
use Illuminate\Support\Str;
8+
79
enum LayoutPosition: string
810
{
9-
case Start = 'Start';
10-
case End = 'End';
11+
case Top = 'top';
12+
case TopStart = 'topStart';
13+
case TopEnd = 'topEnd';
14+
case Bottom = 'bottom';
15+
case BottomStart = 'bottomStart';
16+
case BottomEnd = 'bottomEnd';
17+
18+
public function withOrder(?int $order): string
19+
{
20+
if ($order && $order > 0) {
21+
$parts = Str::of($this->value)->ucsplit();
22+
23+
return $parts->shift().$order.$parts->first();
24+
}
25+
26+
return $this->value;
27+
}
1128
}

src/Html/Layout.php

Lines changed: 89 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,14 @@
44

55
namespace Yajra\DataTables\Html;
66

7+
use Illuminate\Contracts\Support\Renderable;
8+
use Illuminate\Support\Facades\Blade;
79
use Illuminate\Support\Fluent;
810
use Illuminate\Support\Traits\Macroable;
11+
use Illuminate\View\Component;
12+
use InvalidArgumentException;
13+
use Livewire\Livewire;
14+
use Throwable;
915
use Yajra\DataTables\Html\Enums\LayoutPosition;
1016

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

20-
public function topStart(string|array|null $options, int $order = 0): static
26+
public function top(array|string|null $options, ?int $order = null): static
2127
{
22-
return $this->top($options, $order, LayoutPosition::Start);
28+
$this->attributes[LayoutPosition::Top->withOrder($order)] = $options;
29+
30+
return $this;
2331
}
2432

25-
public function top(array|string|null $options, ?int $order = null, ?LayoutPosition $position = null): static
33+
public function topStart(string|array|null $options, ?int $order = null): static
2634
{
27-
if ($order > 0) {
28-
$this->attributes["top{$order}{$position?->value}"] = $options;
29-
} else {
30-
$this->attributes["top{$position?->value}"] = $options;
31-
}
35+
$this->attributes[LayoutPosition::TopStart->withOrder($order)] = $options;
3236

3337
return $this;
3438
}
3539

36-
public function topEnd(string|array|null $options, int $order = 0): static
40+
public function topEnd(string|array|null $options, ?int $order = null): static
3741
{
38-
return $this->top($options, $order, LayoutPosition::End);
42+
$this->attributes[LayoutPosition::TopEnd->withOrder($order)] = $options;
43+
44+
return $this;
3945
}
4046

41-
public function topEndView(string $selector, int $order = 0): static
47+
public function topView(string $selector, ?int $order = null): static
4248
{
43-
return $this->topView($selector, $order, LayoutPosition::End);
49+
return $this->top($this->renderCustomElement($selector), $order);
4450
}
4551

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

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

53-
public function bottomStartView(string $selector, int $order = 0): static
62+
public function bottom(array|string|null $options, ?int $order = null): static
5463
{
55-
return $this->bottomView($selector, $order, LayoutPosition::Start);
64+
$this->attributes[LayoutPosition::Bottom->withOrder($order)] = $options;
65+
66+
return $this;
5667
}
5768

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

62-
return $this->bottom($script, $order, $position);
73+
return $this;
6374
}
6475

65-
public function bottom(array|string|null $options, ?int $order = null, ?LayoutPosition $position = null): static
76+
public function bottomEnd(string|array|null $options, ?int $order = null): static
6677
{
67-
if ($order > 0) {
68-
$this->attributes["bottom{$order}{$position?->value}"] = $options;
69-
} else {
70-
$this->attributes["bottom{$position?->value}"] = $options;
71-
}
78+
$this->attributes[LayoutPosition::BottomEnd->withOrder($order)] = $options;
7279

7380
return $this;
7481
}
7582

76-
public function bottomEndView(string $selector, int $order = 0): static
83+
public function bottomView(string $selector, ?int $order = null): static
7784
{
78-
return $this->bottomView($selector, $order, LayoutPosition::End);
85+
return $this->bottom($this->renderCustomElement($selector), $order);
7986
}
8087

81-
public function topStartView(string $selector, int $order = 0): static
88+
public function bottomStartView(string $selector, ?int $order = null): static
8289
{
83-
return $this->topView($selector, $order, LayoutPosition::Start);
90+
return $this->bottomStart($this->renderCustomElement($selector), $order);
8491
}
8592

86-
public function bottomStart(string|array|null $options, int $order = 0): static
93+
public function bottomEndView(string $selector, ?int $order = null): static
8794
{
88-
return $this->bottom($options, $order, LayoutPosition::Start);
95+
return $this->bottomEnd($this->renderCustomElement($selector), $order);
96+
}
97+
98+
/**
99+
* @throws Throwable
100+
*/
101+
public function addView(
102+
Component|Renderable|string $view,
103+
LayoutPosition $layoutPosition,
104+
?int $order = null
105+
): static {
106+
if ($view instanceof Component) {
107+
$view = Blade::renderComponent($view);
108+
}
109+
110+
$html = $view instanceof Renderable ? $view->render() : Blade::render($view);
111+
112+
$element = json_encode($html);
113+
114+
if ($element === false) {
115+
throw new InvalidArgumentException("Cannot render view [$html] to json.");
116+
}
117+
118+
$this->attributes[$layoutPosition->withOrder($order)] = $this->renderCustomElement($element, false);
119+
120+
return $this;
89121
}
90122

91-
public function bottomEnd(string|array|null $options, int $order = 0): static
123+
/**
124+
* @param class-string $component
125+
*
126+
* @throws Throwable
127+
*/
128+
public function addLivewire(
129+
string $component,
130+
LayoutPosition $layoutPosition,
131+
?int $order = null
132+
): static {
133+
$html = json_encode(Livewire::mount($component));
134+
135+
if ($html === false) {
136+
throw new InvalidArgumentException("Cannot render Livewire component [$component] to json.");
137+
}
138+
139+
$this->attributes[$layoutPosition->withOrder($order)] = $this->renderCustomElement($html, false);
140+
141+
return $this;
142+
}
143+
144+
private function renderCustomElement(string $element, bool $asJsSelector = true): string
92145
{
93-
return $this->bottom($options, $order, LayoutPosition::End);
146+
$html = $asJsSelector ? "$('{$element}').html()" : $element;
147+
148+
return "function() { return $html; }";
94149
}
95150
}

0 commit comments

Comments
 (0)