Packages
moon
2.76.5
2.90.5
retired
2.90.4
2.90.3
2.90.2
2.90.1
2.90.0
2.89.4
2.89.1
2.89.0
2.88.0
2.87.11
2.87.10
2.87.9
2.87.8
2.87.7
2.87.6
2.87.5
2.87.4
2.87.3
2.87.2
2.87.1
2.87.0
2.86.1
2.86.0
2.85.1
2.85.0
2.84.0
2.83.0
2.82.0
2.81.4
2.81.3
2.81.2
2.81.1
2.81.0
2.80.2
2.80.1
2.80.0
2.79.13
2.79.12
2.79.11
2.79.10
2.79.9
2.79.8
2.79.7
2.79.6
2.79.5
2.79.4
2.79.3
2.79.2
2.79.1
2.79.0
2.78.4
2.78.3
2.78.2
2.78.1
2.78.0
2.77.0
2.76.5
2.76.4
2.76.3
2.76.2
2.76.1
2.76.0
2.75.0
2.74.1
2.74.0
2.73.8
2.73.7
2.73.6
2.73.5
2.73.4
2.73.3
2.73.2
2.73.1
2.73.0
2.72.5
2.72.4
2.72.3
2.72.2
2.72.1
2.72.0
2.71.1
2.71.0
2.70.0
2.69.2
2.69.1
2.69.0
2.68.11
2.68.10
Components-based design system written in elixir
Current section
Files
Jump to
Current section
Files
lib/moon_web/pages/components/file_input_page.ex
defmodule MoonWeb.Pages.Components.FileInputPage do
@moduledoc false
use MoonWeb, :live_view
alias Moon.Autolayouts.TopToDown
alias Moon.Components.Button
alias Moon.Components.FileInput
alias Moon.Components.Form
alias Moon.Components.Link
alias MoonWeb.Components.ExampleAndCode
alias MoonWeb.Components.Page
alias MoonWeb.Components.ComponentPageDescription
alias __MODULE__.SimpleS3Upload
data(breadcrumbs, :any,
default: [
%{
to: "#",
name: "Components v1"
},
%{
to: "/components/file-input",
name: "File Input"
}
]
)
def render(assigns) do
~F"""
<Page {=@theme_name} {=@active_page} {=@breadcrumbs} {=@direction}>
<ComponentPageDescription title="File Input">
<p>
Uploads: <Link to="https://hexdocs.pm/phoenix_live_view/uploads.html">https://hexdocs.pm/phoenix_live_view/uploads.html</Link>
</p>
<p>
External uploads: <Link to="https://hexdocs.pm/phoenix_live_view/uploads-external.html">https://hexdocs.pm/phoenix_live_view/uploads-external.html</Link>
</p>
</ComponentPageDescription>
<ExampleAndCode title="Local upload" id="file_input_1">
<:example>
<Form id="upload-form-1" for={:example_form} change="upload_changed" submit="upload_submitted">
<TopToDown>
<FileInput
conf={@uploads.some_picture_file}
label="Upload your ID"
placeholder="Choose a photo..."
cancel_upload="cancel-upload"
/>
<Button type="submit" variant="primary">Upload</Button>
</TopToDown>
</Form>
</:example>
<:code>{get_example_1_code()}</:code>
<:state>{get_example_1_state(assigns)}</:state>
</ExampleAndCode>
<ExampleAndCode title="Upload directly from browser to S3" id="file_input_2">
<:example>
<Form
id="upload-form-2"
for={:example_form_for_s3}
change="upload_s3_changed"
submit="upload_s3_submitted"
>
<TopToDown>
<FileInput
conf={@uploads.some_picture_file_for_s3}
label="Upload your ID"
placeholder="Choose a photo..."
cancel_upload="cancel-upload"
/>
<Button type="submit" variant="primary">Upload</Button>
</TopToDown>
</Form>
</:example>
<:code>{get_example_2_code()}</:code>
<:state>{get_example_2_state(assigns)}</:state>
</ExampleAndCode>
<ExampleAndCode title="Custom design instead of button" id="file_input_3">
<:example>
<Form id="upload-form-3" for={:example_form} change="upload_changed" submit="upload_submitted">
<TopToDown>
<FileInput conf={@uploads.some_picture_file} cancel_upload="cancel-upload">
.oOo.
</FileInput>
<Button type="submit" variant="primary">Upload</Button>
</TopToDown>
</Form>
</:example>
<:code>{get_example_3_code()}</:code>
<:state>{get_example_1_state(assigns)}</:state>
</ExampleAndCode>
</Page>
"""
end
def mount(_params, _session, socket) do
socket =
assign(socket,
uploaded_files: []
)
|> allow_upload(:some_picture_file,
accept: ~w(.jpg .jpeg .png .pdf),
max_file_size: 1024 * 1024,
max_entries: 1
)
|> allow_upload(:some_picture_file_for_s3,
accept: ~w(.jpg .jpeg .png .pdf),
max_file_size: 1024 * 1024,
max_entries: 1,
external: &presign_upload/2
)
{:ok, socket}
end
def handle_params(_params, uri, socket) do
{:noreply, assign(socket, uri: uri)}
end
def handle_event("upload_changed", _params, socket) do
{:noreply, socket}
end
def handle_event("upload_s3_changed", _params, socket) do
{:noreply, socket}
end
def handle_event("upload_s3_submitted", _params, socket) do
consume_uploaded_entries(socket, :image, fn _meta, entry -> {:ok, entry} end)
{:noreply, socket}
end
def handle_event("cancel_upload", %{"ref" => ref}, socket) do
{:noreply, cancel_upload(socket, :image, ref)}
end
def presign_upload(entry, socket) do
uploads = socket.assigns.uploads
s3_config = Application.get_env(:moon, :s3)
bucket = s3_config[:bucket]
key = "uploaded-file"
config = %{
region: s3_config[:region],
access_key_id: s3_config[:access_key_id],
secret_access_key: s3_config[:secret_access_key]
}
{:ok, fields} =
SimpleS3Upload.sign_form_upload(config, bucket,
key: key,
content_type: entry.client_type,
max_file_size: uploads.some_picture_file_for_s3.max_file_size,
expires_in: :timer.hours(1)
)
meta = %{
uploader: "S3",
key: key,
url: "https://#{bucket}.s3.#{config.region}.amazonaws.com/",
fields: fields
}
{:ok, meta, socket}
end
def get_example_1_state(assigns) do
"""
@uploaded_files = #{inspect(assigns.uploaded_files)}
@uploads.some_picture_file = #{inspect(assigns.uploads.some_picture_file)}
"""
end
def get_example_2_state(assigns) do
"""
@uploaded_files = #{inspect(assigns.uploaded_files)}
@uploads.some_picture_file = #{inspect(assigns.uploads.some_picture_file)}
"""
end
def get_example_1_code() do
"""
<Form id="upload-form-1" for={:example_form} change="upload_changed" submit="upload_submitted">
<TopToDown>
<FileInput conf={@uploads.some_picture_file} label="Upload your ID" placeholder="Choose a photo..." />
<section phx-drop-target={@uploads.some_picture_file.ref} class={"p-4", Moon.Components.FieldBorder.get_default_class()}>
<h1>Drag and drop area</h1>
<div>
{#for entry <- @uploads.some_picture_file.entries}
<.live_img_preview entry={entry} style="max-width: 200px; max-height: 200px;" />
<progress value={entry.progress} max="100">{entry.progress}</progress>
<button phx-click="cancel-upload" phx-value-ref={entry.ref} aria-label="cancel">×</button>
{#for err <- upload_errors(@uploads.some_picture_file, entry)}
<p class="alert alert-danger">{inspect(err)}</p>
{/for}
{/for}
</div>
{#for err <- upload_errors(@uploads.some_picture_file)}
<p class="alert alert-danger">{inspect(err)}</p>
{/for}
</section>
<Button type="submit" variant="primary">Upload</Button>
</TopToDown>
</Form>
"""
end
def get_example_2_code() do
"""
<Form id="upload-form-2" for={:example_form_for_s3} change="upload_s3_changed" submit="upload_s3_submitted">
<TopToDown>
<FileInput conf={@uploads.some_picture_file_for_s3} label="Upload your ID" placeholder="Choose a photo..." />
<section phx-drop-target={@uploads.some_picture_file_for_s3.ref} class={"p-4", Moon.Components.FieldBorder.get_default_class()}>
<h1>Drag and drop area</h1>
<div>
{#for entry <- @uploads.some_picture_file_for_s3.entries}
<.live_img_preview entry={entry} style="max-width: 200px; max-height: 200px;" />
<progress value={entry.progress} max="100">{entry.progress}</progress>
<button phx-click="cancel-upload" phx-value-ref={entry.ref} aria-label="cancel">×</button>
{#for err <- upload_errors(@uploads.some_picture_file_for_s3, entry)}
<p class="alert alert-danger">{inspect(err)}</p>
{/for}
{/for}
</div>
{#for err <- upload_errors(@uploads.some_picture_file_for_s3)}
<p class="alert alert-danger">{inspect(err)}</p>
{/for}
</section>
<Button type="submit" variant="primary">Upload</Button>
</TopToDown>
</Form>
"""
end
def get_example_3_code() do
"""
<Form id="upload-form-3" for={:example_form} change="upload_changed" submit="upload_submitted">
<TopToDown>
<FileInput
conf={@uploads.some_picture_file}
label="Upload your ID"
placeholder="Choose a photo..."
cancel_upload="cancel-upload"
>
.oOo.
</FileInput>
<Button type="submit" variant="primary">Upload</Button>
</TopToDown>
</Form>
"""
end
end