Skip to content

Commit b91be18

Browse files
committed
Rename ActionCollection, Add UniqueIds validator, add Button's accessibility_label field
1 parent 4718210 commit b91be18

9 files changed

Lines changed: 80 additions & 60 deletions

File tree

src/Blocks/Actions.php

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

55
namespace SlackPhp\BlockKit\Blocks;
66

7-
use SlackPhp\BlockKit\Collections\ActionsCollection;
7+
use SlackPhp\BlockKit\Collections\ActionCollection;
88
use SlackPhp\BlockKit\Elements\{
99
Button,
1010
Checkboxes,
@@ -15,26 +15,26 @@
1515
};
1616
use SlackPhp\BlockKit\Elements\Selects\SelectMenu;
1717
use SlackPhp\BlockKit\Property;
18-
use SlackPhp\BlockKit\Validation\{RequiresAllOf, ValidCollection};
18+
use SlackPhp\BlockKit\Validation\{RequiresAllOf, UniqueIds, ValidCollection};
1919

2020
#[RequiresAllOf('elements')]
2121
class Actions extends Block
2222
{
23-
#[Property, ValidCollection(5, uniqueIds: true)]
24-
public ActionsCollection $elements;
23+
#[Property, ValidCollection(5), UniqueIds]
24+
public ActionCollection $elements;
2525

2626
/**
27-
* @param ActionsCollection|array<Button|Checkboxes|DatePicker|OverflowMenu|RadioButtons|SelectMenu|TimePicker|null> $elements
27+
* @param ActionCollection|array<Button|Checkboxes|DatePicker|OverflowMenu|RadioButtons|SelectMenu|TimePicker|null> $elements
2828
*/
29-
public function __construct(ActionsCollection|array $elements = [], ?string $blockId = null)
29+
public function __construct(ActionCollection|array $elements = [], ?string $blockId = null)
3030
{
3131
parent::__construct($blockId);
32-
$this->elements = new ActionsCollection();
32+
$this->elements = new ActionCollection();
3333
$this->elements(...$elements);
3434
}
3535

3636
public function elements(
37-
ActionsCollection|Button|Checkboxes|DatePicker|OverflowMenu|RadioButtons|SelectMenu|TimePicker|null ...$elements
37+
ActionCollection|Button|Checkboxes|DatePicker|OverflowMenu|RadioButtons|SelectMenu|TimePicker|null ...$elements
3838
): self {
3939
$this->elements->append(...$elements);
4040

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
/**
2020
* @extends ComponentCollection<Button|Checkboxes|DatePicker|OverflowMenu|RadioButtons|SelectMenu|TimePicker>
2121
*/
22-
class ActionsCollection extends ComponentCollection
22+
class ActionCollection extends ComponentCollection
2323
{
2424
protected static function createComponent(array $data): Button|Checkboxes|DatePicker|OverflowMenu|RadioButtons|SelectMenu|TimePicker
2525
{

src/Elements/Button.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,17 @@ class Button extends Element
2727
#[Property]
2828
public ?ButtonStyle $style;
2929

30+
#[Property('accessibility_label'), ValidString(75)]
31+
public ?string $accessibilityLabel;
32+
3033
public function __construct(
3134
?string $actionId = null,
3235
PlainText|string|null $text = null,
3336
?string $value = null,
3437
ButtonStyle|string|null $style = null,
3538
?string $url = null,
3639
?Confirm $confirm = null,
40+
?string $accessibilityLabel = null,
3741
) {
3842
parent::__construct();
3943
$this->actionId($actionId);
@@ -42,6 +46,7 @@ public function __construct(
4246
$this->style($style);
4347
$this->url($url);
4448
$this->confirm($confirm);
49+
$this->accessibilityLabel($accessibilityLabel);
4550
}
4651

4752
public function text(PlainText|string|null $text): self
@@ -71,4 +76,11 @@ public function style(ButtonStyle|string|null $style): self
7176

7277
return $this;
7378
}
79+
80+
public function accessibilityLabel(?string $accessibilityLabel): self
81+
{
82+
$this->accessibilityLabel = $accessibilityLabel;
83+
84+
return $this;
85+
}
7486
}

src/Kit.php

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,9 @@ public static function workflowStep(
9595

9696
#region Blocks
9797
/**
98-
* @param Collections\ActionsCollection|array<Elements\Button|Elements\Checkboxes|Elements\DatePicker|Elements\OverflowMenu|Elements\RadioButtons|Elements\Selects\SelectMenu|Elements\TimePicker|null> $elements
98+
* @param Collections\ActionCollection|array<Elements\Button|Elements\Checkboxes|Elements\DatePicker|Elements\OverflowMenu|Elements\RadioButtons|Elements\Selects\SelectMenu|Elements\TimePicker|null> $elements
9999
*/
100-
public static function actions(Collections\ActionsCollection|array $elements = [], ?string $blockId = null): Blocks\Actions
100+
public static function actions(Collections\ActionCollection|array $elements = [], ?string $blockId = null): Blocks\Actions
101101
{
102102
return new Blocks\Actions($elements, $blockId);
103103
}
@@ -166,8 +166,9 @@ public static function button(
166166
Elements\ButtonStyle|string|null $style = null,
167167
?string $url = null,
168168
?Parts\Confirm $confirm = null,
169+
?string $accessibilityLabel = null,
169170
): Elements\Button {
170-
return new Elements\Button($actionId, $text, $value, $style, $url, $confirm);
171+
return new Elements\Button($actionId, $text, $value, $style, $url, $confirm, $accessibilityLabel);
171172
}
172173

173174
public static function channelSelectMenu(
@@ -471,9 +472,9 @@ public static function plainText(?string $text = null, ?bool $emoji = null): Par
471472
/**
472473
* @param array<Elements\Button|Elements\Checkboxes|Elements\DatePicker|Elements\OverflowMenu|Elements\RadioButtons|Elements\Selects\SelectMenu|Elements\TimePicker|null> $actions
473474
*/
474-
public static function actionsCollection(array $actions = []): Collections\ActionsCollection
475+
public static function actionCollection(array $actions = []): Collections\ActionCollection
475476
{
476-
return new Collections\ActionsCollection($actions);
477+
return new Collections\ActionCollection($actions);
477478
}
478479

479480
/**

src/Surfaces/Attachment.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
use SlackPhp\BlockKit\Component;
1010
use SlackPhp\BlockKit\Property;
1111
use SlackPhp\BlockKit\Hydration\OmitType;
12-
use SlackPhp\BlockKit\Validation\{RequiresAllOf, ValidCollection};
12+
use SlackPhp\BlockKit\Validation\{RequiresAllOf, UniqueIds, ValidCollection};
1313

1414
/**
1515
* Attachments are a surface that represent secondary content within a message, and can only exist within a message.
@@ -25,7 +25,7 @@
2525
#[OmitType, RequiresAllOf('blocks')]
2626
class Attachment extends Surface
2727
{
28-
#[Property, ValidCollection(50, uniqueIds: true)]
28+
#[Property, ValidCollection(50), UniqueIds]
2929
public BlockCollection $blocks;
3030

3131
#[Property]

src/Surfaces/Message.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@
88
use SlackPhp\BlockKit\Collections\{AttachmentCollection, BlockCollection};
99
use SlackPhp\BlockKit\{FauxProperty, Property};
1010
use SlackPhp\BlockKit\Hydration\OmitType;
11-
use SlackPhp\BlockKit\Validation\{RequiresAnyOf, ValidCollection, ValidString};
11+
use SlackPhp\BlockKit\Validation\{RequiresAnyOf, UniqueIds, ValidCollection, ValidString};
1212

1313
/**
1414
* @see https://api.slack.com/surfaces
1515
*/
1616
#[OmitType, RequiresAnyOf('blocks', 'text', 'attachments')]
1717
class Message extends Surface
1818
{
19-
#[Property, ValidCollection(50, 0, uniqueIds: true)]
19+
#[Property, ValidCollection(50, 0), UniqueIds]
2020
public BlockCollection $blocks;
2121

2222
#[FauxProperty('response_type', 'replace_original', 'delete_original')]

src/Surfaces/Surface.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@
77
use SlackPhp\BlockKit\Blocks\Block;
88
use SlackPhp\BlockKit\Collections\BlockCollection;
99
use SlackPhp\BlockKit\{Component, Kit, Property};
10-
use SlackPhp\BlockKit\Validation\ValidCollection;
10+
use SlackPhp\BlockKit\Validation\{UniqueIds, ValidCollection};
1111

1212
/**
1313
* A Slack app surface is something within a Slack app that renders blocks from the block kit (e.g., a Message).
1414
*/
1515
abstract class Surface extends Component
1616
{
17-
#[Property, ValidCollection(100, uniqueIds: true)]
17+
#[Property, ValidCollection(100), UniqueIds]
1818
public BlockCollection $blocks;
1919

2020
/**

src/Validation/UniqueIds.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace SlackPhp\BlockKit\Validation;
6+
7+
use Attribute;
8+
use SlackPhp\BlockKit\Blocks\Block;
9+
use SlackPhp\BlockKit\Component;
10+
use SlackPhp\BlockKit\Elements\Element;
11+
12+
use function is_iterable;
13+
14+
#[Attribute(Attribute::TARGET_PROPERTY)]
15+
class UniqueIds implements PropertyRule
16+
{
17+
public function check(Component $component, string $field, mixed $value): void
18+
{
19+
if (!is_iterable($value)) {
20+
return;
21+
}
22+
23+
$uniqueIds = [];
24+
foreach ($value as $item) {
25+
if ($item instanceof Block) {
26+
$idField = 'block_id';
27+
$idValue = $item->blockId;
28+
} elseif ($item instanceof Element && isset($item->actionId)) {
29+
$idField = 'action_id';
30+
$idValue = $item->actionId;
31+
}
32+
33+
if (!isset($idField, $idValue)) {
34+
continue;
35+
}
36+
37+
if (in_array($idValue, $uniqueIds, true)) {
38+
throw new ValidationException(
39+
'The "%s" field of a valid "%s" component must NOT have any items with duplicate "%s"s',
40+
[$field, $component->type->value, $idField],
41+
);
42+
} else {
43+
$uniqueIds[] = $idValue;
44+
}
45+
}
46+
}
47+
}

src/Validation/ValidCollection.php

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ class ValidCollection implements PropertyRule
1616
public function __construct(
1717
private int $maxCount = 0,
1818
private int $minCount = 1,
19-
private bool $uniqueIds = false,
2019
) {}
2120

2221
public function check(Component $component, string $field, mixed $value): void
@@ -50,44 +49,5 @@ public function check(Component $component, string $field, mixed $value): void
5049
[$field, $component->type->value, $this->maxCount],
5150
);
5251
}
53-
54-
if (!$this->uniqueIds) {
55-
return;
56-
}
57-
58-
$uniqueIds = [];
59-
foreach ($collection as $item) {
60-
['field' => $idField, 'value' => $idValue] = $this->extractId($item);
61-
if (!empty($idValue)) {
62-
if (in_array($idValue, $uniqueIds, true)) {
63-
throw new ValidationException(
64-
'The "%s" field of a valid "%s" component must NOT have any items with duplicate "%s"s',
65-
[$field, $component->type->value, $idField],
66-
);
67-
} else {
68-
$uniqueIds[] = $idValue;
69-
}
70-
}
71-
}
72-
}
73-
74-
/**
75-
* @return array{field: ?string, value: ?string}
76-
*/
77-
private function extractId(mixed $item): array
78-
{
79-
if (!$item instanceof Component) {
80-
return ['field' => null, 'value' => null];
81-
}
82-
83-
if (isset($item->blockId)) {
84-
return ['field' => 'block_id' , 'value' => $item->blockId];
85-
}
86-
87-
if (isset($item->actionId)) {
88-
return ['field' => 'action_id', 'value' => $item->actionId];
89-
}
90-
91-
return ['field' => null, 'value' => null];
9252
}
9353
}

0 commit comments

Comments
 (0)