Skip to main content

File

Overview

The File component provides a Bulma-styled file input, supporting color, size, boxed/fullwidth/align styles, icons, "has name", and filename display.

It is highly customizable for all file upload UI needs.


Import

import { File, Icon } from '@allxsmith/bestax-bulma';

Usage

File is a self-contained Bulma file widget. It detects whether it's already inside a Field and skips rendering its own field wrapper if so. For typical use, pass buttonLabel, iconLeft, and any modifier props (hasName, isBoxed, isFullwidth, isRight, isCentered, color, size) — Bulma doesn't document file inputs in addons or grouped layouts, so the convenience form covers every case. Use label only when you want an additional Bulma <label class="label"> rendered above the widget.

Default

A basic file input. The buttonLabel prop sets the text on the CTA button, and iconLeft adds an icon for visual context.

<File buttonLabel="Choose a file…" iconLeft={<Icon name="upload" />} />


With Filename Display

Set hasName to display the selected file name. The fileName prop shows a custom or pre-selected name.

<File
  hasName
  fileName="resume.pdf"
  buttonLabel="Choose a file…"
  iconLeft={<Icon name="upload" />}
/>


CTA on Right

Combine isRight with hasName to put the CTA button on the right and the filename on the left.

<File
  hasName
  isRight
  fileName="contract.pdf"
  buttonLabel="Choose a file…"
  iconLeft={<Icon name="upload" />}
/>


Full Width

isFullwidth makes the file input take the full width of its container — pairs well with hasName so the filename area expands.

<File
  hasName
  isFullwidth
  fileName="picture.png"
  buttonLabel="Choose a file…"
  iconLeft={<Icon name="upload" />}
/>


Boxed

isBoxed stacks the icon over the text into a square box.

<File isBoxed buttonLabel="Choose a file…" iconLeft={<Icon name="upload" />} />


Boxed with Name

Combine isBoxed and hasName for a boxed widget that also shows the filename.

<File
  isBoxed
  hasName
  fileName="holiday.jpg"
  buttonLabel="Choose a file…"
  iconLeft={<Icon name="upload" />}
/>


Colors

The color prop applies Bulma color modifiers. The four examples below match the combinations Bulma's docs show.

<>
  <File
    color="primary"
    buttonLabel="Choose a file…"
    iconLeft={<Icon name="upload" />}
  />
  <File
    color="info"
    hasName
    fileName="resume.pdf"
    buttonLabel="Choose a file…"
    iconLeft={<Icon name="upload" />}
  />
  <File
    color="warning"
    isBoxed
    buttonLabel="Choose a file…"
    iconLeft={<Icon name="cloud-upload-alt" />}
  />
  <File
    color="danger"
    isBoxed
    hasName
    fileName="resume.pdf"
    buttonLabel="Choose a file…"
    iconLeft={<Icon name="cloud-upload-alt" />}
  />
</>


Sizes

The size prop controls the file input's size.

<>
  <File
    size="small"
    buttonLabel="Choose a file…"
    iconLeft={<Icon name="upload" />}
  />
  <File buttonLabel="Choose a file…" iconLeft={<Icon name="upload" />} />
  <File
    size="medium"
    buttonLabel="Choose a file…"
    iconLeft={<Icon name="upload" />}
  />
  <File
    size="large"
    buttonLabel="Choose a file…"
    iconLeft={<Icon name="upload" />}
  />
</>


Sizes with Name

Combine size with hasName to scale the filename display alongside the button.

<>
  <File
    size="small"
    hasName
    fileName="sample.txt"
    buttonLabel="Choose a file…"
    iconLeft={<Icon name="upload" />}
  />
  <File
    hasName
    fileName="sample.txt"
    buttonLabel="Choose a file…"
    iconLeft={<Icon name="upload" />}
  />
  <File
    size="medium"
    hasName
    fileName="sample.txt"
    buttonLabel="Choose a file…"
    iconLeft={<Icon name="upload" />}
  />
  <File
    size="large"
    hasName
    fileName="sample.txt"
    buttonLabel="Choose a file…"
    iconLeft={<Icon name="upload" />}
  />
</>


Sizes with Boxed

Combine size with isBoxed for boxed file inputs at every size.

<>
  <File
    size="small"
    isBoxed
    buttonLabel="Choose a file…"
    iconLeft={<Icon name="upload" />}
  />
  <File
    isBoxed
    buttonLabel="Choose a file…"
    iconLeft={<Icon name="upload" />}
  />
  <File
    size="medium"
    isBoxed
    buttonLabel="Choose a file…"
    iconLeft={<Icon name="upload" />}
  />
  <File
    size="large"
    isBoxed
    buttonLabel="Choose a file…"
    iconLeft={<Icon name="upload" />}
  />
</>


Sizes with Boxed and Name

For a boxed file input that also shows the filename, combine isBoxed, hasName, and size.

<>
  <File
    size="small"
    isBoxed
    hasName
    fileName="summary.docx"
    buttonLabel="Choose a file…"
    iconLeft={<Icon name="upload" />}
  />
  <File
    isBoxed
    hasName
    fileName="summary.docx"
    buttonLabel="Choose a file…"
    iconLeft={<Icon name="upload" />}
  />
  <File
    size="medium"
    isBoxed
    hasName
    fileName="summary.docx"
    buttonLabel="Choose a file…"
    iconLeft={<Icon name="upload" />}
  />
  <File
    size="large"
    isBoxed
    hasName
    fileName="summary.docx"
    buttonLabel="Choose a file…"
    iconLeft={<Icon name="upload" />}
  />
</>


Alignment: Centered

isCentered centers the widget within its parent container.

<File
  color="info"
  isCentered
  isBoxed
  hasName
  fileName="centered.pdf"
  buttonLabel="Choose a file…"
  iconLeft={<Icon name="upload" />}
/>


Alignment: Right

isRight aligns the widget to the right of its parent.

<File
  color="primary"
  isRight
  hasName
  fileName="right.pdf"
  buttonLabel="Choose a file…"
  iconLeft={<Icon name="upload" />}
/>


Context-Aware Rendering

The File component is context-aware: it detects whether it is already inside a Field and skips rendering its own field wrapper if so. Use label to add a Bulma <label class="label"> above the widget; use buttonLabel to set the CTA text.

note

File does not consume the Control context (it is its own self-contained widget). The "With Field and Control Wrappers" example below shows that wrapping File in a Control is harmless but doesn't change its rendering.

Default (with label)

The simplest usage — label adds a Field label above the widget.

<File
  label="Document"
  buttonLabel="Choose a file…"
  iconLeft={<Icon name="upload" />}
/>


With Field Wrapper

For manual layout control (e.g., horizontal forms), wrap in Field. The component detects it's inside a Field and skips rendering its own.

function example() {
  return (
    <Field horizontal label="Document">
      <Field.Body>
        <Field>
          <File
            buttonLabel="Choose a file…"
            iconLeft={<Icon name="upload" />}
          />
        </Field>
      </Field.Body>
    </Field>
  );
}


With Field and Control Wrappers

For full manual composition, wrap in both Field and Control. File doesn't consume Control's context but the outer Field is still detected and File's own Field wrapper is skipped.

function example() {
  return (
    <Field horizontal label="Document">
      <Field.Body>
        <Field>
          <Control iconLeftName="paperclip">
            <File
              buttonLabel="Choose a file…"
              iconLeft={<Icon name="upload" />}
            />
          </Control>
        </Field>
      </Field.Body>
    </Field>
  );
}


Accessibility

  • The root is a <div class="file"> with a nested <label> and <input type="file">.
  • The label is always clickable.
  • When File renders its own Field (that is, outside an existing one), the Field-level label prop is automatically associated with the file input via htmlFor, so the input then has two labels (the Field label plus the wrapping CTA label); assistive technology reads both. An explicit labelProps.htmlFor overrides the association and no id is generated.
  • Add aria-label to the <input> for accessibility if your label is not plain text.


Additional Resources


Props

PropTypeDefaultDescription
labelReact.ReactNodeField label. Automatically associated with the file input via htmlFor — uses your id when provided, otherwise a generated one. The input then has two labels (this one plus the wrapping file-label); assistive tech reads both. Dropped inside an outer Field (label that Field yourself).
labelPropsReact.LabelHTMLAttributes<HTMLLabelElement> & { [key: string]: unknown; }Props for the label element. An explicit htmlFor here overrides the automatic association (no id is generated then).
color'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger' | 'black' | 'dark' | 'light' | 'white'Bulma color modifier for the file input.
size'small' | 'medium' | 'large'Size modifier for the file input.
isBoxedbooleanfalseBoxed file input.
isFullwidthbooleanfalseWhether the file input expands to full width.
isFullWidthbooleanfalseDeprecated. Use isFullwidth instead — isFullwidth wins if both are set. Whether the file input expands to full width.
isRightbooleanfalsePosition the CTA on the right (with hasName).
isCenteredbooleanfalseCenter the file input within its container.
hasNamebooleanfalseShow a file name indicator.
buttonLabelReact.ReactNodeText on the file CTA button (defaults to "Choose a file…").
iconLeftReact.ReactNodeLeft icon element.
iconRightReact.ReactNodeRight icon element.
classNamestringAdditional CSS classes to apply.
inputClassNamestringAdditional CSS classes for the <input>.
fileNamestringFile name to display.
labelSize'small' | 'normal' | 'medium' | 'large'Size for the label (used in horizontal layouts).
horizontalbooleanfalseHorizontal field layout.
messageReact.ReactNodeHelp/validation message below the input.
messageColor'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger'Bulma color for the message.
fieldClassNamestringAdditional CSS classes for the Field wrapper.
refReact.Ref<HTMLInputElement>Forwarded to the underlying element.
...All standard <input> attributes and Bulma helper propsSee Helper Props

CSS & Sass Variables

File registers these variables on its own .file element. Override them there (or via className) — a value set on an ancestor is only inherited, and loses to the component-level declaration. See Theme.

CSS VariableSass VariableDefault
--bulma-file-radius$file-radiusvar(--bulma-radius)
--bulma-file-name-border-color$file-name-border-colorvar(--bulma-border)
--bulma-file-name-border-style$file-name-border-stylesolid
--bulma-file-name-border-width$file-name-border-width1px 1px 1px 0
--bulma-file-name-max-width$file-name-max-width16em
--bulma-file-h$file-hvar(--bulma-scheme-h)
--bulma-file-s$file-svar(--bulma-scheme-s)
--bulma-file-background-l$file-background-lvar(--bulma-scheme-main-ter-l)
--bulma-file-background-l-delta$file-background-l-delta0%
--bulma-file-hover-background-l-delta$file-hover-background-l-delta-5%
--bulma-file-active-background-l-delta$file-active-background-l-delta-10%
--bulma-file-border-l$file-border-lvar(--bulma-border-l)
--bulma-file-border-l-delta$file-border-l-delta0%
--bulma-file-hover-border-l-delta$file-hover-border-l-delta-10%
--bulma-file-active-border-l-delta$file-active-border-l-delta-20%
--bulma-file-cta-color-l$file-cta-color-lvar(--bulma-text-strong-l)
--bulma-file-name-color-l$file-name-color-lvar(--bulma-text-strong-l)
--bulma-file-color-l-delta$file-color-l-delta0%
--bulma-file-hover-color-l-delta$file-hover-color-l-delta-5%
--bulma-file-active-color-l-delta$file-active-color-l-delta-10%