Skip to content

Commit

Permalink
Add rich text block, elements and parts (#66)
Browse files Browse the repository at this point in the history
* feat: add rich text block, elements and parts

* chore: add `@see` docblock urls to Slack block kit documentation

* feat(date): validate format template strings
  • Loading branch information
maartenpaauw authored Dec 28, 2024
1 parent 2da28fd commit 902dc66
Show file tree
Hide file tree
Showing 71 changed files with 3,038 additions and 25 deletions.
38 changes: 38 additions & 0 deletions src/Blocks/RichText.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

declare(strict_types=1);

namespace SlackPhp\BlockKit\Blocks;

use SlackPhp\BlockKit\Collections\RichTextSubCollection;
use SlackPhp\BlockKit\Elements\RichTexts\RichTextSubElement;
use SlackPhp\BlockKit\Property;
use SlackPhp\BlockKit\Validation\RequiresAllOf;
use SlackPhp\BlockKit\Validation\ValidCollection;

/**
* @see https://api.slack.com/reference/block-kit/blocks#rich_text
*/
#[RequiresAllOf('elements')]
class RichText extends Block
{
#[Property, ValidCollection]
public RichTextSubCollection $elements;

/**
* @param RichTextSubCollection|array<RichTextSubCollection|RichTextSubElement|null> $elements
*/
public function __construct(RichTextSubCollection|array $elements = [], ?string $blockId = null)
{
parent::__construct($blockId);
$this->elements = new RichTextSubCollection();
$this->elements(...$elements);
}

public function elements(RichTextSubCollection|RichTextSubElement|null ...$elements): self
{
$this->elements->append(...$elements);

return $this;
}
}
51 changes: 51 additions & 0 deletions src/Collections/RichTextCollection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

declare(strict_types=1);

namespace SlackPhp\BlockKit\Collections;

use SlackPhp\BlockKit\Component;
use SlackPhp\BlockKit\Elements\RichTexts\RichTextElement;
use SlackPhp\BlockKit\Elements\RichTexts\Text;

/**
* @extends ComponentCollection<RichTextElement>
*/
class RichTextCollection extends ComponentCollection
{
protected static function createComponent(array $data): Component
{
return RichTextElement::fromArray($data);
}

/**
* @param array<RichTextElement|self|string|null> $elements
*/
public function __construct(array $elements = [])
{
$this->append(...$elements);
}

public function append(RichTextElement|self|string|null ...$elements): void
{
$this->add($elements);
}

public function prepend(RichTextElement|self|string|null ...$elements): void
{
$this->add($elements, true);
}

protected function prepareItems(array $items): iterable
{
foreach ($items as $element) {
if ($element instanceof RichTextElement) {
yield $element;
} elseif ($element instanceof self) {
yield from $element;
} elseif (is_string($element)) {
yield Text::wrap($element);
}
}
}
}
51 changes: 51 additions & 0 deletions src/Collections/RichTextSectionCollection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

declare(strict_types=1);

namespace SlackPhp\BlockKit\Collections;

use SlackPhp\BlockKit\Component;
use SlackPhp\BlockKit\Elements\RichTexts\RichTextSection;

/**
* @extends ComponentCollection<RichTextSection>
*/
class RichTextSectionCollection extends ComponentCollection
{
protected static function createComponent(array $data): Component
{
return RichTextSection::fromArray($data);
}

/**
* @param array<RichTextSection|self|string|null> $sections
*/
public function __construct(array $sections = [])
{
$this->append(...$sections);
}

public function append(RichTextSection|self|string|null ...$elements): void
{
$this->add($elements);
}

public function prepend(RichTextSection|self|string|null ...$elements): void
{
$this->add($elements, true);
}


protected function prepareItems(array $items): iterable
{
foreach ($items as $section) {
if ($section instanceof RichTextSection) {
yield $section;
} elseif ($section instanceof self) {
yield from $section;
} elseif (is_string($section)) {
yield RichTextSection::wrap($section);
}
}
}
}
48 changes: 48 additions & 0 deletions src/Collections/RichTextSubCollection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

declare(strict_types=1);

namespace SlackPhp\BlockKit\Collections;

use SlackPhp\BlockKit\Component;
use SlackPhp\BlockKit\Elements\RichTexts\RichTextSubElement;

/**
* @extends ComponentCollection<RichTextSubElement>
*/
class RichTextSubCollection extends ComponentCollection
{
protected static function createComponent(array $data): Component
{
return RichTextSubElement::fromArray($data);
}

/**
* @param array<RichTextSubElement|self|null> $elements
*/
public function __construct(array $elements = [])
{
$this->append(...$elements);
}

public function append(RichTextSubElement|self|null ...$elements): void
{
$this->add($elements);
}

public function prepend(RichTextSubElement|self|null ...$elements): void
{
$this->add($elements, true);
}

protected function prepareItems(array $items): iterable
{
foreach ($items as $element) {
if ($element instanceof RichTextSubElement) {
yield $element;
} elseif ($element instanceof self) {
yield from $element;
}
}
}
}
50 changes: 50 additions & 0 deletions src/Collections/TextCollection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

declare(strict_types=1);

namespace SlackPhp\BlockKit\Collections;

use SlackPhp\BlockKit\Component;
use SlackPhp\BlockKit\Elements\RichTexts\Text;

/**
* @extends ComponentCollection<Text>
*/
class TextCollection extends ComponentCollection
{
protected static function createComponent(array $data): Component
{
return Text::fromArray($data);
}

/**
* @param array<Text|self|string|null> $elements
*/
public function __construct(array $elements = [])
{
$this->append(...$elements);
}

public function append(Text|self|string|null ...$elements): void
{
$this->add($elements);
}

public function prepend(Text|self|string|null ...$elements): void
{
$this->add($elements, true);
}

protected function prepareItems(array $items): iterable
{
foreach ($items as $text) {
if ($text instanceof Text) {
yield $text;
} elseif ($text instanceof self) {
yield from $text;
} elseif (is_string($text)) {
yield Text::wrap($text);
}
}
}
}
31 changes: 31 additions & 0 deletions src/Elements/RichTexts/Broadcast.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

declare(strict_types=1);

namespace SlackPhp\BlockKit\Elements\RichTexts;

use SlackPhp\BlockKit\Property;
use SlackPhp\BlockKit\Validation\RequiresAllOf;

/**
* @see https://api.slack.com/reference/block-kit/blocks#broadcast-element-type
*/
#[RequiresAllOf('range')]
class Broadcast extends RichTextElement
{
#[Property]
public ?Range $range;

public function __construct(Range|string|null $range = null)
{
parent::__construct();
$this->range($range);
}

public function range(Range|string|null $range): self
{
$this->range = Range::fromValue($range);

return $this;
}
}
38 changes: 38 additions & 0 deletions src/Elements/RichTexts/Channel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

declare(strict_types=1);

namespace SlackPhp\BlockKit\Elements\RichTexts;

use SlackPhp\BlockKit\Elements\RichTexts\Traits\HasMentionStyle;
use SlackPhp\BlockKit\Parts\MentionStyle;
use SlackPhp\BlockKit\Property;
use SlackPhp\BlockKit\Validation\RequiresAllOf;
use SlackPhp\BlockKit\Validation\ValidString;

/**
* @see https://api.slack.com/reference/block-kit/blocks#channel-element-type
*/
#[RequiresAllOf('channel_id')]
class Channel extends RichTextElement
{
use HasMentionStyle;

#[Property('channel_id'), ValidString]
public ?string $channelId;

public function __construct(?string $channelId = null, ?MentionStyle $style = null)
{
parent::__construct();

$this->channelId($channelId);
$this->style($style);
}

public function channelId(?string $channelId): self
{
$this->channelId = $channelId;

return $this;
}
}
32 changes: 32 additions & 0 deletions src/Elements/RichTexts/Color.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

declare(strict_types=1);

namespace SlackPhp\BlockKit\Elements\RichTexts;

use SlackPhp\BlockKit\Property;
use SlackPhp\BlockKit\Validation\RequiresAllOf;
use SlackPhp\BlockKit\Validation\ValidString;

/**
* @see https://api.slack.com/reference/block-kit/blocks#color-element-type
*/
#[RequiresAllOf('value')]
class Color extends RichTextElement
{
#[Property, ValidString]
public ?string $value;

public function __construct(?string $value = null)
{
parent::__construct();
$this->value($value);
}

public function value(?string $value): self
{
$this->value = $value;

return $this;
}
}
Loading

0 comments on commit 902dc66

Please sign in to comment.