You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Native-like .value, .name, .checked, .type properties for uniform form handling
Date format: yyyy-mm-dd throughout
Attributes are reactive — changes after render are reflected automatically
<th-button>
A button with four visual variants, loading state, ripple effect, and optional link mode.
Attributes
Attribute
Type
Default
Description
variant
string
"filled"
One of: filled, tonal, outlined, ghost
size
string
—
"small", "large", or omit for medium
disabled
boolean
—
Disables the button
loading
boolean
—
Shows spinner, disables interaction
href
string
—
When set, renders an <a> instead of <button>
target
string
—
Link target (only when href is set)
rel
string
—
Link rel (only when href is set)
download
string
—
Link download (only when href is set)
type
string
—
Button type attribute ("submit", "reset", "button")
name
string
—
Button name
value
string
—
Button value
form
string
—
Associated form ID
autofocus
boolean
—
Auto-focus on mount
Slots
Slot
Description
default
Button label text
"icon"
Icon element. When only icon is present (no text), the button renders as a square icon-only button
CSS Shadow Parts
Part
Element
button
The inner <button> or <a>
content
<span> wrapping the slots
loader
Loading spinner <span>
Examples
<th-button>Filled</th-button><th-buttonvariant="tonal">Tonal</th-button><th-buttonvariant="outlined">Outlined</th-button><th-buttonvariant="ghost">Ghost</th-button><th-buttonsize="small">Small</th-button><th-buttonsize="large">Large</th-button><th-buttonloading>Saving...</th-button><th-buttondisabled>Disabled</th-button><!-- Link mode --><th-buttonhref="https://example.com" target="_blank">Link</th-button><!-- Icon-only --><th-button><svgslot="icon">...</svg></th-button>
<th-field>
A form field with label, input/textarea/date picker, built-in validation, and error display.
Attributes
Attribute
Type
Default
Description
label
string
—
Field label text
type
string
"text"
One of: text, email, number, date, textarea
value
string
—
Current input value
name
string
—
Field name for form serialization
placeholder
string
—
Placeholder text
required
boolean
—
Marks as required (shows * in label)
disabled
boolean
—
Disables the input
readonly
boolean
—
Makes input read-only
minlength
number
—
Minimum text length
maxlength
number
—
Maximum text length
rows
number
3
Textarea row count (only when type="textarea")
min
string
—
Minimum value (for number/date types)
max
string
—
Maximum value (for number/date types)
pattern
string
—
Regex pattern for validation
autocomplete
string
—
Autocomplete hint
autofocus
boolean
—
Auto-focus on mount
error
string
—
Sets an error message (overrides validation). Remove attr to clear
Note: When type="date", the built-in input is type="text" with maxlength="10" (for yyyy-mm-dd format) and a custom calendar popup. Validation checks the date format, real date existence, and optional min/max constraints.
Properties
Property
Type
Get/Set
Description
.value
string
get/set
Current input value
.name
string
get
Field name attribute
.disabled
boolean
get/set
Whether the field is disabled
.readonly
boolean
get/set
Whether the field is read-only
.required
boolean
get/set
Whether the field is required
Methods
Method
Returns
Description
.checkValidity()
boolean
Returns whether the input passes validation
.reportValidity()
boolean
Checks validity and shows error message if invalid
.setCustomValidity(msg)
void
Sets a custom validation error. Pass empty string to clear
.focus()
void
Focuses the inner input/textarea
Events (native, delegated from inner <input>/<textarea>)
Event
Description
input
Fires on every value change (bubbles)
change
Fires when value is committed (bubbles)
invalid
Fires when validation fails
Slots
Slot
Description
default
Replaces the built-in <input>/<textarea> with a custom element (the custom element must have .value and support the expected attributes). When type="textarea", light DOM text content is consumed as the initial value
"label"
Replaces the label text
CSS Shadow Parts
Part
Element
field
Outer container
label
<label> element
input
The <input> or <textarea>
error
Error tooltip <span>
date-btn
Calendar toggle button (only when type="date")
calendar
Date picker popup (only when type="date")
Examples
<!-- Text input --><th-fieldlabel="Name" name="username" placeholder="Enter your name"></th-field><!-- Email with validation --><th-fieldlabel="Email" type="email" name="email" required></th-field><!-- Number --><th-fieldlabel="Age" type="number" name="age" min="0" max="150"></th-field><!-- Date picker --><th-fieldlabel="Date" type="date" name="date"></th-field><!-- Textarea with slot content consumed as initial value --><th-fieldlabel="Bio" type="textarea" name="bio" rows="5"><p>Existing content</p></th-field><!-- Pre-filled value --><th-fieldlabel="City" value="Shanghai"></th-field><!-- With error --><th-fieldlabel="Password" type="password" error="Too short"></th-field><!-- Disabled --><th-fieldlabel="Readonly" value="Immutable" disabled></th-field><!-- Using slot for label --><th-fieldname="email"><spanslot="label">Email Address</span></th-field>
<th-check>
Checkbox or radio button with custom styling.
Attributes
Attribute
Type
Default
Description
type
string
"checkbox"
Either "checkbox" or "radio"
checked
boolean
—
Whether the element is checked
disabled
boolean
—
Disables interaction
name
string
—
Group name (radio buttons with same name auto-uncheck each other)
The selected attribute on an <option> sets the initial value.
CSS Shadow Parts
Part
Element
select
Outer container
label
<label> element
trigger
Clickable trigger bar
value
Value display <span>
panel
Dropdown panel
error
Error message <span>
Keyboard navigation
Key
Action
Enter / Space
Open dropdown, or confirm highlighted option
Escape
Close dropdown
ArrowDown
Highlight next option (opens if closed)
ArrowUp
Highlight previous option (opens if closed)
Examples
<th-selectlabel="Country" name="country"><optionvalue="cn">China</option><optionvalue="us" selected>United States</option><optionvalue="jp">Japan</option></th-select><!-- With placeholder --><th-selectlabel="City" placeholder="Select a city..."><optionvalue="shanghai">Shanghai</option><optionvalue="beijing">Beijing</option></th-select><!-- Programmatic --><script>constsel=document.querySelector('th-select');sel.value='jp';console.log(sel.value);// 'jp'sel.addEventListener('change',(e)=>console.log(e.detail));</script>
<th-dialog>
A modal dialog with overlay, title, body, and footer slot.
Attributes
Attribute
Type
Default
Description
open
boolean
—
Whether the dialog is visible
title
string
—
Dialog title text
closable
boolean
true
Whether Escape key can close the dialog
width
number
—
Fixed dialog width in pixels (overrides CSS default)
Methods
Method
Description
.open()
Opens the dialog (sets open attribute)
.close()
Closes the dialog with animation (removes open attribute)
Slots
Slot
Description
default
Dialog body content
"footer"
Footer buttons. When empty, the footer is hidden. Buttons are styled automatically
CSS Shadow Parts
Part
Element
overlay
Fixed full-screen overlay
dialog
Dialog panel
title
Title bar
body
Body content area
footer
Footer area
Behavior
Body scroll is prevented while open (wheel + touchmove)
Escape key closes the dialog (unless closable="false")
Clicking the overlay does NOT close the dialog
Examples
<th-dialogid="myDialog" title="Confirm"><p>Are you sure?</p><buttonslot="footer">OK</button><buttonslot="footer">Cancel</button></th-dialog><script>document.querySelector('#myDialog').open();</script>
<th-toast>
A fixed-position toast notification. Auto-removes after a duration. Multiple toasts stack vertically.
Attributes
Attribute
Type
Default
Description
type
string
"info"
One of: info, warn, error, success
duration
number
3
Display duration in seconds
Methods
Method
Description
.close()
Closes the toast immediately and dispatches a close event
After the script loads, Thyme is available globally.
Dialogs
Thyme.alert('Hello World');Thyme.alert('File deleted','Warning');// Returns Promise<boolean>constok=awaitThyme.confirm('Delete this item?');if(ok){/* proceed */}
Toast notifications
Thyme.info('Loading...');Thyme.success('Done!',2);// 2 secondsThyme.warn('Low disk space',5);// 5 secondsThyme.error('Something broke',10);// 10 seconds
Locale / i18n
Thyme.locale='zh';// switch to ChineseThyme.locale='en';// switch to English
Form utilities
// Serialize a form scope to an object.// Returns null if ANY field fails checkValidity() — the first// invalid field receives focus and shows its error message.constdata=Thyme.form.getJsonObject('#my-form');// or pass an element:constdata=Thyme.form.getJsonObject(document.querySelector('#my-form'));// Serialize multiple form scopes to an array.// Returns null if ANY scope's validation fails.constall=Thyme.form.getJsonArray('.form-scope');// or pass a NodeList:constall=Thyme.form.getJsonArray(document.querySelectorAll('.form-scope'));// Populate a form from an objectThyme.form.setJsonObject('#my-form',{username: 'admin',age: 25});// Typical submit guard:constdata=Thyme.form.getJsonObject('#my-form');if(data===null)return;// validation failed, already focusedawaitfetch('/api/submit',{method: 'POST',body: JSON.stringify(data)});
Rules for serialization (getJsonObject / getJsonArray):
Only elements with a name attribute are included
Unchecked checkboxes / radio buttons / switches are skipped
Checkboxes with the same name or <select multiple> are collected into an array
contentEditable elements use trimmed innerHTML
User-input elements (native <input>/<textarea>, <th-field>) have their value trimmed and written back to the element
Selection elements (<select>, <th-select>, <th-check>, <th-switch>, radio buttons) are stored as-is
On any checkValidity() failure, getJsonObject returns null immediately — the first invalid field is focused and shows its error
setJsonObject populates elements by matching [name] attributes. Handles all the same element types including <select multiple>, checkbox arrays, radio groups, and contentEditable.
HTTP client
Thyme.http wraps fetch() with JSON handling, response type detection, and error reporting.
The response body is parsed automatically based on Content-Type:
Content-Type
Parsed as
text/*
response.text()
application/json
response.json()
Everything else
response.blob()
Non-OK status codes (4xx/5xx) throw an Error with the parsed server message.
Error handling
try{awaitThyme.http.get('/api/data');}catch(e){console.error(e.message);// server error message or "Unknown error"}
Errors are also passed to Thyme.error() automatically.
Utility functions
Thyme.utils.delay(1000);// Promise that resolves after 1sThyme.utils.nanoId();// Random 24-char ID (0-9a-zA-Z)Thyme.utils.nanoId(8);// Random 8-char IDThyme.utils.formatDate(newDate(),'yyyy-MM-dd');// "2026-05-15"Thyme.utils.formatDate(newDate(),'yyyy-MM-dd hh:mm:ss');// "2026-05-15 14:30:00"Thyme.utils.formatDate(newDate(),'MM/dd/yyyy',true);// "05/15/2026" in UTCThyme.utils.formatDecimal(3.14159,2);// 3.14Thyme.utils.formatMoney(1234567.89);// "1,234,567.89"Thyme.utils.formatBytes(1048576);// "1 MiB"Thyme.utils.parseDuration('01:30:00');// 5400 (seconds)Thyme.utils.formatSeconds(3661);// "1h 1m 1s"Thyme.utils.base64Encode('hello');// "aGVsbG8="
Theming
Set these CSS custom properties on any ancestor element — they inherit through Shadow DOM:
:root {
--th-primary:#3730a3; /* Primary color, default: indigo-800 */--th-radius:8px; /* Border radius, default: 8px */--th-font-size:14px; /* Base font size */--th-line-height:1.5; /* Base line height */
}
All derived colors (hover, ripple, border, focus ring) are computed automatically from --th-primary via color-mix() — no additional variables needed.
Styling via ::part()
Each component exposes CSS shadow parts for granular styling: