Monsoon v0.2.0
Made by Alexandre Kohler Star

Two factor and sign in

Phone number

Phone number with a country picker: a searchable list with flags and dial codes, formatting as you type for the selected country, typing or pasting +44 or 0044 switches the country, and a hidden field with the E.164 number. Without the script the native select and tel input still work. Needs monsoon.js.

Two factor and sign in13 classesNeeds monsoon.jsLight and dark

Needs monsoon.js. The styles work on their own, and the behavior comes from the optional interactive layer: add <script src="https://cdn.jsdelivr.net/npm/monsooncss/dist/monsoon.js" defer></script> or import 'monsooncss/js'. See the interactive layer.

Example

Full

JavaScript API

Attribute

data-m-auth-phone

Options

OptionDescription
data-m-auth-phone-name="phone_e164" (hidden input with +15550100123)
data-m-auth-phone-countries="US,BR,GB,PT" (limit the list)

Methods

MethodDescription
Monsoon.authPhone(el).value (country, dial, national, e164, valid)
Monsoon.authPhone(el).country = "BR"
Monsoon.authPhone(el).open()
Monsoon.authPhone(el).close()

Events

EventDescription
monsoon:auth-phone { country, dial, national, e164, valid }

Classes

13 classes. Click a name to copy it. Utilities on the same element always win over component defaults, so any of them can be adjusted with plain utility classes.

ClassTypeWhat it does
Base Base class of the phone number. On a <div> in the example. Sets flex display and width.
CSS
.phone-input {
  position: relative;
  display: flex;
  width: 100%;
  min-width: 0;
}
Part Part of the phone number. On a <select> in the example. Sets alignment, width, corner radius and padding.
CSS
.phone-input-select {
  padding-inline-end: 2rem;
}

.phone-input-select, .phone-input-country {
  flex: none;
  width: auto;
  border-start-end-radius: 0;
  border-end-end-radius: 0;
}
Part Part of the phone number. On an <input> in the example. Sets alignment, width, margin, corner radius and stacking order.
CSS
.phone-input-field:focus {
  z-index: 1;
}

.phone-input-field {
  flex: 1;
  min-width: 0;
  margin-inline-start: calc(-1 * var(--m-border-width));
  font-variant-numeric: tabular-nums;
  border-start-start-radius: 0;
  border-end-start-radius: 0;
}
Modifier Modifier, combined with the phone-input class. Not used in the example above. Sets alignment, width, corner radius, inline-flex display, gap and height.
CSS
.phone-input-country[aria-expanded=true]::after {
  rotate: 180deg;
}

.phone-input-country:hover {
  background-color: color-mix(in oklab, var(--surface-2), var(--foreground) 4%);
}
Modifier Modifier, combined with the phone-input class. Not used in the example above. Sets block display, alignment, width, height, overflow and corner radius.
CSS
.phone-input-flag {
  display: block;
  flex: none;
  width: 1.375rem;
  height: .9375rem;
  overflow: hidden;
  border-radius: 3px;
  box-shadow: 0 0 0 1px color-mix(in oklab, var(--foreground) 14%, transparent);
}
Modifier Modifier, combined with the phone-input class. Not used in the example above. Sets grid display, alignment, text size, font weight, text style and text color.
CSS
.phone-input-code {
  display: grid;
  place-items: center;
  font-size: .5625rem;
  font-weight: 700;
  letter-spacing: .02em;
  color: var(--muted-foreground);
  background-color: var(--muted);
}
Modifier Modifier, combined with the phone-input class. Not used in the example above. Sets text color.
CSS
.phone-input-dial {
  font-variant-numeric: tabular-nums;
  color: inherit;
}

.phone-input-option[aria-selected=true] > .phone-input-dial {
  color: var(--primary);
}
Modifier Modifier, combined with the phone-input class. Not used in the example above. Sets absolute position, offsets, stacking order, grid display, gap and width.
CSS
.phone-input-menu[hidden] {
  display: none;
}

.phone-input-menu {
  position: absolute;
  top: calc(100% + .375rem);
  inset-inline-start: 0;
  z-index: 50;
  display: grid;
  gap: .25rem;
  width: min(20rem, 100%);
  min-width: min(16rem, 100vw - 2rem);
  padding: .375rem;
  background-color: var(--surface);
  border: var(--m-border-width) solid var(--border);
  border-radius: var(--m-radius-xl);
  box-shadow: var(--m-shadow-lg);
  animation: m-auth-drop .18s var(--m-ease);
}
Modifier Modifier, combined with the phone-input class. Not used in the example above. Sets height, margin, padding and overflow.
CSS
.phone-input-list {
  max-height: 15rem;
  margin: 0;
  padding: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  list-style: none;
}
Modifier Modifier, combined with the phone-input class. Not used in the example above. Sets grid display, grid tracks, alignment, gap, padding and text size.
CSS
.phone-input-option[aria-selected=true] {
  font-weight: 600;
}

.phone-input-option[aria-selected=true] > .phone-input-dial {
  color: var(--primary);
}
Modifier Modifier, combined with the phone-input class. Not used in the example above. Sets overflow and text style.
CSS
.phone-input-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
Modifier Modifier, combined with the phone-input class. Not used in the example above. Sets margin, padding, text size, text style and text color.
CSS
.phone-input-empty {
  margin: 0;
  padding: .75rem;
  font-size: .8125rem;
  text-align: center;
  color: var(--muted-foreground);
}

Usage

The styles ship inside the same stylesheet as the utilities, and the behavior comes from the optional monsoon.js script, which enhances any element with a matching data-m attribute, including markup added later.

index.html
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/monsooncss">
<script src="https://cdn.jsdelivr.net/npm/monsooncss/dist/monsoon.js" defer></script>

<!-- Phone number: start from the base class, then add modifiers -->
<form class="grid gap-5 max-w-sm" action="#" onsubmit="event.preventDefault()">
  <div class="field">
    <label class="label" for="mfa-phone">Mobile number</label>
    <div class="phone-input" data-m-auth-phone data-m-auth-phone-name="phone_e164">
      <select class="phone-input-select select" name="country" aria-label="Country">
        <option value="US">United States (+1)</option>
        <option value="BR" selected>Brazil (+55)</option>
        <option value="GB">United Kingdom (+44)</option>
        <option value="PT">Portugal (+351)</option>
        <option value="DE">Germany (+49)</option>
        <option value="IN">India (+91)</option>
      </select>
      <input id="mfa-phone" class="phone-input-field input" type="tel" name="phone" value="11987650474" autocomplete="tel-national" aria-describedby="mfa-phone-hint">
    </div>
<!-- the full example is in the Code tab above -->

Theme it with --seed on any ancestor, for example style="--seed: #0d9488", and force a scheme with class="dark" or class="light" on a wrapper.

Accessibility

  • Give every control a visible label linked with for, or an aria-label when the purpose is obvious from context. Link help and error text with aria-describedby; invalid styles use :user-invalid, so they appear only after the user interacts.
  • Every interactive part shows a visible focus ring with :focus-visible, and tone colors pair with -foreground tokens that keep text at 4.5:1 or better in light and dark mode.

No recent searches

Try , , or .

Recent

Loading the search index

No results for ""

Check the spelling, or search a class name such as px-4.