Input
AtomText input field with label, hint, error, prefix icon, password toggle, and 3 size variants.
<%- include('modules/ui/Input', { id: 'email', label: 'Email address', placeholder: 'you@example.com' }) %>
<%- include('modules/ui/Input', { id: 'name', label: 'Full name', required: true, placeholder: 'Jane Doe' }) %>
Letters, numbers and underscores only
<%- include('modules/ui/Input', { id: 'user', label: 'Username', hint: 'Letters, numbers and underscores only' }) %>
Enter a valid email address
<%- include('modules/ui/Input', { id: 'email', label: 'Email address', error: 'Enter a valid email address' }) %>
<%- include('modules/ui/Input', { id: 'acc', label: 'Account ID', disabled: true }) %>
<%- include('modules/ui/Input', { id: 'pw', label: 'Password', type: 'password', placeholder: '••••••••' }) %>
<%- include('modules/ui/Input', { id: 'search', label: 'Search', iconLeft: '', placeholder: 'Search…' }) %>
<%- include('modules/ui/Input', { id: 'sm', label: 'Small', size: 'sm' }) %>
<%- include('modules/ui/Input', { id: 'md', label: 'Medium', size: 'md' }) %>
<%- include('modules/ui/Input', { id: 'lg', label: 'Large', size: 'lg' }) %>
<%
var _id = locals.id || 'input-' + Math.random().toString(36).substr(2, 9);
var _type = locals.type || 'text';
var _val = (locals.value !== undefined && locals.value !== null) ? String(locals.value) : '';
var _dis = !!locals.disabled;
var _req = !!locals.required;
var _ro = !!locals.readOnly;
var _isPassword = (_type === 'password');
var _isNumber = (_type === 'number');
var _state = locals.error ? 'error' : (locals.success ? 'success' : 'default');
var _hasPrefix = !!locals.iconLeft;
var _hasClear = !!locals.clearable && _val.length > 0 && !_ro && !_isPassword;
var _hasSuffix = !!locals.iconRight || _hasClear || _isPassword;
var _hintId = (locals.hint && !locals.error && !locals.success) ? (_id + '-hint') : '';
var _errorId = locals.error ? (_id + '-error') : '';
var _successId = (locals.success && !locals.error) ? (_id + '-success') : '';
var _describedBy = [_hintId, _errorId, _successId].filter(function (x) { return !!x; }).join(' ');
var inputBaseClass = 'block w-full rounded-md border px-3 py-2 text-sm transition-colors '
+ 'text-text-primary placeholder:text-text-disabled '
+ 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus '
+ 'disabled:opacity-50 disabled:cursor-not-allowed disabled:bg-surface-sunken '
+ 'read-only:bg-surface-sunken read-only:cursor-default ';
if (_state === 'error') {
inputBaseClass += 'border-error ring-1 ring-error bg-error-subtle ';
} else if (_state === 'success') {
inputBaseClass += 'border-success ring-1 ring-success bg-success-subtle ';
} else {
inputBaseClass += 'border-border bg-surface-base ';
}
if (_hasPrefix) inputBaseClass += 'pl-9 ';
if (_hasSuffix || _isNumber) inputBaseClass += 'pr-9 ';
if (_isNumber) {
inputBaseClass += '[appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none ';
}
var _charCount = _val.length;
var _showCount = !!locals.showCount && !!locals.maxLength;
%>
<% if (_hasPrefix) { %>
<%- locals.iconLeft %>
<% } %>
placeholder="<%= locals.placeholder %>"<% } %>
<% if (_val) { %>value="<%= _val %>"<% } %>
<% if (locals.name) { %>name="<%= locals.name %>"<% } %>
<% if (_dis) { %>disabled<% } %>
<% if (_req) { %>required<% } %>
<% if (_ro) { %>readonly<% } %>
<% if (locals.maxLength) { %>maxlength="<%= locals.maxLength %>"<% } %>
<% if (locals.step !== undefined) { %>step="<%= locals.step %>"<% } %>
<% if (locals.min !== undefined) { %>min="<%= locals.min %>"<% } %>
<% if (locals.max !== undefined) { %>max="<%= locals.max %>"<% } %>
aria-invalid="<%= _state === 'error' ? 'true' : 'false' %>"
<% if (_describedBy) { %>aria-describedby="<%= _describedBy %>"<% } %>
data-testid="input-<%= _id %>"
>
<% if (_isPassword && !_ro) { %>
<% } %>
<% if (_hasClear) { %>
<% } %>
<% if (locals.iconRight && !_hasClear && !_isPassword) { %>
<%- locals.iconRight %>
<% } %>
<% if (_isNumber && !_ro) { %>
<% } %>
<% if (_hintId) { %><%= locals.hint %>
<% } %>
<% if (_errorId) { %><%= locals.error %>
<% } %>
<% if (_successId) { %><%= locals.success %>
<% } %>
<% if (_showCount) { %>
<%= _charCount %>/<%= locals.maxLength %>
<% } %>
<% if (_isPassword || _isNumber || locals.clearable) { %>
<% } %>