Skip to content

Commit 423ef1f

Browse files
Rework
1 parent 39036e9 commit 423ef1f

File tree

5 files changed

+65
-42
lines changed

5 files changed

+65
-42
lines changed

doc/fields/ChoiceField.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,9 @@ The built-in badge styles are the same as Bootstrap: ``'success'``,
9494

9595
yield ChoiceField::new('...')->renderAsBadges([
9696
// $value => $badgeStyleName
97-
'paid' => '#00FF00',
98-
'pending' => '#FFFF00',
99-
'refunded' => '#FF0000',
97+
'paid' => new BadgeStyle('#00FF00'),
98+
'pending' => new BadgeStyle('#FFFF00'),
99+
'refunded' => new BadgeStyle('#FF0000'),
100100
]);
101101

102102
renderAsNativeWidget

src/Field/ChoiceField.php

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace EasyCorp\Bundle\EasyAdminBundle\Field;
44

55
use EasyCorp\Bundle\EasyAdminBundle\Contracts\Field\FieldInterface;
6+
use EasyCorp\Bundle\EasyAdminBundle\Field\Style\BadgeStyle;
67
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
78
use Symfony\Contracts\Translation\TranslatableInterface;
89

@@ -126,8 +127,8 @@ public function renderAsBadges($badgeSelector = true): self
126127

127128
if (\is_array($badgeSelector)) {
128129
foreach ($badgeSelector as $badgeType) {
129-
if (!self::isSupportedBadge($badgeType)) {
130-
throw new \InvalidArgumentException(sprintf('The values of the array passed to the "%s" method must be a full 6-digit hexadecimal color or one of the following valid badge types: "%s" ("%s" given).', __METHOD__, implode(', ', self::VALID_BADGE_TYPES), $badgeType));
130+
if (!$badgeType instanceof BadgeStyle && !\in_array($badgeType, self::VALID_BADGE_TYPES, true)) {
131+
throw new \InvalidArgumentException(sprintf('The values of the array passed to the "%s" method must be an instance of "%s" or one of the following valid badge types: "%s" ("%s" given).', __METHOD__, BadgeStyle::class, implode(', ', self::VALID_BADGE_TYPES), $badgeType));
131132
}
132133
}
133134
}
@@ -137,16 +138,6 @@ public function renderAsBadges($badgeSelector = true): self
137138
return $this;
138139
}
139140

140-
public static function isSupportedBadge(string $badgeType): bool
141-
{
142-
return \in_array($badgeType, self::VALID_BADGE_TYPES, true) || self::isSupportedBadgeColor($badgeType);
143-
}
144-
145-
public static function isSupportedBadgeColor(string $badgeColor): bool
146-
{
147-
return 1 === preg_match('/^#[0-9a-f]{6}$/iD', $badgeColor);
148-
}
149-
150141
public function renderAsNativeWidget(bool $asNative = true): self
151142
{
152143
$this->setCustomOption(self::OPTION_WIDGET, $asNative ? self::WIDGET_NATIVE : self::WIDGET_AUTOCOMPLETE);

src/Field/Configurator/ChoiceConfigurator.php

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto;
99
use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto;
1010
use EasyCorp\Bundle\EasyAdminBundle\Field\ChoiceField;
11+
use EasyCorp\Bundle\EasyAdminBundle\Field\Style\BadgeStyle;
1112
use EasyCorp\Bundle\EasyAdminBundle\Translation\TranslatableChoiceMessage;
1213
use EasyCorp\Bundle\EasyAdminBundle\Translation\TranslatableChoiceMessageCollection;
1314
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
@@ -182,6 +183,7 @@ private function getChoices(array|callable|null $choiceGenerator, EntityDto $ent
182183
private function getBadgeCssClassAndStyle(array|bool|callable|null $badgeSelector, mixed $value, FieldDto $field): array
183184
{
184185
$cssClass = 'badge';
186+
$style = null;
185187

186188
$badgeType = '';
187189
if (true === $badgeSelector) {
@@ -190,35 +192,18 @@ private function getBadgeCssClassAndStyle(array|bool|callable|null $badgeSelecto
190192
$badgeType = $badgeSelector[$value] ?? 'badge-secondary';
191193
} elseif (\is_callable($badgeSelector)) {
192194
$badgeType = $badgeSelector($value, $field);
193-
if (!ChoiceField::isSupportedBadge($badgeType)) {
194-
throw new \RuntimeException(sprintf('The value returned by the callable passed to the "renderAsBadges()" method must be a full 6-digit hexadecimal color or one of the following valid badge types: "%s" ("%s" given).', implode(', ', ChoiceField::VALID_BADGE_TYPES), $badgeType));
195+
if (!$badgeType instanceof BadgeStyle && !\in_array($badgeType, ChoiceField::VALID_BADGE_TYPES, true)) {
196+
throw new \RuntimeException(sprintf('The value returned by the callable passed to the "renderAsBadges()" method must be an instance of "%s" or one of the following valid badge types: "%s" ("%s" given).', BadgeStyle::class, implode(', ', ChoiceField::VALID_BADGE_TYPES), $badgeType));
195197
}
196198
}
197199

198-
if ('' !== $badgeType && !ChoiceField::isSupportedBadgeColor($badgeType)) {
200+
if ($badgeType instanceof BadgeStyle) {
201+
$style = $badgeType->toStyle();
202+
} elseif ('' !== $badgeType) {
199203
$cssClass .= ' '.u($badgeType)->ensureStart('badge-')->toString();
200204
}
201205

202-
return [$cssClass, $this->getBadgeStyle($badgeType)];
203-
}
204-
205-
private function getBadgeStyle(string $bgColor): ?string
206-
{
207-
if (!ChoiceField::isSupportedBadgeColor($bgColor)) {
208-
return null;
209-
}
210-
211-
[$r, $g, $b] = [
212-
hexdec(substr($bgColor, 1, 2)),
213-
hexdec(substr($bgColor, 3, 2)),
214-
hexdec(substr($bgColor, 5, 2)),
215-
];
216-
217-
$luminance = (0.299 * $r + 0.587 * $g + 0.114 * $b) / 255;
218-
219-
$color = $luminance > 0.5 ? '#000000' : '#FFFFFF';
220-
221-
return sprintf('background-color:%s; color:%s;', $bgColor, $color);
206+
return [$cssClass, $style];
222207
}
223208

224209
/**

src/Field/Style/BadgeStyle.php

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
3+
namespace EasyCorp\Bundle\EasyAdminBundle\Field\Style;
4+
5+
final class BadgeStyle
6+
{
7+
private ?string $textColor = null;
8+
9+
public function __construct(
10+
private string $backgroundColor,
11+
?string $textColor = null
12+
) {
13+
if (!$this->isSupportedColor($this->backgroundColor)) {
14+
throw new \InvalidArgumentException(sprintf('The background color must be a full 6-digit hexadecimal color ("%s" given).', $this->backgroundColor));
15+
}
16+
17+
if (null === $textColor) {
18+
$this->textColor = $this->computeTextColor($this->backgroundColor);
19+
} elseif (!$this->isSupportedColor($this->textColor)) {
20+
throw new \InvalidArgumentException(sprintf('The text color must be a full 6-digit hexadecimal color ("%s" given).', $this->textColor));
21+
}
22+
}
23+
24+
public function toStyle(): string
25+
{
26+
return sprintf('background-color:%s; color:%s;', $this->backgroundColor, $this->textColor);
27+
}
28+
29+
private function isSupportedColor(string $color): bool
30+
{
31+
return 1 === preg_match('/^#[0-9a-f]{6}$/iD', $color);
32+
}
33+
34+
private function computeTextColor(string $bgColor): string
35+
{
36+
[$r, $g, $b] = [
37+
hexdec(substr($bgColor, 1, 2)),
38+
hexdec(substr($bgColor, 3, 2)),
39+
hexdec(substr($bgColor, 5, 2)),
40+
];
41+
42+
$luminance = (0.299 * $r + 0.587 * $g + 0.114 * $b) / 255;
43+
44+
return $luminance > 0.5 ? '#000000' : '#FFFFFF';
45+
}
46+
}

tests/Field/ChoiceFieldTest.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use EasyCorp\Bundle\EasyAdminBundle\Field\ChoiceField;
66
use EasyCorp\Bundle\EasyAdminBundle\Field\Configurator\ChoiceConfigurator;
7+
use EasyCorp\Bundle\EasyAdminBundle\Field\Style\BadgeStyle;
78
use EasyCorp\Bundle\EasyAdminBundle\Tests\Field\Fixtures\ChoiceField\PriorityUnitEnum;
89
use EasyCorp\Bundle\EasyAdminBundle\Tests\Field\Fixtures\ChoiceField\StatusBackedEnum;
910
use function Symfony\Component\Translation\t;
@@ -172,16 +173,16 @@ public function testBadges()
172173
$field->setValue([1, 3])->renderAsBadges(function ($value) { return $value > 1 ? 'success' : 'primary'; });
173174
self::assertSame('<span class="badge badge-primary">a</span><span class="badge badge-success">c</span>', (string) $this->configure($field)->getFormattedValue());
174175

175-
$field->setValue(1)->renderAsBadges([1 => '#123456', '3' => '#AAAAAA']);
176+
$field->setValue(1)->renderAsBadges([1 => new BadgeStyle('#123456'), '3' => new BadgeStyle('#AAAAAA')]);
176177
self::assertSame('<span class="badge" style="background-color:#123456; color:#FFFFFF;">a</span>', (string) $this->configure($field)->getFormattedValue());
177178

178-
$field->setValue([1, 3])->renderAsBadges([1 => '#123456', '3' => '#AAAAAA']);
179+
$field->setValue([1, 3])->renderAsBadges([1 => new BadgeStyle('#123456'), '3' => new BadgeStyle('#AAAAAA')]);
179180
self::assertSame('<span class="badge" style="background-color:#123456; color:#FFFFFF;">a</span><span class="badge" style="background-color:#AAAAAA; color:#000000;">c</span>', (string) $this->configure($field)->getFormattedValue());
180181

181-
$field->setValue(1)->renderAsBadges(function ($value) { return $value > 1 ? '#AAAAAA' : '#123456'; });
182+
$field->setValue(1)->renderAsBadges(function ($value) { return $value > 1 ? new BadgeStyle('#AAAAAA') : new BadgeStyle('#123456'); });
182183
self::assertSame('<span class="badge" style="background-color:#123456; color:#FFFFFF;">a</span>', (string) $this->configure($field)->getFormattedValue());
183184

184-
$field->setValue([1, 3])->renderAsBadges(function ($value) { return $value > 1 ? '#AAAAAA' : '#123456'; });
185+
$field->setValue([1, 3])->renderAsBadges(function ($value) { return $value > 1 ? new BadgeStyle('#AAAAAA') : new BadgeStyle('#123456'); });
185186
self::assertSame('<span class="badge" style="background-color:#123456; color:#FFFFFF;">a</span><span class="badge" style="background-color:#AAAAAA; color:#000000;">c</span>', (string) $this->configure($field)->getFormattedValue());
186187
}
187188
}

0 commit comments

Comments
 (0)