feat(ui): add collapsible advanced settings and enlarge compose modal

Extract a shared forms collapsible for advanced SSH/build settings
across boarding, server creation, and application general. Support
larger modals with header actions, close the compose editor after
save via compose-save-finished, and cover the layout in tests.
This commit is contained in:
Andras Bacsai committed 2026-08-07 16:22:11 +02:00
1 parent 4926cdba0e
commit ada3ea354a
12 files changed
+207 -144

No files matched your search

@@ -0,0 +1,22 @@
@props([
'title' => 'Advanced settings',
'contentClass' => '',
])
<div x-data="{ open: false }" {{ $attributes->class(['flex flex-col gap-4']) }}>
<button type="button" x-on:click="open = !open"
class="flex items-center gap-2 text-left text-sm font-medium hover:underline" :aria-expanded="open">
<svg class="size-4 transition-transform" x-bind:class="open && 'rotate-90'" viewBox="0 0 20 20"
fill="currentColor" aria-hidden="true">
<path fill-rule="evenodd"
d="M7.21 14.77a.75.75 0 0 1 .02-1.06L11.168 10 7.23 6.29a.75.75 0 1 1 1.04-1.08l4.5 4.25a.75.75 0 0 1 0 1.08l-4.5 4.25a.75.75 0 0 1-1.06-.02Z"
clip-rule="evenodd" />
</svg>
{{ $title }}
</button>
<div x-show="open" x-cloak
class="rounded-lg border border-neutral-200 p-4 dark:border-coolgray-400 {{ $contentClass }}">
{{ $slot }}
</div>
</div>
@@ -12,6 +12,7 @@
// Optional Livewire bool property to entangle open state (survives Livewire re-renders).
'wireOpen' => null,
'contentClicks' => true,
'isLarge' => false,
])
@php
@@ -54,10 +55,19 @@
x-transition:leave="ease-in duration-100"
x-transition:leave-start="opacity-100 translate-y-0 sm:scale-100"
x-transition:leave-end="opacity-0 -translate-y-2 sm:scale-95"
class="application-settings-form application-settings-section relative max-h-[calc(100dvh-2rem)] w-full lg:w-auto lg:min-w-2xl lg:max-w-4xl"
@class([
'application-settings-form application-settings-section relative flex max-h-[calc(100dvh-2rem)] w-full flex-col overflow-hidden',
'lg:w-[95vw]! lg:max-w-7xl!' => $isLarge,
'lg:w-auto lg:min-w-2xl lg:max-w-4xl' => ! $isLarge,
])
style="box-shadow: 0 0 0 1px var(--coollabs-hairline), var(--shadow-modal)">
<header class="flex-nowrap!">
<h3 class="min-w-0 flex-1 truncate">{{ $title }}</h3>
@isset($headerActions)
<div class="flex shrink-0 items-center gap-2">
{{ $headerActions }}
</div>
@endisset
<button type="button" @click="modalOpen=false"
class="flex size-7 shrink-0 cursor-pointer items-center justify-center rounded-md text-neutral-500 outline-0 transition-colors hover:bg-neutral-100 hover:text-black focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-accent dark:text-fg-faint dark:hover:bg-white/[0.06] dark:hover:text-fg">
<x-reicon name="x" class="size-4" />