-
Notifications
You must be signed in to change notification settings - Fork 2
Introduce Callout #358
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Introduce Callout #358
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| // Layout | ||
| .callout { | ||
| display: flex; | ||
| column-gap: 1em; | ||
| justify-content: start; | ||
|
|
||
| &.callout-fit-content { | ||
| width: fit-content; | ||
| } | ||
|
|
||
| i.icon::before { | ||
| margin-right: 0; | ||
| } | ||
|
|
||
| p { | ||
| margin: 0; | ||
| } | ||
|
|
||
| .callout-title { | ||
| margin-bottom: .5em; | ||
| } | ||
|
|
||
| .callout-text { | ||
| display: flex; | ||
| flex-direction: column; | ||
| } | ||
| } | ||
|
|
||
| // Style | ||
| .callout { | ||
| padding: .5em 1em; | ||
| border: 1px solid var(--callout-color); | ||
| background-color: var(--callout-bg-color); | ||
| border-radius: .25em; | ||
|
|
||
| i.icon { | ||
| color: var(--callout-color); | ||
| font-size: 1.5em; | ||
| } | ||
|
|
||
| &.callout-type-info { | ||
| --callout-color: @callout-info-color; | ||
| --callout-bg-color: @callout-info-bg; | ||
| } | ||
|
|
||
| &.callout-type-success { | ||
| --callout-color: @callout-success-color; | ||
| --callout-bg-color: @callout-success-bg; | ||
| } | ||
|
|
||
| &.callout-type-warning { | ||
| --callout-color: @callout-warning-color; | ||
| --callout-bg-color: @callout-warning-bg; | ||
| } | ||
|
|
||
| &.callout-type-error { | ||
| --callout-color: @callout-error-color; | ||
| --callout-bg-color: @callout-error-bg; | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| <?php | ||
|
|
||
| namespace ipl\Web\Common; | ||
|
|
||
| use ipl\Web\Widget\Icon; | ||
|
|
||
| /** | ||
| * An enum containing all possible callout types for the {@see \ipl\Web\Widget\Callout} widget | ||
| */ | ||
| enum CalloutType: string | ||
| { | ||
| case Info = 'callout-type-info'; | ||
| case Success = 'callout-type-success'; | ||
| case Warning = 'callout-type-warning'; | ||
| case Error = 'callout-type-error'; | ||
|
|
||
| /** | ||
| * Get the icon element for use in the callout | ||
| * | ||
| * @return Icon | ||
| */ | ||
| public function getIcon(): Icon | ||
| { | ||
| return new Icon(match ($this) { | ||
| self::Info => 'circle-info', | ||
| self::Success => 'circle-check', | ||
| self::Warning => 'warning', | ||
| self::Error => 'circle-xmark', | ||
| }); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| <?php | ||
|
|
||
| namespace ipl\Web\Widget; | ||
|
|
||
| use ipl\Html\Attributes; | ||
| use ipl\Html\BaseHtmlElement; | ||
| use ipl\Html\HtmlElement; | ||
| use ipl\Html\Text; | ||
| use ipl\Html\ValidHtml; | ||
| use ipl\Web\Common\CalloutType; | ||
|
|
||
| /** | ||
| * Information box with a type specific color and icon | ||
| * | ||
| * The type controls both the color scheme and the icon. An optional title | ||
| * is displayed above the content. | ||
| */ | ||
|
TheSyscall marked this conversation as resolved.
|
||
| class Callout extends BaseHtmlElement | ||
|
jrauh01 marked this conversation as resolved.
|
||
| { | ||
| /** @var string Class name for fit content callouts */ | ||
| protected const CLASS_FIT_CONTENT = 'callout-fit-content'; | ||
|
|
||
| protected $tag = 'div'; | ||
|
|
||
| protected $defaultAttributes = ['class' => 'callout']; | ||
|
|
||
| /** | ||
| * Create a new callout | ||
| * | ||
| * The $type parameter determines the color and icon of the callout. | ||
| * | ||
| * @param CalloutType $type The type of the callout | ||
| * @param ValidHtml|string $content The content of the callout | ||
| * @param ?string $title An optional title, displayed above the content | ||
| */ | ||
| public function __construct( | ||
| protected CalloutType $type, | ||
| protected ValidHtml|string $content, | ||
| protected ?string $title = null | ||
| ) { | ||
| $this->addAttributes(Attributes::create(['class' => $type->value])); | ||
| } | ||
|
|
||
| protected function assemble(): void | ||
| { | ||
| $this->addHtml($this->type->getIcon()); | ||
|
|
||
| $this->addHtml(HtmlElement::create( | ||
| 'div', | ||
| ['class' => 'callout-text'], | ||
| [ | ||
| $this->title === null || trim($this->title) === '' | ||
| ? null | ||
| : HtmlElement::create('strong', ['class' => 'callout-title'], Text::create($this->title)), | ||
| is_string($this->content) ? Text::create($this->content) : $this->content, | ||
| ], | ||
| )); | ||
| } | ||
|
|
||
| /** | ||
| * Set the callout width to 100% of its parent container | ||
| * | ||
| * Callouts are by default sized to fill their parent container. | ||
| * | ||
| * @param bool $isFitContent Whether the callout size should be dependent on its content | ||
| * | ||
| * @return $this | ||
| */ | ||
| public function setFitContent(bool $isFitContent = true): static | ||
| { | ||
| if ($isFitContent) { | ||
| $this->addAttributes(Attributes::create(['class' => static::CLASS_FIT_CONTENT])); | ||
| } else { | ||
| $this->removeAttribute('class', static::CLASS_FIT_CONTENT); | ||
| } | ||
|
|
||
| return $this; | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,124 @@ | ||
| <?php | ||
|
|
||
| namespace ipl\Tests\Web\Widget; | ||
|
|
||
| use ipl\Html\Html; | ||
| use ipl\Html\Test\TestCase; | ||
| use ipl\Web\Common\CalloutType; | ||
| use ipl\Web\Widget\Callout; | ||
|
|
||
| class CalloutTest extends TestCase | ||
| { | ||
| public function testCalloutWithoutTitle(): void | ||
| { | ||
| $callout = new Callout(CalloutType::Info, 'Content'); | ||
|
|
||
| $html = <<<'HTML' | ||
| <div class="callout callout-type-info"> | ||
| <i class="icon fa-circle-info fa"></i> | ||
| <div class="callout-text"> | ||
| Content | ||
| </div> | ||
| </div> | ||
| HTML; | ||
|
|
||
| $this->assertHtml($html, $callout); | ||
| } | ||
|
|
||
| public function testCalloutWithTitle(): void | ||
| { | ||
| $callout = new Callout(CalloutType::Info, 'Content', 'Title'); | ||
|
|
||
| $html = <<<'HTML' | ||
| <div class="callout callout-type-info"> | ||
| <i class="icon fa-circle-info fa"></i> | ||
| <div class="callout-text"> | ||
| <strong class="callout-title">Title</strong> | ||
| Content | ||
| </div> | ||
| </div> | ||
| HTML; | ||
|
|
||
| $this->assertHtml($html, $callout); | ||
| } | ||
|
|
||
| public function testCalloutFalsyTitle(): void | ||
| { | ||
| $callout = new Callout(CalloutType::Warning, 'Content', '0'); | ||
|
|
||
| $html = <<<'HTML' | ||
| <div class="callout callout-type-warning"> | ||
| <i class="icon fa-warning fa"></i> | ||
| <div class="callout-text"> | ||
| <strong class="callout-title">0</strong> | ||
| Content | ||
| </div> | ||
| </div> | ||
| HTML; | ||
| $this->assertHtml($html, $callout); | ||
| } | ||
|
|
||
| public function testCalloutEmptyTitle(): void | ||
| { | ||
| $callout = new Callout(CalloutType::Error, 'Content', ''); | ||
|
|
||
| $html = <<<'HTML' | ||
| <div class="callout callout-type-error"> | ||
| <i class="icon fa-circle-xmark fa"></i> | ||
| <div class="callout-text"> | ||
| Content | ||
| </div> | ||
| </div> | ||
| HTML; | ||
| $this->assertHtml($html, $callout); | ||
| } | ||
|
|
||
| public function testCalloutValidHtmlContent(): void | ||
| { | ||
| $callout = new Callout( | ||
| CalloutType::Success, | ||
| Html::tag('p', ['class' => 'test-class'], 'This is a Test'), | ||
| 'Test Title', | ||
| ); | ||
|
|
||
| $html = <<<'HTML' | ||
| <div class="callout callout-type-success"> | ||
| <i class="icon fa-circle-check fa"></i> | ||
| <div class="callout-text"> | ||
| <strong class="callout-title">Test Title</strong> | ||
| <p class="test-class">This is a Test</p> | ||
| </div> | ||
| </div> | ||
| HTML; | ||
|
|
||
| $this->assertHtml($html, $callout); | ||
| } | ||
|
|
||
| public function testCalloutFitContent(): void | ||
| { | ||
| $callout = (new Callout(CalloutType::Error, 'Content')) | ||
| ->setFitContent(true); | ||
|
|
||
| $html = <<<'HTML' | ||
| <div class="callout callout-type-error callout-fit-content"> | ||
| <i class="icon fa-circle-xmark fa"></i> | ||
| <div class="callout-text"> | ||
| Content | ||
| </div> | ||
| </div> | ||
| HTML; | ||
| $this->assertHtml($html, $callout); | ||
|
|
||
| $callout->setFitContent(false); | ||
|
|
||
| $html2 = <<<'HTML' | ||
| <div class="callout callout-type-error"> | ||
| <i class="icon fa-circle-xmark fa"></i> | ||
| <div class="callout-text"> | ||
| Content | ||
| </div> | ||
| </div> | ||
| HTML; | ||
| $this->assertHtml($html2, $callout); | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.