Skip to content

Commit

Permalink
[1.x] Custom card CSS (#157)
Browse files Browse the repository at this point in the history
* Allow cards to include custom CSS

* Fix code styling

* Allow Htmlable CSS

* Fix code styling

* Add tests

* Fix code styling

---------

Co-authored-by: jessarcher <[email protected]>
  • Loading branch information
jessarcher and jessarcher authored Dec 6, 2023
1 parent 08559ae commit 6404f90
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 13 deletions.
8 changes: 2 additions & 6 deletions resources/views/components/pulse.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,11 @@
<link rel="preconnect" href="https://fonts.bunny.net">
<link href="https://fonts.bunny.net/css?family=figtree:300,400,500,600" rel="stylesheet" />

<style>
{!! Laravel\Pulse\Facades\Pulse::css() !!}
</style>
{!! Laravel\Pulse\Facades\Pulse::css() !!}

@livewireStyles

<script>
{!! Laravel\Pulse\Facades\Pulse::js() !!}
</script>
{!! Laravel\Pulse\Facades\Pulse::js() !!}
</head>
<body class="font-sans antialiased">
<div class="bg-gray-50 dark:bg-gray-950 min-h-screen">
Expand Down
2 changes: 1 addition & 1 deletion src/Facades/Pulse.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
* @method static \Laravel\Pulse\Pulse resolveAuthenticatedUserIdUsing(callable $callback)
* @method static mixed|null withUser(\Illuminate\Contracts\Auth\Authenticatable|string|int|null $user, callable $callback)
* @method static \Laravel\Pulse\Pulse rememberUser(\Illuminate\Contracts\Auth\Authenticatable $user)
* @method static string css()
* @method static string|self css(array|string|\Illuminate\Contracts\Support\Htmlable|null $path = null)
* @method static string js()
* @method static bool registersRoutes()
* @method static \Laravel\Pulse\Pulse ignoreRoutes()
Expand Down
26 changes: 26 additions & 0 deletions src/Livewire/Card.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

use Illuminate\Contracts\Support\Renderable;
use Illuminate\Support\Facades\View;
use Laravel\Pulse\Facades\Pulse;
use Livewire\Component;
use Livewire\Livewire;

abstract class Card extends Component
{
Expand Down Expand Up @@ -43,4 +45,28 @@ public function placeholder(): Renderable
'class' => $this->class,
]);
}

/**
* Capture component-specific CSS.
*
* @return void
*/
public function dehydrate()
{
if (Livewire::isLivewireRequest()) {
return;
}

Pulse::css($this->css());
}

/**
* Define any CSS that should be loaded for the component.
*
* @return string|\Illuminate\Contracts\Support\Htmlable|array<int, string|\Illuminate\Contracts\Support\Htmlable>|null
*/
protected function css()
{
return null;
}
}
36 changes: 30 additions & 6 deletions src/Pulse.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\Support\Htmlable;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Illuminate\Support\Lottery;
use Illuminate\Support\Str;
use Illuminate\Support\Traits\ForwardsCalls;
use Laravel\Pulse\Contracts\Ingest;
use Laravel\Pulse\Contracts\Storage;
Expand Down Expand Up @@ -89,6 +92,13 @@ class Pulse
*/
protected $handleExceptionsUsing = null;

/**
* The CSS paths to include on the dashboard.
*
* @var list<string|Htmlable>
*/
protected $css = [__DIR__.'/../dist/pulse.css'];

/**
* Create a new Pulse instance.
*/
Expand Down Expand Up @@ -428,15 +438,29 @@ public function rememberUser(Authenticatable $user): self
}

/**
* Return the compiled CSS from the vendor directory.
* Register or return CSS for the Pulse dashboard.
*
* @param string|Htmlable|list<string|Htmlable>|null $css
*/
public function css(): string
public function css(string|Htmlable|array|null $css = null): string|self
{
if (($content = file_get_contents(__DIR__.'/../dist/pulse.css')) === false) {
throw new RuntimeException('Unable to load Pulse dashboard CSS.');
if (func_num_args() === 1) {
$this->css = array_values(array_unique(array_merge($this->css, Arr::wrap($css))));

return $this;
}

return $content;
return collect($this->css)->reduce(function ($carry, $css) {
if ($css instanceof Htmlable) {
return $carry.Str::finish($css->toHtml(), PHP_EOL);
} else {
if (($contents = @file_get_contents($css)) === false) {
throw new RuntimeException("Unable to load Pulse dashboard CSS path [$css].");
}

return $carry."<style>{$contents}</style>".PHP_EOL;
}
}, '');
}

/**
Expand All @@ -448,7 +472,7 @@ public function js(): string
throw new RuntimeException('Unable to load the Pulse dashboard JavaScript.');
}

return $content;
return "<script>{$content}</script>".PHP_EOL;
}

/**
Expand Down
55 changes: 55 additions & 0 deletions tests/Feature/Livewire/CustomCardTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

use Illuminate\Support\HtmlString;
use Laravel\Pulse\Facades\Pulse;
use Laravel\Pulse\Livewire\Card;
use Livewire\Livewire;

it('loads custom css using a path', function () {
Livewire::test(CustomCardWithCssPath::class)
->assertOk();

$css = Pulse::css();

expect($css)->toContain(<<<'HTML'
<style>.custom-class {
color: purple;
}
</style>
HTML);
});

it('loads custom css using a Htmlable', function () {
Livewire::test(CustomCardWithCssHtmlable::class)
->assertOk();

$css = Pulse::css();

expect($css)->toContain('<link rel="stylesheet" src="https://example.com/cdn/custom-card.css">');
});

class CustomCardWithCssPath extends Card
{
public function render()
{
return '<div></div>';
}

protected function css()
{
return __DIR__.'/../../fixtures/custom.css';
}
}

class CustomCardWithCssHtmlable extends Card
{
public function render()
{
return '<div></div>';
}

protected function css()
{
return new HtmlString('<link rel="stylesheet" src="https://example.com/cdn/custom-card.css">');
}
}
3 changes: 3 additions & 0 deletions tests/fixtures/custom.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.custom-class {
color: purple;
}

0 comments on commit 6404f90

Please sign in to comment.