Packages
phoenix_kit
1.7.120
1.7.208
1.7.207
1.7.206
1.7.205
1.7.204
1.7.203
1.7.202
1.7.201
1.7.200
1.7.199
1.7.198
1.7.197
1.7.196
1.7.194
1.7.193
1.7.192
1.7.191
1.7.190
1.7.189
1.7.187
1.7.186
1.7.185
1.7.184
1.7.183
1.7.182
1.7.181
1.7.180
1.7.179
1.7.178
1.7.177
1.7.176
1.7.175
1.7.174
1.7.173
1.7.172
1.7.171
1.7.170
1.7.169
1.7.168
1.7.167
1.7.166
1.7.165
1.7.164
1.7.162
1.7.161
1.7.160
1.7.159
1.7.157
1.7.156
1.7.155
1.7.154
1.7.153
1.7.152
1.7.151
1.7.150
1.7.149
1.7.146
1.7.145
1.7.144
1.7.143
1.7.138
1.7.133
1.7.132
1.7.131
1.7.130
1.7.128
1.7.126
1.7.125
1.7.121
1.7.120
1.7.119
1.7.118
1.7.117
1.7.116
1.7.115
1.7.114
1.7.113
1.7.112
1.7.111
1.7.110
1.7.109
1.7.108
1.7.107
1.7.106
1.7.105
1.7.104
1.7.103
1.7.102
1.7.101
1.7.100
1.7.99
1.7.98
1.7.97
1.7.96
1.7.95
1.7.94
1.7.93
1.7.92
1.7.91
1.7.90
1.7.89
1.7.88
1.7.87
1.7.86
1.7.85
1.7.84
1.7.83
1.7.82
1.7.81
1.7.80
1.7.79
1.7.78
1.7.77
1.7.76
1.7.75
1.7.74
1.7.71
1.7.70
1.7.69
1.7.66
1.7.65
1.7.64
1.7.63
1.7.62
1.7.61
1.7.59
1.7.58
1.7.57
1.7.56
1.7.55
1.7.54
1.7.53
1.7.52
1.7.51
1.7.49
1.7.44
1.7.43
1.7.42
1.7.41
1.7.39
1.7.38
1.7.37
1.7.36
1.7.34
1.7.33
1.7.31
1.7.30
1.7.29
1.7.28
1.7.27
1.7.26
1.7.25
1.7.24
1.7.23
1.7.22
1.7.21
1.7.20
1.7.19
1.7.18
1.7.17
1.7.16
1.7.15
1.7.14
1.7.13
1.7.12
1.7.11
1.7.10
1.7.9
1.7.8
1.7.7
1.7.6
1.7.5
1.7.4
1.7.3
1.7.2
1.7.1
1.7.0
1.6.20
1.6.19
1.6.18
1.6.17
1.6.16
1.6.15
1.6.14
1.6.13
1.6.12
1.6.11
1.6.10
1.6.9
1.6.8
1.6.7
1.6.6
1.6.5
1.6.4
1.6.3
1.5.2
1.5.1
1.5.0
1.4.9
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.2
1.3.1
1.3.0
1.2.10
1.2.9
1.2.8
1.2.7
1.2.5
1.2.4
1.2.2
1.2.1
1.2.0
1.1.0
1.0.0
A foundation for building Elixir Phoenix apps — SaaS, social networks, ERP systems, marketplaces, and more
Current section
Files
Jump to
Current section
Files
lib/modules/storage/web/dimension_form.html.heex
<PhoenixKitWeb.Components.LayoutWrapper.app_layout
flash={@flash}
phoenix_kit_current_scope={assigns[:phoenix_kit_current_scope]}
page_title={@page_title}
current_path={@current_path}
current_locale={@current_locale}
project_title={@project_title}
>
<div class="container mx-auto px-4 py-8 max-w-3xl">
<.admin_page_header
back={PhoenixKit.Utils.Routes.path("/admin/settings/media/dimensions")}
title={@page_title}
subtitle={gettext("Configure dimension presets for automatic file variant generation")}
/>
<.form for={@changeset} phx-change="validate" phx-submit="save" class="space-y-6">
<%!-- Basic Information --%>
<div class="card bg-base-100 shadow-sm">
<div class="card-body gap-4">
<h2 class="card-title text-lg">
<.icon name="hero-tag" class="w-5 h-5" /> {gettext("Basic Information")}
</h2>
<fieldset class="fieldset">
<legend class="fieldset-legend font-semibold">
{gettext("Dimension Name")} *
</legend>
<input
type="text"
name="dimension[name]"
phx-debounce="blur"
value={get_field_value(@changeset, :name)}
class={"input input-bordered w-full #{input_class(@changeset, :name)}"}
placeholder={gettext("e.g., thumbnail, medium, 720p")}
required
/>
{render_error(@changeset, :name)}
<p class="text-xs text-base-content/50 mt-1">
{gettext("A unique name to identify this dimension preset")}
</p>
</fieldset>
<input type="hidden" name="dimension[applies_to]" value={@dimension_type} />
</div>
</div>
<%!-- Size Configuration --%>
<div class="card bg-base-100 shadow-sm">
<div class="card-body gap-4">
<h2 class="card-title text-lg">
<.icon name="hero-arrows-pointing-out" class="w-5 h-5" />
{gettext("Size Configuration")}
</h2>
<%!-- Aspect Ratio Toggle --%>
<div class="form-control">
<label class="label cursor-pointer justify-start gap-3">
<input type="hidden" name="dimension[maintain_aspect_ratio]" value="false" />
<input
type="checkbox"
name="dimension[maintain_aspect_ratio]"
value="true"
checked={get_field_value(@changeset, :maintain_aspect_ratio) != false}
class="checkbox checkbox-primary"
/>
<div>
<span class="label-text font-semibold">
{gettext("Maintain Aspect Ratio")}
</span>
<p class="text-xs text-base-content/50">
<%= if get_field_value(@changeset, :maintain_aspect_ratio) != false do %>
{gettext("Only width is used, height is calculated automatically")}
<% else %>
{gettext("Both width and height are used for fixed dimensions")}
<% end %>
</p>
</div>
</label>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<fieldset class="fieldset">
<legend class="fieldset-legend font-semibold">
<%= if get_field_value(@changeset, :maintain_aspect_ratio) != false do %>
{gettext("Target Width (px)")} *
<% else %>
{gettext("Width (px)")} *
<% end %>
</legend>
<input
type="number"
name="dimension[width]"
phx-debounce="blur"
value={get_field_value(@changeset, :width)}
class={"input input-bordered w-full #{input_class(@changeset, :width)}"}
placeholder="800"
min="1"
required
/>
{render_error(@changeset, :width)}
</fieldset>
<%= if get_field_value(@changeset, :maintain_aspect_ratio) == false do %>
<fieldset class="fieldset">
<legend class="fieldset-legend font-semibold">
{gettext("Height (px)")} *
</legend>
<input
type="number"
name="dimension[height]"
phx-debounce="blur"
value={get_field_value(@changeset, :height)}
class={"input input-bordered w-full #{input_class(@changeset, :height)}"}
placeholder="600"
min="1"
required
/>
{render_error(@changeset, :height)}
</fieldset>
<% end %>
</div>
</div>
</div>
<%!-- Quality & Format --%>
<div class="card bg-base-100 shadow-sm">
<div class="card-body gap-4">
<h2 class="card-title text-lg">
<.icon name="hero-adjustments-horizontal" class="w-5 h-5" />
{gettext("Quality & Format")}
</h2>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<fieldset class="fieldset">
<legend class="fieldset-legend font-semibold">
<%= if @dimension_type == "video" do %>
{gettext("Quality (CRF)")}
<% else %>
{gettext("Quality")}
<% end %>
</legend>
<input
type="number"
name="dimension[quality]"
phx-debounce="blur"
value={get_field_value(@changeset, :quality)}
class={"input input-bordered w-full #{input_class(@changeset, :quality)}"}
placeholder={if @dimension_type == "video", do: "23", else: "85"}
min={if @dimension_type == "video", do: "0", else: "1"}
max={if @dimension_type == "video", do: "51", else: "100"}
/>
{render_error(@changeset, :quality)}
<p class="text-xs text-base-content/50 mt-1">
<%= if @dimension_type == "video" do %>
{gettext("CRF 0-51, lower = higher quality. 18-28 recommended.")}
<% else %>
{gettext("1-100, higher = better quality. 80-90 recommended.")}
<% end %>
</p>
</fieldset>
<fieldset class="fieldset">
<legend class="fieldset-legend font-semibold">
<%= if @dimension_type == "video" do %>
{gettext("Codec Override")}
<% else %>
{gettext("Format Override")}
<% end %>
</legend>
<% format_value = get_field_value(@changeset, :format) %>
<label class={"select w-full #{input_class(@changeset, :format)}"}>
<select name="dimension[format]">
<option value="">{gettext("Preserve original")}</option>
<%= if @dimension_type != "video" do %>
<option value="jpg" selected={format_value == "jpg"}>JPEG</option>
<option value="png" selected={format_value == "png"}>PNG</option>
<option value="webp" selected={format_value == "webp"}>WebP</option>
<% end %>
<%= if @dimension_type == "video" do %>
<option value="mp4" selected={format_value == "mp4"}>MP4</option>
<% end %>
</select>
</label>
{render_error(@changeset, :format)}
<p class="text-xs text-base-content/50 mt-1">
{gettext("Leave empty to preserve the original file format")}
</p>
</fieldset>
</div>
</div>
</div>
<%!-- Alternative Formats (image dimensions only) --%>
<%= if @dimension_type != "video" do %>
<div class="card bg-base-100 shadow-sm">
<div class="card-body gap-4">
<h2 class="card-title text-lg">
<.icon name="hero-document-duplicate" class="w-5 h-5" />
{gettext("Alternative Formats")}
</h2>
<p class="text-sm text-base-content/60">
{gettext(
"Generate additional format variants alongside the primary format. Modern formats like WebP and AVIF offer better compression."
)}
</p>
<input type="hidden" name="dimension[alternative_formats][]" value="" />
<div class="flex flex-wrap gap-4">
<%= for {fmt, label} <- [{"webp", "WebP"}, {"avif", "AVIF"}, {"png", "PNG"}, {"jpg", "JPEG"}] do %>
<%= if fmt != @primary_format do %>
<label class="label cursor-pointer gap-2">
<input
type="checkbox"
name="dimension[alternative_formats][]"
value={fmt}
checked={fmt in @current_alternatives}
class="checkbox checkbox-sm checkbox-primary"
/>
<span class="label-text">{label}</span>
</label>
<% end %>
<% end %>
</div>
{render_error(@changeset, :alternative_formats)}
</div>
</div>
<% end %>
<%!-- Actions --%>
<div class="flex justify-end gap-3">
<.link
navigate={PhoenixKit.Utils.Routes.path("/admin/settings/media/dimensions")}
class="btn btn-ghost"
>
{gettext("Cancel")}
</.link>
<button type="submit" class="btn btn-primary" disabled={!@changeset.valid?}>
<.icon name="hero-check" class="w-4 h-4" /> {@form_action}
</button>
</div>
</.form>
</div>
</PhoenixKitWeb.Components.LayoutWrapper.app_layout>