diff --git a/asset/css/callout.less b/asset/css/callout.less new file mode 100644 index 000000000..12daf8b9c --- /dev/null +++ b/asset/css/callout.less @@ -0,0 +1,71 @@ +// Layout +.callout { + display: flex; + justify-content: center; + column-gap: 1em; + + width: fit-content; + margin: 0 auto 1em; + + &.callout-full-width { + width: 100%; + justify-content: start; + } + + &.callout-form-element { + /* + * 14em is the width of the `control-label-group` element. This property value assumes that there are no + * special cases for which the label width differs. There is no way to get the width of the form label + * programmatically. + */ + margin-left: 14em; + width: auto; + justify-content: start; + } + + 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: color-mix(in srgb, var(--callout-color) 10%, transparent); + border-radius: .25em; + + i.icon { + color: var(--callout-color); + font-size: 1.5em; + } + + &.callout-type-info { + --callout-color: @color-pending; + } + + &.callout-type-success { + --callout-color: @color-ok; + } + + &.callout-type-warning { + --callout-color: @color-warning; + } + + &.callout-type-error { + --callout-color: @color-critical; + } +} diff --git a/src/Common/CalloutType.php b/src/Common/CalloutType.php new file mode 100644 index 000000000..ea86d5679 --- /dev/null +++ b/src/Common/CalloutType.php @@ -0,0 +1,31 @@ + 'circle-info', + self::Success => 'circle-check', + self::Warning => 'warning', + self::Error => 'circle-xmark', + }); + } +} diff --git a/src/Widget/Callout.php b/src/Widget/Callout.php new file mode 100644 index 000000000..1296c5487 --- /dev/null +++ b/src/Widget/Callout.php @@ -0,0 +1,104 @@ + '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 + ? HtmlElement::create('strong', ['class' => 'callout-title'], Text::create($this->title)) + : null, + is_string($this->content) ? Text::create($this->content) : $this->content, + ], + )); + } + + /** + * Set the callout width to 100% of its parent container + * + * Callouts are normally only as wide as their content. + * Setting it to full width will force the callout to be as wide as its container. + * + * @param bool $isFullWidth Whether the callout should be full width + * + * @return $this + */ + public function setFullWidth(bool $isFullWidth = true): static + { + if ($isFullWidth) { + $this->addAttributes(Attributes::create(['class' => static::CLASS_FULL_WIDTH])); + } else { + $this->removeAttribute('class', static::CLASS_FULL_WIDTH); + } + + return $this; + } + + /** + * Set up the callout to be used inside a form + * + * Setting this to true will allow the callout to be used for a single form element. + * This is used to visually align the callout to the content of the form element. + * + * @param bool $isFormElement Whether the callout should be used for a form element + * + * @return $this + */ + public function setFormElement(bool $isFormElement = true): static + { + if ($isFormElement) { + $this->addAttributes(Attributes::create(['class' => static::CLASS_FORM_ELEMENT])); + } else { + $this->removeAttribute('class', static::CLASS_FORM_ELEMENT); + } + + return $this; + } +} diff --git a/tests/Widget/CalloutTest.php b/tests/Widget/CalloutTest.php new file mode 100644 index 000000000..111890697 --- /dev/null +++ b/tests/Widget/CalloutTest.php @@ -0,0 +1,153 @@ + + +
This is a Test
+