UI kit
ui marketplace package (tibi plugin add ui) ships accessible components built on the platform: <dialog> for modals, the Popover API for floating panels (top layer, light dismiss, Esc), and native inputs rendered in the light DOM so they submit with forms, autofill and bind with t-bind. Everything is a <Ti…> tag; lists and callbacks are passed as value props (.items="list").Try it
Esc or the backdrop closes it.
Components
<TiButton>:variant(solid, outline, soft, ghost, link),color(primary, neutral, success, warning, error),size(xs, sm, md, lg),href,type,block,loading,disabled.type="submit"submits the enclosing form.<TiModal>:heading(use it rather thantitle, which also shows as a browser tooltip over the whole dialog),description,open,fullscreen,dismissible,backdrop="static"(backdrop clicks don't close it); slotstrigger, default,footer;host.show()/close()/toggle(); eventsopen,close; width from--ti-modal-width(32rem by default).<TiPopover>:side,align,mode(click, hover),open; slotstriggerand default.<TiTooltip>:text,side,delay(ms),disabled.<TiDropdownMenu .items>: items{ label, href?, color?, disabled?, kbd?, style?, onSelect?, items? }(stylestyles the label), or groups (an array of arrays); eventselect. An item withitemsopens a submenu beside it (hover, click or ArrowRight; ArrowLeft or Esc goes back). Arrow keys, Home / End, Enter, Esc.<TiSelectMenu .items>: strings or{ label, value, disabled? };value,multiple,searchable,placeholder,name(hidden inputs for form submission),disabled; eventchange;host.value.<TiForm .validate>: runs native constraint validation and yourvalidate(values)(sync or async, returning{ field: message }), puts messages on the matching<TiFormField name>, then emitssubmitwith{ values, formData, form }orinvalid.disableddisables every control.<TiFormField>:label,name,description,hint,error,required,size. Wires the label to its control and clears the error as the user types.<TiInput>: every native input attribute that matters (type,name,value,placeholder,required,min/max,pattern, …) plussizeandvariant(outline, soft, ghost).<TiCheckbox>,<TiPinInput length otp>(emitscomplete),<TiColourPicker .swatches>,<TiDateTimePicker mode>(host.valueAsDate,host.iso; zoned ISO values convert to the visitor's local time).<TiNavigationMenu .items orientation>: marks the current page witharia-current(longest matching path;exactper item) and follows client-side navigation.<TiAlert>:color,variant(soft, solid, outline),title,description,dismissible; slotsicon, default,actions.<TiSeparator orientation label>.- Toasts live in the separate
toastpackage (<TiToastHost/>pluswindow.tibi.toast.show()).
A form
Theming
Components read CSS custom properties with sensible fallbacks: --ti-primary (falls back to --brand), --ti-neutral, --ti-success, --ti-warning, --ti-error, --ti-info, --ti-surface, --ti-on-surface (text on the surface: menus, popovers, modals and fields; inherits when unset), --ti-border, --ti-border-strong, --ti-muted, --ti-radius, --ti-radius-lg, --ti-tooltip-bg, --ti-tooltip-fg. Set them on :root in your global CSS.
examples/ui-kit in the Tibi repo uses every component on one page.