Skip to content
Open
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
7 changes: 5 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,10 @@
}
},
"scripts": {
"phpunit": "@php -d memory_limit=2G vendor/bin/phpunit --display-warnings --display-skipped --display-deprecations --display-errors --display-notices",
"phpunit": [
"Composer\\Config::disableProcessTimeout",
"@php -d memory_limit=2G vendor/bin/phpunit --display-warnings --display-skipped --display-deprecations --display-errors --display-notices"
],
"coverage": "vendor/bin/phpunit --coverage-html build/reports/html --coverage-clover build/reports/clover.xml",
"fmt": "vendor/bin/mago fmt",
"lint:fix": "vendor/bin/mago lint --fix --format-after-fix",
Expand Down Expand Up @@ -276,4 +279,4 @@
"composer exceptions:build"
]
}
}
}
69 changes: 69 additions & 0 deletions docs/1-essentials/02-views.md
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,75 @@ This component provides the ability to inject any icon from the [Iconify](https:
```html
<x-icon name="material-symbols:php" class="size-4 text-indigo-400" />
```
will render
```html
<svg class="size-4 text-indigo-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path
fill="currentcolor"
d="m3 15v9h3.5q.6 0 1.05.45t8 10.5v1q0 .6-.45 1.05t6.5 13h-2v2zm6.5 0v9h11v2h2v9h1.5v6h13v-2.5h-2v15zm7 0v9h20q.6 0 1.05.45t.45 1.05v1q0 .6-.45 1.05t20 13h-2v2zm-12-3.5h2v-1h-2zm13.5 0h2v-1h-2z"
/>
</svg>
```

This component includes some optional props you can use to control width and height. As a fallback, if you specify no class, no style, no width & height, the component will render a default width and height, but you can override this behaviour in any of the following ways.

```html
<x-icon name="material-symbols:php" />
```
will render
```html
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24">
<path
fill="currentcolor"
d="m3 15v9h3.5q.6 0 1.05.45t8 10.5v1q0 .6-.45 1.05t6.5 13h-2v2zm6.5 0v9h11v2h2v9h1.5v6h13v-2.5h-2v15zm7 0v9h20q.6 0 1.05.45t.45 1.05v1q0 .6-.45 1.05t20 13h-2v2zm-12-3.5h2v-1h-2zm13.5 0h2v-1h-2z"
/>
</svg>
```

Firstly, you can set width and height using Tailwind or custom classes. As long as you pass the `class` prop, the component will assume you are providing suitable dimensions, and will not check, or assert, any default dimensions.

```html
<x-icon name="material-symbols:php" class="w-[24px] h-[24px] text-indigo-400" />
```
will render
```html
<svg class="w-[24px] h-[24px] text-indigo-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path
fill="currentcolor"
d="m3 15v9h3.5q.6 0 1.05.45t8 10.5v1q0 .6-.45 1.05t6.5 13h-2v2zm6.5 0v9h11v2h2v9h1.5v6h13v-2.5h-2v15zm7 0v9h20q.6 0 1.05.45t.45 1.05v1q0 .6-.45 1.05t20 13h-2v2zm-12-3.5h2v-1h-2zm13.5 0h2v-1h-2z"
/>
</svg>
```

Secondly, if you aren't using Tailwind, or wish to set for a single icon without making a class, you can instead pass dimensions via the `style` prop. Again, as long as you pass `style`, the component will assume you are providing suitable dimensions, and will not check, or assert, any default dimensions.

```html
<x-icon name="material-symbols:php" style="width: 24px; height: 24px;" />
```
will render
```html
<svg style="width: 24px; height: 24px;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path
fill="currentcolor"
d="m3 15v9h3.5q.6 0 1.05.45t8 10.5v1q0 .6-.45 1.05t6.5 13h-2v2zm6.5 0v9h11v2h2v9h1.5v6h13v-2.5h-2v15zm7 0v9h20q.6 0 1.05.45t.45 1.05v1q0 .6-.45 1.05t20 13h-2v2zm-12-3.5h2v-1h-2zm13.5 0h2v-1h-2z"
/>
</svg>
```

Finally, you may provide the width and height properties directly with the props `width` and `height`. The component requires both to be set, or will render the fallback dimensions.

```html
<x-icon name="material-symbols:php" width="24px" height="24px" />
```
will render
```html
<svg xmlns="http://www.w3.org/2000/svg" width="24px" height="24px" viewBox="0 0 24 24">
<path
fill="currentcolor"
d="m3 15v9h3.5q.6 0 1.05.45t8 10.5v1q0 .6-.45 1.05t6.5 13h-2v2zm6.5 0v9h11v2h2v9h1.5v6h13v-2.5h-2v15zm7 0v9h20q.6 0 1.05.45t.45 1.05v1q0 .6-.45 1.05t20 13h-2v2zm-12-3.5h2v-1h-2zm13.5 0h2v-1h-2z"
/>
</svg>
```

The first time a specific icon is being rendered, Tempest will query the [Iconify API](https://iconify.design/docs/api/queries.html) to fetch the corresponding SVG tag. The result of this query will be cached indefinitely, so it can be reused at no further cost.

Expand Down
62 changes: 44 additions & 18 deletions packages/view/src/Components/x-icon.view.php
Original file line number Diff line number Diff line change
@@ -1,37 +1,63 @@
<?php
/**
* @var string $name
* SEE: docs/1-essentials/02-views.md for usage instructions
* @var string|null $name
* @var string|null $class
* @var string|null $style
* @var string|null $width
* @var string|null $height
*/

use Tempest\Core\Environment;
use Tempest\Icon\Icon;
use Tempest\Support\Str\ImmutableString;

use function Tempest\Container\get;
use function Tempest\Support\str;

$class ??= null;
$name ??= null;
$environment = get(Environment::class);

if ($name) {
$svg = get(Icon::class)->render($name);
} else {
$svg = null;
}

if ($svg === null && $environment->isLocal()) {
$svg = '<!-- unknown-icon: ' . $name . ' -->';
}

if ($class) {
$svg = str($svg)
->replace(
$svg = str(is_string($name) ? get(Icon::class)->render($name) : null)
->when(
fn (ImmutableString $s): bool => $s->toString() === '' && $environment->isLocal(),
fn (ImmutableString $s): ImmutableString => str("<!-- unknown-icon: {$name} -->"),
)
->replace(
search: " width=\"1em\" height=\"1em\"",
replace: '',
)
->when(
$style ?? null,
fn (ImmutableString $s): ImmutableString => $s->replace(
search: '<svg',
replace: "<svg style=\"{$style}\"",
),
)
->when(
$class ?? null,
fn (ImmutableString $s): ImmutableString => $s->replace(
search: '<svg',
replace: "<svg class=\"{$class}\"",
)
->toString();
}
),
)
->when(
isset($width, $height),
fn (ImmutableString $s): ImmutableString => $s
->replace(
search: '<svg',
replace: "<svg width=\"{$width}\" height=\"{$height}\"",
),
)
->when(
! isset($width, $height) && ! isset($style) && ! isset($class),
fn (ImmutableString $s): ImmutableString => $s
->replace(
search: '<svg',
replace: "<svg width=\"1em\" height=\"1em\"",
),
)
->toString();
?>

{!! $svg !!}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<x-test-layout>
<x-slot name="icon">
<x-icon name="ph:eye" class="size-5" />
<x-icon name="material-symbols:php" class="size-5" />
</x-slot>
Test
</x-test-layout>
Loading