Files
coolify/resources/views/components/forms/input.blade.php
T
Aditya Tripathi 7a96f0900d fix(ui): follow-up polish + extend deploy-log reopen to apps
- Fix DB URL copy button: a Blade @if inside the <x-copy-button> tag silently
  broke the component; compute the resolve expression in PHP and pass one attr
- Sidebar: show section dividers between groups in the collapsed rail
- Project cards/list + dashboard: use the app's styled tooltip (data-tooltip) on
  the env/resource icon stats, and lift them above the card link overlay so they
  actually receive hover
- Applications: show the persistent 'Deploying… View log' indicator (links to the
  running deployment's log page) in the heading, extending the reopen feature to
  all resource types
- Shared variables: use the canonical application-settings-workspace stacked,
  sticky sidebar to match other settings pages
- Environment page: add a 'Shared variables' shortcut to the dedicated page
2026-09-14 07:12:11 +00:00

112 lines
5.6 KiB
PHP

@php
// Copy affordance reads the live Livewire value. The bound property comes
// either from the `id`-derived modelBinding or from a passthrough
// `wire:model` attribute (used by read-only fields like DB URLs). Resolve to a
// single JS expression here — a directive inside the <x-copy-button> tag would
// break Blade's component-tag compiler.
$copyResolve = null;
if ($copyable) {
$copyModel = $modelBinding !== 'null' ? $modelBinding : $attributes->get('wire:model');
$copyResolve = $copyModel
? "\$wire.get('".$copyModel."')"
: (string) \Illuminate\Support\Js::from($value);
}
@endphp
<div @class([
'flex-1' => $isMultiline,
'w-full' => !$isMultiline,
])>
@if ($label)
{{--
Fixed-height label row (h-4 = helper icon). Helper lives outside <label> so
side-by-side fields align whether a field has a helper, required mark, both, or neither.
Margin is only on this wrapper — mb-0! beats .application-settings-form label rules.
--}}
<div class="mb-1.5 flex h-4 w-full items-center gap-1.5">
<label class="mb-0! flex items-center gap-1 text-sm font-medium leading-4">{{ $label }}
@if ($required)
<x-highlighted text="*" />
@endif
@isset($labelSuffix)
{{ $labelSuffix }}
@endisset
</label>
@if ($helper)
<x-helper :helper="$helper" />
@endif
</div>
@endif
@if ($loading)
<div class="{{ $defaultClass }} flex w-full items-center text-neutral-500 dark:text-fg-dim" aria-busy="true">
<x-loading :text="$loadingText" />
</div>
@elseif ($type === 'password')
<div class="relative" x-data="{ type: 'password' }" @success.window="type = 'password'">
<input autocomplete="{{ $autocomplete }}" value="{{ $value }}"
x-bind:type="type"
x-bind:class="{ 'truncate': type === 'text' && ! $el.disabled }"
{{ $attributes->merge(['class' => $defaultClass]) }} @required($required)
@if ($modelBinding !== 'null') wire:model={{ $modelBinding }} wire:dirty.class="[box-shadow:inset_4px_0_0_#6b16ed,inset_0_0_0_2px_#e5e5e5] dark:[box-shadow:inset_4px_0_0_#fcd452,inset_0_0_0_2px_#242424]" @endif
wire:loading.attr="disabled"
@readonly($readonly) @disabled($disabled) id="{{ $htmlId }}"
name="{{ $name }}" placeholder="{{ $attributes->get('placeholder') }}"
aria-placeholder="{{ $attributes->get('placeholder') }}"
@if ($autofocus) x-ref="autofocusInput" autofocus @endif>
@if ($allowToPeak)
<button type="button" x-on:click="type = type === 'password' ? 'text' : 'password'"
class="password-toggle flex absolute inset-y-0 right-0 z-10 items-center pr-2 cursor-pointer text-neutral-500 hover:text-black dark:text-neutral-400 dark:hover:text-white"
aria-label="Toggle password visibility">
{{-- Eye icon (shown when password is hidden) --}}
<x-reicon name="eye" x-show="type === 'password'" class="size-[18px]" />
{{-- Eye-off2 icon (shown when password is visible) --}}
<x-reicon name="eye-off2" x-cloak x-show="type === 'text'" class="size-[18px]" />
</button>
@endif
@if ($copyable)
<x-copy-button :resolve="$copyResolve" label="Copy to clipboard"
class="absolute top-1/2 z-10 -translate-y-1/2 {{ $allowToPeak ? 'right-8' : 'right-1' }}" />
@endif
</div>
@else
@if ($copyable)
<div class="relative">
@endif
<input autocomplete="{{ $autocomplete }}" @if ($value) value="{{ $value }}" @endif
{{ $attributes->merge(['class' => $defaultClass]) }} @required($required) @readonly($readonly)
@if ($modelBinding !== 'null') wire:model={{ $modelBinding }} wire:dirty.class="[box-shadow:inset_4px_0_0_#6b16ed,inset_0_0_0_2px_#e5e5e5] dark:[box-shadow:inset_4px_0_0_#fcd452,inset_0_0_0_2px_#242424]" @endif
wire:loading.attr="disabled"
type="{{ $type }}" @disabled($disabled) min="{{ $attributes->get('min') }}"
max="{{ $attributes->get('max') }}" minlength="{{ $attributes->get('minlength') }}"
maxlength="{{ $attributes->get('maxlength') }}"
@if ($htmlId !== 'null') id={{ $htmlId }} @endif name="{{ $name }}"
placeholder="{{ $attributes->get('placeholder') }}"
@if ($autofocus) x-ref="autofocusInput" autofocus @endif>
@if ($copyable)
<x-copy-button :resolve="$copyResolve" label="Copy to clipboard"
class="absolute top-1/2 right-1 z-10 -translate-y-1/2" />
</div>
@endif
@endif
@if (!$label && $helper)
<x-helper :helper="$helper" />
@endif
@error($modelBinding)
<label class="label">
@php
preg_match('/(https?:\/\/\S+)$/', $message, $validationLinkMatches);
$validationLink = $validationLinkMatches[1] ?? null;
@endphp
<span class="text-red-500 label-text-alt">
@if ($validationLink)
{{ str($message)->beforeLast($validationLink)->trim() }}
<a class="font-medium underline" href="{{ $validationLink }}">Set them here.</a>
@else
{{ $message }}
@endif
</span>
</label>
@enderror
</div>