Customize live_file_input

Hello! I am trying to customize the file input generated by the following code:

 <%= live_file_input @uploads.my_upload, class: "my-classes"%>

this gets turned into:

<input accept=".png,.jpg,.jpeg,.pdf" class="my-classes" data-phx-active-refs="" data-phx-done-refs="" data-phx-preflighted-refs="" data-phx-update="ignore" data-phx-upload-ref="phx-Fo-HLbVCBA32siBG" id="phx-Fo-HLbVCBA32siBG" name="my_upload
" phx-hook="Phoenix.LiveFileUpload" type="file">

Right now it just displays a button that says “Browse…” and next to that is “No file selected.”. I want to customize this button with my own text and styles but so far have not been able to achieve this. The docs for live_file_input say you can pass options (like :class) but there is no list of options to reference from. Thank you!

Referring to the options, the docs say

Options may be passed through to the tag builder for custom attributes.

The tag builder just makes an html element like

<tag option1="opt1_val" option2="opt2_val">content</tag>

You can see an example of this when you pass class: "my-classes" to the builder and that translates to class="my-classes" in HTML. You can pass whatever name/value you want - AFAIK there is no requirement that they are valid attributes for any particular tag type.

You can find more about HTML file input attributes here

I found a solution. I just wrapped the whole live_file_input in a label tag and set the live_file_input to display: none like this:

<label class="my-classes">
   <%= live_file_input @uploads.my_upload, class: "hidden"%>
   my custom upload file text

This way I can customize the file input text and styles they way I want! Apparently its not so straightforward to style file upload inputs.

1 Like

There are a couple of methods described on MDN. Using display none is warned against as it affects keyboard accessibility.

Using Alpine JS to trigger the click with the visullay-hidden css trick on the MDN page:

<LiveFileInput upload={@uploads.dbf} class="visually-hidden" opts={"x-ref": "liveFileInput"} />
<Button color="gray" opts={"x-on:click": "$"}>Select files</Button>