{{--
A stored URL, rendered as a link out of the app.
Props:
url The stored URL, or null. Nothing but the fallback renders
when it is empty, so a detail row still reads as a row.
fallback What an empty url shows. An em-dash unless told otherwise.
label Link text. The url itself unless told otherwise.
Two things this component owns so no caller has to remember them:
* `target="_blank"` gets `rel="noopener noreferrer"` with it. Without
noopener the opened page can reach back through window.opener; without
noreferrer it learns which of our screens it was opened from.
* The url reaches the href through Blade's own escaping, so a quote in a
stored value closes nothing. The scheme is the server's job and is
already done: every url column is validated `url:http,https`, which is
what keeps `javascript:` out of an href — escaping alone would not.
The scheme is checked again below anyway. Nothing the app writes can fail
that check, so the branch is unreachable through the forms; it is there for
a value that predates the validation rule or was written straight to the
database, which the FormRequest cannot speak for. A url that fails it
renders as the fallback rather than as a link.
--}}
@props([
'url' => null,
'fallback' => '—',
'label' => null,
])
@if (filled($url) && (str_starts_with($url, 'http://') || str_starts_with($url, 'https://')))
merge(['class' => 'text-primary']) }}>{{ $label ?? $url }}
@else
{{ $fallback }}
@endif