Jangle UI documentation
Components

Add labeled actions, waiting states, and native form behavior with Jangle UI Button.

Use Button

<jangle-button> is for a visible, labeled action in the current context: Save, Apply, Create, Retry, or opening an application-owned experience. Use an anchor when the primary result is navigating to a URL, and do not use an empty label to create an icon-only action.

Add Button

Configure package access and install Components and Tokens, then load the theme and Button registration entry:

import '@jangle-ui/tokens/tokens.css';
import '@jangle-ui/components/button/register';
<jangle-button intent="brand" treatment="strong" icon="save"> Save changes </jangle-button>

The default is a neutral, subtle, medium Button with type="button". Choose intent for the action's meaning, treatment for its emphasis, and size for the complete control size. Button also accepts a leading or trailing Icon name and keeps that Icon decorative because the visible text names the action.

Use context="inverse" only when the Button sits on an inverse surface.

Match an action to a Status surface

On a Status surface, use intent="neutral" treatment="quiet" and the matching context: status-information, status-success, status-warning, or status-danger. For example, a Warning Alert's recovery action uses:

<jangle-button context="status-warning" intent="neutral" treatment="quiet" size="sm">
  Reconnect
</jangle-button>

The action rests transparent and uses the host palette for hover and pressed states. Set context explicitly and update it if the host tone changes; Button does not infer it from an ancestor.

Status contexts support one neutral/quiet recipe. Other combinations normalize the properties and reflected attributes to intent="neutral" treatment="quiet" and produce a developer diagnostic. The action remains available. Returning to default or inverse keeps those normalized values; set a different intent and treatment explicitly when you want another ordinary appearance.

Handle unavailable and waiting actions

Use disabled when an action cannot be invoked. Use pending after an action starts, and supply a localized pending-label describing the work in progress. Set the label before entering pending; it is captured once per pending entry, and later label changes apply to the next entry:

<jangle-button id="save-button" pending-label="Saving changes">Save changes</jangle-button>

Here, saveChanges() is application-owned async work; replace it with the request or client logic for your product:

const saveButton = document.querySelector('#save-button');

saveButton.addEventListener('click', async () => {
  saveButton.pending = true;

  try {
    await saveChanges();
  } finally {
    saveButton.pending = false;
  }
});

Pending keeps the Button's focus, size, and accessible name while blocking repeat activation. The application still owns the operation, completion, failure, recovery message, and any later focus movement.

Submit a form

Button defaults to type="button" to avoid accidental submission. Set type="submit" or type="reset" when you want the corresponding browser behavior. Submitter names and values work as they do on a native button:

<form id="profile-form">
  <!-- Application-owned fields -->
  <jangle-button type="submit" name="action" value="save" intent="brand" treatment="strong">
    Save profile
  </jangle-button>
</form>

Omit formaction, formenctype, formmethod, and formtarget to inherit the form settings. Setting an override attribute or its JavaScript property overrides that setting for this submitter; removing the attribute restores inheritance.

Button uses a transparent native button bridge to preserve validation, implicit Enter submission, reset, and submitter data. That bridge is the real SubmitEvent.submitter. Pass it to FormData, and use closest('jangle-button') when you need the owning component:

const form = document.querySelector('#profile-form');

form.addEventListener('submit', (event) => {
  event.preventDefault();

  const button = event.submitter?.closest('jangle-button');
  const data = new FormData(form, event.submitter);
});

form.requestSubmit(jangleButton) is not supported. Call jangleButton.click() for Button's guarded programmatic activation.

Explore the complete reference

Open Button in the public Storybook for interactive controls, every supported property, visual combinations, accessibility guidance, and working state and form examples. Storybook is public and does not require a Jangle UI account.

On this page