Skip to content

Commit bacbd07

Browse files
committed
Implement mj-carousel components
1 parent 03d748f commit bacbd07

File tree

3 files changed

+273
-0
lines changed

3 files changed

+273
-0
lines changed
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
<?php
2+
3+
/**
4+
* PHP MJML Renderer library
5+
*
6+
* @package MadeByDenis\PhpMjmlRenderer
7+
* @link https://github.com/dingo-d/php-mjml-renderer
8+
* @license https://opensource.org/licenses/MIT MIT
9+
*/
10+
11+
declare(strict_types=1);
12+
13+
namespace MadeByDenis\PhpMjmlRenderer\Elements\BodyComponents;
14+
15+
use MadeByDenis\PhpMjmlRenderer\Elements\AbstractElement;
16+
17+
/**
18+
* Mjml Carousel Element
19+
*
20+
* Displays an interactive image carousel with navigation.
21+
*
22+
* @link https://documentation.mjml.io/#mj-carousel
23+
*
24+
* @since 1.0.0
25+
*/
26+
class MjCarousel extends AbstractElement
27+
{
28+
public const string TAG_NAME = 'mj-carousel';
29+
30+
public const bool ENDING_TAG = false;
31+
32+
/**
33+
* List of allowed attributes on the element
34+
*
35+
* @var array<string, array<string, string>>
36+
*/
37+
protected array $allowedAttributes = [
38+
'align' => [
39+
'unit' => 'string',
40+
'type' => 'alignment',
41+
'description' => 'horizontal alignment',
42+
'default_value' => 'center',
43+
],
44+
'border-radius' => [
45+
'unit' => 'px',
46+
'type' => 'string',
47+
'description' => 'border radius',
48+
'default_value' => '',
49+
],
50+
'container-background-color' => [
51+
'unit' => 'color',
52+
'type' => 'color',
53+
'description' => 'column background color',
54+
'default_value' => '',
55+
],
56+
'icon-width' => [
57+
'unit' => 'px',
58+
'type' => 'string',
59+
'description' => 'width of icons',
60+
'default_value' => '44px',
61+
],
62+
'left-icon' => [
63+
'unit' => 'string',
64+
'type' => 'string',
65+
'description' => 'icon on the left',
66+
'default_value' => 'https://i.imgur.com/xTh3hln.png',
67+
],
68+
'right-icon' => [
69+
'unit' => 'string',
70+
'type' => 'string',
71+
'description' => 'icon on the right',
72+
'default_value' => 'https://i.imgur.com/os7o9kz.png',
73+
],
74+
'thumbnails' => [
75+
'unit' => 'string',
76+
'type' => 'string',
77+
'description' => 'display or not thumbnails (visible/hidden)',
78+
'default_value' => 'visible',
79+
],
80+
];
81+
82+
protected array $defaultAttributes = [
83+
'align' => 'center',
84+
'icon-width' => '44px',
85+
'left-icon' => 'https://i.imgur.com/xTh3hln.png',
86+
'right-icon' => 'https://i.imgur.com/os7o9kz.png',
87+
'thumbnails' => 'visible',
88+
];
89+
90+
public function render(): string
91+
{
92+
$divAttributes = $this->getHtmlAttributes([
93+
'style' => 'div',
94+
]);
95+
96+
$children = $this->getChildren() ?? [];
97+
$content = $this->renderChildren($children, []);
98+
99+
return "<div $divAttributes>$content</div>";
100+
}
101+
102+
/**
103+
* @return array<string, array<string, string>>
104+
*/
105+
public function getStyles(): array
106+
{
107+
return [
108+
'div' => [
109+
'text-align' => $this->getAttribute('align'),
110+
'border-radius' => $this->getAttribute('border-radius'),
111+
],
112+
];
113+
}
114+
}
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
<?php
2+
3+
/**
4+
* PHP MJML Renderer library
5+
*
6+
* @package MadeByDenis\PhpMjmlRenderer
7+
* @link https://github.com/dingo-d/php-mjml-renderer
8+
* @license https://opensource.org/licenses/MIT MIT
9+
*/
10+
11+
declare(strict_types=1);
12+
13+
namespace MadeByDenis\PhpMjmlRenderer\Elements\BodyComponents;
14+
15+
use MadeByDenis\PhpMjmlRenderer\Elements\AbstractElement;
16+
17+
/**
18+
* Mjml Carousel Image Element
19+
*
20+
* Individual image item in a carousel.
21+
*
22+
* @link https://documentation.mjml.io/#mj-carousel-image
23+
*
24+
* @since 1.0.0
25+
*/
26+
class MjCarouselImage extends AbstractElement
27+
{
28+
public const string TAG_NAME = 'mj-carousel-image';
29+
30+
public const bool ENDING_TAG = false;
31+
32+
/**
33+
* List of allowed attributes on the element
34+
*
35+
* @var array<string, array<string, string>>
36+
*/
37+
protected array $allowedAttributes = [
38+
'alt' => [
39+
'unit' => 'string',
40+
'type' => 'string',
41+
'description' => 'image description',
42+
'default_value' => '',
43+
],
44+
'href' => [
45+
'unit' => 'string',
46+
'type' => 'string',
47+
'description' => 'link to redirect to on click',
48+
'default_value' => '',
49+
],
50+
'rel' => [
51+
'unit' => 'string',
52+
'type' => 'string',
53+
'description' => 'specify the rel attribute',
54+
'default_value' => '',
55+
],
56+
'src' => [
57+
'unit' => 'string',
58+
'type' => 'string',
59+
'description' => 'image source',
60+
'default_value' => '',
61+
],
62+
'target' => [
63+
'unit' => 'string',
64+
'type' => 'string',
65+
'description' => 'link target on click',
66+
'default_value' => '_blank',
67+
],
68+
'thumbnails-src' => [
69+
'unit' => 'string',
70+
'type' => 'string',
71+
'description' => 'thumbnail source',
72+
'default_value' => '',
73+
],
74+
'title' => [
75+
'unit' => 'string',
76+
'type' => 'string',
77+
'description' => 'image title',
78+
'default_value' => '',
79+
],
80+
];
81+
82+
protected array $defaultAttributes = [
83+
'target' => '_blank',
84+
];
85+
86+
public function render(): string
87+
{
88+
$src = $this->getAttribute('src');
89+
$alt = $this->getAttribute('alt');
90+
$href = $this->getAttribute('href');
91+
$target = $this->getAttribute('target');
92+
93+
$imgTag = "<img src='$src' alt='$alt' style='max-width: 100%;' />";
94+
95+
if ($href) {
96+
return "<a href='$href' target='$target'>$imgTag</a>";
97+
}
98+
99+
return $imgTag;
100+
}
101+
102+
/**
103+
* @return array<string, array<string, string>>
104+
*/
105+
public function getStyles(): array
106+
{
107+
return [];
108+
}
109+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
namespace MadeByDenis\PhpMjmlRenderer\Tests\Unit\Elements\BodyComponents;
4+
5+
use MadeByDenis\PhpMjmlRenderer\Elements\BodyComponents\MjCarousel;
6+
use MadeByDenis\PhpMjmlRenderer\Elements\BodyComponents\MjCarouselImage;
7+
8+
describe('MjCarousel', function () {
9+
it('returns the correct component name', function () {
10+
$element = new MjCarousel();
11+
expect($element->getTagName())->toBe('mj-carousel');
12+
});
13+
14+
it('has correct default attributes', function () {
15+
$element = new MjCarousel();
16+
expect($element->getAttribute('align'))->toBe('center');
17+
expect($element->getAttribute('thumbnails'))->toBe('visible');
18+
});
19+
20+
it('renders correctly', function () {
21+
$element = new MjCarousel();
22+
$out = $element->render();
23+
expect($out)->toContain('<div');
24+
});
25+
});
26+
27+
describe('MjCarouselImage', function () {
28+
it('returns the correct component name', function () {
29+
$element = new MjCarouselImage();
30+
expect($element->getTagName())->toBe('mj-carousel-image');
31+
});
32+
33+
it('renders image correctly', function () {
34+
$element = new MjCarouselImage(['src' => 'test.jpg', 'alt' => 'Test']);
35+
$out = $element->render();
36+
expect($out)->toContain('<img');
37+
expect($out)->toContain('test.jpg');
38+
expect($out)->toContain('Test');
39+
});
40+
41+
it('renders with link when href is provided', function () {
42+
$element = new MjCarouselImage([
43+
'src' => 'test.jpg',
44+
'href' => 'https://example.com',
45+
]);
46+
$out = $element->render();
47+
expect($out)->toContain('<a href=');
48+
expect($out)->toContain('https://example.com');
49+
});
50+
});

0 commit comments

Comments
 (0)