Commit e64548b9 authored by Yassine Doghri's avatar Yassine Doghri
Browse files

feat: replace form helper functions with components in admin template

parent 65367295
......@@ -81,9 +81,8 @@ class PostController extends FediversePostController
if (! ($cachedView = cache($cacheName))) {
$data = [
'podcast' => $this->podcast,
'actor' => $this->actor,
'post' => $this->post,
'podcast' => $this->podcast,
];
// if user is logged in then send to the authenticated activity view
......
......@@ -69,9 +69,6 @@ class EpisodeComment extends UuidEntity
'is_from_post' => 'boolean',
];
/**
* Returns the comment's attached episode
*/
public function getEpisode(): ?Episode
{
if ($this->episode_id === null) {
......
......@@ -3,23 +3,34 @@
declare(strict_types=1);
/**
* @copyright 2020 Podlibre
* @copyright 2021 Podlibre
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
* @link https://castopod.org/
*/
return [
'blocked_actors' => 'Blocked accounts',
'blocked_domains' => 'Blocked domains',
'block_lists_form' => [
'handle' => 'Account handle',
'handle_hint' => 'Input @username@domain account.',
'domain' => 'Domain name',
'submit' => 'Block!',
'your_handle' => 'Your handle',
'your_handle_hint' => 'Enter the @username@domain you want to act from.',
'follow' => [
'label' => 'Follow',
'title' => 'Follow {actorDisplayName}',
'subtitle' => 'You are going to follow:',
'accountNotFound' => 'The account could not be found.',
'submit' => 'Proceed to follow',
],
'list' => [
'actor' => 'Account',
'domain' => 'Domain name',
'unblock' => 'Unblock',
'favourite' => [
'title' => "Favourite {actorDisplayName}'s post",
'subtitle' => 'You are going to favourite:',
'submit' => 'Proceed to favourite',
],
'reblog' => [
'title' => "Share {actorDisplayName}'s post",
'subtitle' => 'You are going to share:',
'submit' => 'Proceed to share',
],
'reply' => [
'title' => "Reply to {actorDisplayName}'s post",
'subtitle' => 'You are going to reply to:',
'submit' => 'Proceed to reply',
],
];
......@@ -3,20 +3,35 @@
declare(strict_types=1);
/**
* @copyright 2020 Podlibre
* @copyright 2021 Podlibre
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
* @link https://castopod.org/
*/
return [
'block_lists' => 'Listes de blocage',
'block_lists_form' => [
'blocked_users' => 'Utilisateurs bloqués',
'blocked_users_hint' =>
'Entrez les pseudonymes @utilisateur@domaine séparés par une virgule.',
'blocked_domains' => 'Domaines bloqués',
'blocked_domains_hint' =>
'Entrez les noms de domaine séparés par une virgule.',
'submit' => 'Sauvegarder les listes',
'your_handle' => 'Votre pseudonyme',
'your_handle_hint' =>
'Entrez le @utilisateur@domaine avec lequel vous voulez interagir.',
'follow' => [
'label' => 'Suivre',
'title' => 'Suivre {actorDisplayName}',
'subtitle' => 'Vous allez suivre :',
'accountNotFound' => 'Le compte n’a pas pu être trouvé.',
'submit' => 'Poursuivre',
],
'favourite' => [
'title' => 'Mettez la publication de {actorDisplayName} en favori',
'subtitle' => 'Vous allez mettre en favori :',
'submit' => 'Poursuivre',
],
'reblog' => [
'title' => 'Partagez la publication de {actorDisplayName}',
'subtitle' => 'Vous allez partager :',
'submit' => 'Poursuivre',
],
'reply' => [
'title' => 'Répondre à la publication de {actorDisplayName}',
'subtitle' => 'Vous allez répondre à :',
'submit' => 'Poursuivre',
],
];
......@@ -24,11 +24,12 @@ class Component implements ComponentInterface
{
helper('viewcomponents');
// overwrite default attributes if set
$this->attributes = array_merge($this->attributes, $attributes);
if ($attributes !== []) {
$this->hydrate($attributes);
}
// overwrite default attributes if set
$this->attributes = array_merge($this->attributes, $attributes);
}
/**
......
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 59 40">
<path d="M52.801 38.23h-8.853s-.93-1.975-1.306-2.671c-.378-.697-1.278-.668-1.278-.668H17.33s-.871-.116-1.307.668c-.464.784-1.335 2.67-1.335 2.67H5.98c-2.003 0-3.658-1.625-3.658-3.628V5.893c0-2.003 1.626-3.658 3.629-3.658h46.821c2.003 0 3.658 1.626 3.658 3.629v28.708c.029 2.003-1.626 3.657-3.629 3.657Z" fill="#009486"/>
<path d="M17.01 10.014h24.703c4.267-.028 7.721 3.426 7.692 7.722 0 4.238-3.454 7.692-7.692 7.692H17.01c-4.238 0-7.692-3.454-7.692-7.692 0-4.238 3.454-7.722 7.692-7.722Z" fill="#E7F9E4"/>
<path d="M39.768 14.804a3.773 3.773 0 0 0-3.774 3.777c0 .861.298 1.656.795 2.319 0 0 1.29-.96 3.111-.96 1.357 0 2.946.827 2.946.827.43-.63.695-1.358.695-2.186a3.773 3.773 0 0 0-3.773-3.777Zm-20.9 0a3.773 3.773 0 0 0-3.774 3.777c0 .828.265 1.557.695 2.186 0 0 1.59-.828 2.946-.828 1.821 0 3.112.96 3.112.96a3.707 3.707 0 0 0 .794-2.318 3.773 3.773 0 0 0-3.773-3.777Z" fill="#009486"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" id="Calque_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 202.4 137.8" style="enable-background:new 0 0 202.4 137.8;" xml:space="preserve">
<style type="text/css">
.st0{fill:#009486;}
.st1{fill:#E7F9E4;}
.st2{fill:none;}
.st3{fill:#E7FFE3;}
</style>
<g>
<path id="dark_greeen_19_" class="st0" d="M181.9,131.7h-32.5c0,0-1.2-2.5-2.5-4.9c-1.3-2.4-4.4-2.3-4.4-2.3H59.7
c0,0-3-0.4-4.5,2.3c-1.6,2.7-2.6,4.9-2.6,4.9H20.6c-6.9,0-12.6-5.6-12.6-12.5V20.3c0-6.9,5.6-12.6,12.5-12.6h161.3
c6.9,0,12.6,5.6,12.6,12.5v98.9C194.5,126,188.8,131.7,181.9,131.7z"/>
<path class="st1" d="M143.7,34.5H58.6c-14.6,0-26.5,12-26.5,26.6c0,14.6,11.9,26.5,26.5,26.5h85.1c14.6,0,26.5-11.9,26.5-26.5
C170.3,46.3,158.4,34.4,143.7,34.5z M68.3,68.7c0,0-3.9-2.9-9.4-2.9c-4.1,0-8.9,2.5-8.9,2.5c-1.3-1.9-2.1-4.1-2.1-6.6
c0-6.3,5.1-11.4,11.4-11.4s11.4,5.1,11.4,11.4C70.7,64.4,69.8,66.8,68.3,68.7z M101.2,75.3c-12.5,0-12-9.6-12-9.6
c-0.2-1.8,2.1-2.4,2.9-1.3c0.4,0.6,0.4,0.6,0.7,1.7c1.7,5.9,8.4,5.6,8.4,5.6s6.7,0.4,8.4-5.6c0.3-1,0.3-1.1,0.7-1.7
c0.8-1,3.1-0.5,2.9,1.3C113.2,65.7,113.7,75.3,101.2,75.3z M152.3,68.4c0,0-4.8-2.5-8.9-2.5c-5.5,0-9.4,2.9-9.4,2.9
c-1.5-1.9-2.4-4.3-2.4-7c0-6.3,5.1-11.4,11.4-11.4s11.4,5.1,11.4,11.4C154.5,64.2,153.7,66.5,152.3,68.4z"/>
<path class="st2" d="M110.3,64.3c-0.4,0.6-0.4,0.6-0.7,1.7c-1.7,5.9-8.4,5.6-8.4,5.6s-6.7,0.4-8.4-5.6c-0.3-1-0.3-1.1-0.7-1.7
c-0.8-1-3.1-0.5-2.9,1.3c0,0-0.5,9.6,12,9.6c12.5,0,12-9.6,12-9.6C113.4,63.9,111.1,63.3,110.3,64.3z"/>
<path class="st2" d="M143.1,50.4c-6.3,0-11.4,5.1-11.4,11.4c0,2.6,0.9,5,2.4,7c0,0,3.9-2.9,9.4-2.9c4.1,0,8.9,2.5,8.9,2.5
c1.3-1.9,2.1-4.1,2.1-6.6C154.5,55.5,149.4,50.4,143.1,50.4z"/>
<path class="st2" d="M59.3,50.4c-6.3,0-11.4,5.1-11.4,11.4c0,2.5,0.8,4.7,2.1,6.6c0,0,4.8-2.5,8.9-2.5c5.5,0,9.4,2.9,9.4,2.9
c1.5-1.9,2.4-4.3,2.4-7C70.7,55.5,65.6,50.4,59.3,50.4z"/>
<g>
<g>
<path class="st3" d="M47.1,23.3c-6.3-1.7-11.7,2.1-14.7,7.3c-0.7,1.2-0.2,2.2,0.5,2.6c1,0.3,1.7,0.1,2.8-1.5
c2.2-3.9,5.9-6.1,10.1-5.3c0,0,2.9,0.9,3.3-1C49.4,24.2,48.3,23.6,47.1,23.3z"/>
</g>
</g>
<g>
<g>
<path class="st3" d="M159.9,27.3c-0.1,1.9,2.9,1.9,2.9,1.9c4.2,0.4,6.8,2.3,7.8,6.7c0.6,1.9,1.2,2.2,2.3,2.2
c0.8-0.1,1.6-1,1.2-2.4c-1.4-5.8-5.1-9.8-11.7-9.9C161.2,25.7,160,26,159.9,27.3z"/>
</g>
</g>
</g>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 59 40">
<path d="M53.024 38.23H43.55s-.35-.726-.728-1.423c-.38-.697-1.283-.668-1.283-.668H17.403s-.875-.116-1.312.668a16.505 16.505 0 0 0-.758 1.422H6.005c-2.011 0-3.673-1.625-3.673-3.628V5.893c0-2.003 1.632-3.658 3.644-3.658h47.02c2.01 0 3.672 1.626 3.672 3.629v28.708c.03 2.003-1.632 3.657-3.644 3.657Z" fill="#009486"/>
<path d="M41.889 10.014H17.082c-4.256 0-7.725 3.484-7.725 7.722s3.47 7.692 7.725 7.692h24.807c4.256 0 7.725-3.454 7.725-7.692a7.655 7.655 0 0 0-7.725-7.722Zm-21.98 9.928s-1.136-.842-2.74-.842c-1.195 0-2.594.726-2.594.726a3.333 3.333 0 0 1-.612-1.916 3.315 3.315 0 0 1 3.323-3.31 3.315 3.315 0 0 1 3.323 3.31c0 .784-.262 1.48-.7 2.032Zm9.591 1.916c-3.644 0-3.498-2.787-3.498-2.787-.058-.522.612-.697.845-.377.117.174.117.174.204.493.496 1.713 2.449 1.626 2.449 1.626s1.953.116 2.449-1.626c.087-.29.087-.32.204-.493.233-.29.903-.145.845.377 0 0 .146 2.787-3.498 2.787Zm14.896-2.003s-1.4-.726-2.595-.726c-1.603 0-2.74.842-2.74.842a3.238 3.238 0 0 1-.7-2.032 3.315 3.315 0 0 1 3.324-3.31 3.315 3.315 0 0 1 3.323 3.31 3.014 3.014 0 0 1-.612 1.916Z" fill="#E7F9E4"/>
<path d="M41.714 14.63a3.315 3.315 0 0 0-3.323 3.309c0 .755.262 1.451.7 2.032 0 0 1.136-.842 2.74-.842 1.195 0 2.594.726 2.594.726.379-.552.612-1.19.612-1.916a3.315 3.315 0 0 0-3.323-3.31ZM17.286 14.63a3.315 3.315 0 0 0-3.323 3.309c0 .726.233 1.364.612 1.916 0 0 1.4-.726 2.594-.726 1.604 0 2.74.842 2.74.842.438-.552.7-1.248.7-2.032a3.315 3.315 0 0 0-3.323-3.31Z" fill="#009486"/>
<path d="M13.73 6.763c-1.837-.493-3.41.61-4.285 2.12-.204.348-.059.638.145.754.292.087.496.03.817-.435.641-1.132 1.72-1.77 2.944-1.539 0 0 .845.262.962-.29.087-.348-.233-.522-.583-.61ZM46.611 7.925c-.03.551.845.551.845.551 1.225.116 1.983.668 2.274 1.945.175.551.35.639.67.639.234-.03.467-.29.35-.697-.408-1.684-1.486-2.845-3.41-2.874-.35-.029-.7.058-.729.436Z" fill="#E7F9E4"/>
</svg>
......@@ -5,13 +5,13 @@ const Clipboard = (): void => {
if (buttons) {
for (let i = 0; i < buttons.length; i++) {
const button: HTMLButtonElement = buttons[i];
const textArea: HTMLTextAreaElement | null = document.querySelector(
`textarea[id="${button.dataset.clipboardTarget}"]`
const element: HTMLFormElement | null = document.querySelector(
`[id="${button.dataset.clipboardTarget}"]`
);
if (textArea) {
if (element) {
button.addEventListener("click", () => {
textArea.select();
textArea.setSelectionRange(0, textArea.value.length);
element.select();
element.setSelectionRange(0, element.value.length);
document.execCommand("copy");
});
}
......
......@@ -4,11 +4,10 @@ const ThemePicker = (): void => {
const iframe: HTMLIFrameElement | null = document.querySelector(
`iframe[id="embeddable_player"]`
);
const iframeTextArea: HTMLTextAreaElement | null = document.querySelector(
`textarea[id="iframe"]`
);
const urlTextArea: HTMLTextAreaElement | null =
document.querySelector(`textarea[id="url"]`);
const iframeTextArea: HTMLFormElement | null =
document.querySelector(`[id="iframe"]`);
const urlTextArea: HTMLFormElement | null =
document.querySelector(`[id="url"]`);
if (buttons && iframe && iframeTextArea && urlTextArea) {
for (let i = 0; i < buttons.length; i++) {
......
.breadcrumb {
@apply inline-flex flex-wrap px-1 text-sm;
@apply inline-flex flex-wrap px-1;
}
.breadcrumb-item + .breadcrumb-item::before {
......
......@@ -15,25 +15,49 @@
}
&:checked + .form-switch-slider::after {
@apply transform translate-x-1;
content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='%23ffffff'%3E%3Cpath fill='none' d='M0 0h24v24H0z'/%3E%3Cpath d='m10 15.172 9.192-9.193 1.415 1.414L10 18l-6.364-6.364 1.414-1.414z'/%3E%3C/svg%3E%0A");
@apply transform translate-x-0 left-2;
content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23ffffff'%3E%3Cpath fill='none' d='M0 0h24v24H0z'/%3E%3Cpath d='m10 15.172 9.192-9.193 1.415 1.414L10 18l-6.364-6.364 1.414-1.414z'/%3E%3C/svg%3E%0A");
}
&:checked + .form-switch-slider.form-switch-slider--small::before {
@apply translate-x-6;
}
&:checked + .form-switch-slider.form-switch-slider--small::after {
@apply left-1;
}
}
.form-switch-slider {
@apply relative inset-0 flex-shrink-0 w-[72px] h-10 transition duration-200 bg-gray-400 border-black rounded-full cursor-pointer border-3;
@apply relative inset-0 flex-shrink-0 w-16 h-8 transition duration-200 bg-gray-400 border-black rounded-full cursor-pointer border-3;
&.form-switch-slider--small {
@apply w-12 h-6;
&::before {
@apply w-4 h-4;
}
&::after {
@apply translate-x-5;
left: 0;
top: -1px;
}
}
&::before {
@apply absolute z-10 w-[28px] h-[28px] transition duration-200 bg-white rounded-full ring-1 ring-black ring-opacity-5 shadow;
@apply absolute z-10 w-6 h-6 transition duration-200 bg-white rounded-full shadow ring-1 ring-black ring-opacity-5;
content: "";
left: 3px;
bottom: 3px;
left: 1px;
bottom: 1px;
}
&::after {
@apply absolute w-6 h-6 transition duration-150 transform translate-x-8 top-1 left-1;
@apply absolute w-5 h-5 transition duration-150 transform translate-x-5;
content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24'%3E%3Cpath fill='none' d='M0 0h24v24H0z'/%3E%3Cpath d='m12 10.586 4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636z'/%3E%3C/svg%3E%0A");
content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' %3E%3Cpath fill='none' d='M0 0h24v24H0z'/%3E%3Cpath d='m12 10.586 4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636z'/%3E%3C/svg%3E%0A");
top: 3px;
left: 10px;
}
}
}
<?php
declare(strict_types=1);
namespace App\Views\Components;
use ViewComponents\Component;
class Alert extends Component
{
protected ?string $glyph = null;
protected ?string $title = null;
/**
* @var 'default'|'success'|'danger'|'warning'
*/
protected string $variant = 'default';
public function render(): string
{
$variantClasses = [
'default' => 'text-gray-800 bg-gray-100 border-gray-300',
'success' => 'text-pine-900 bg-pine-100 border-pine-300',
'danger' => 'text-red-900 bg-red-100 border-red-300',
'warning' => 'text-yellow-900 bg-yellow-100 border-yellow-300',
];
$glyph = $this->glyph === null ? '' : '<Icon glyph="' . $this->glyph . '" class="flex-shrink-0 mr-2 text-lg" />';
$title = $this->title === null ? '' : '<div class="font-semibold">' . $this->title . '</div>';
$class = 'inline-flex w-full p-2 text-sm border rounded ' . $variantClasses[$this->variant] . ' ' . $this->class;
$attributes = stringify_attributes($this->attributes);
return <<<HTML
<div class="{$class}" role="alert" {$attributes}>{$glyph}<div>{$title}{$this->slot}</div></div>
HTML;
}
}
......@@ -8,8 +8,6 @@ use ViewComponents\Component;
class Button extends Component
{
protected string $label = '';
protected string $uri = '';
protected string $variant = 'default';
......@@ -22,6 +20,11 @@ class Button extends Component
protected bool $isSquared = false;
public function setIsSquared(string $value): void
{
$this->isSquared = $value === 'true';
}
public function render(): string
{
$baseClass =
......@@ -80,19 +83,31 @@ class Button extends Component
$this->slot .= '<Icon glyph="' . $this->iconRight . '" class="ml-2" />';
}
unset($this->attributes['slot']);
unset($this->attributes['variant']);
unset($this->attributes['size']);
unset($this->attributes['iconLeft']);
unset($this->attributes['iconRight']);
unset($this->attributes['isSquared']);
unset($this->attributes['uri']);
unset($this->attributes['label']);
if ($this->uri !== '') {
return anchor($this->uri, $this->label, array_merge([
'class' => $buttonClass,
], $this->attributes));
$tagName = 'a';
$defaultButtonAttributes = [
'href' => $this->uri,
];
} else {
$tagName = 'button';
$defaultButtonAttributes = [
'type' => 'button',
];
}
$defaultButtonAttributes = [
'type' => 'button',
];
$attributes = stringify_attributes(array_merge($defaultButtonAttributes, $this->attributes));
return <<<HTML
<button class="{$buttonClass}" {$attributes}>{$this->slot}</button>
<{$tagName} class="{$buttonClass}" {$attributes}>{$this->slot}</{$tagName}>
HTML;
}
}
<?php
declare(strict_types=1);
namespace App\Views\Components\Forms;
class Checkbox extends FormComponent
{
protected ?string $hint = null;
protected bool $isChecked = false;
public function setIsChecked(string $value): void
{
$this->isChecked = $value === 'true';
}
public function render(): string
{
$checkboxInput = form_checkbox(
[
'id' => $this->value,
'name' => $this->name,
'class' => 'form-checkbox text-pine-500 border-black border-3 focus:ring-2 focus:ring-pine-500 focus:ring-offset-2 focus:ring-offset-pine-100 w-6 h-6',
],
$this->value,
old($this->name) ? old($this->name) === $this->value : $this->isChecked,
);
$hint = $this->hint === null ? '' : hint_tooltip($this->hint, 'ml-1');
return <<<HTML
<label class="leading-8">
{$checkboxInput}
<span class="ml-2">{$this->slot}{$hint}</label>
</label>
HTML;
}
}
<?php
declare(strict_types=1);
namespace App\Views\Components\Forms;
class DatetimePicker extends FormComponent
{
public function render(): string
{
$this->attributes['class'] = 'rounded-l-lg border-0 border-rounded-r-none flex-1 focus:ring-0';
$this->attributes['data-input'] = '';
$dateInput = form_input($this->attributes, old($this->name, $this->value));
$clearLabel = lang(
'Episode.publish_form.scheduled_publication_date_clear',
);
$closeIcon = icon('close');
return <<<HTML
<div class="flex border-3 rounded-lg border-black focus-within:ring-2 focus-within:ring-pine-500 focus-within:ring-offset-2 focus-within:ring-offset-pine-100 {$this->class}" data-picker="datetime">
{$dateInput}
<button class="p-3 bg-white hover:bg-pine-100 focus:outline-none rounded-r-md focus:ring-inset focus:ring-2 focus:ring-pine-500 focus:ring-offset-2 focus:ring-offset-pine-100" type="button" aria-label="{$clearLabel}" title="{$clearLabel}" data-clear="">
{$closeIcon}
</button>
</div>
HTML;
}
}
......@@ -16,17 +16,35 @@ class FormComponent extends Component
protected bool $required = false;
protected bool $readonly = false;
public function __construct($attributes)
{
parent::__construct($attributes);
if ($this->id === null) {
$this->id = $this->name;
$this->attributes['id'] = $this->id;
}
}
public function setRequired(string $value): void
{
$this->required = $value === 'true';
if ($this->required) {
$this->attributes['required'] = 'required';
} else {
unset($this->attributes['required']);
}
}
public function setReadonly(string $value): void
{
$this->readonly = $value === 'true';
if ($this->readonly) {
$this->attributes['readonly'] = 'readonly';
} else {
unset($this->attributes['readonly']);
}
}
}
......@@ -7,7 +7,7 @@ namespace App\Views\Components\Forms;
class Helper extends FormComponent
{
/**
* @var "default"|"error"
* @var 'default'|'error'
*/
protected string $type = 'default';
......
......@@ -21,17 +21,12 @@ class Input extends FormComponent
$class .= ' border-black focus:border-black';
}
$data = [
'id' => $this->id,
'name' => $this->name,
'class' => $class,
'type' => $this->type,
];
$this->attributes['class'] = $class;
if ($this->required) {
$data['required'] = 'required';
$this->attributes['required'] = 'required';
}
return form_input($data, old($this->name, $this->value));
return form_input($this->attributes, old($this->name, $this->value));
}
}
......@@ -24,12 +24,17 @@ class Label extends Component
$labelClass = 'text-sm ' . $this->attributes['class'];
unset($this->attributes['class']);
$attributes = stringify_attributes($this->attributes);
$optionalText = $this->isOptional ? '<small class="ml-1 lowercase">(' .
lang('Common.optional') .
')</small>' : '';
$hint = $this->hint === null ? '' : hint_tooltip($this->hint, 'ml-1');
unset($this->attributes['isOptional']);
unset($this->attributes['hint']);
unset($this->attributes['slot']);
$attributes = stringify_attributes($this->attributes);
return <<<HTML
<label class="{$labelClass}" {$attributes}>{$this->slot}{$optionalText}{$hint}</label>
HTML;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment