brumate/ui
Accessible, unstyled components for brumate. They resume like the rest of a brumate page: a part ships no code until someone uses it.
- Button
Pressed 0 times.
Presses with a pointer, a key or a screen reader.
- ToggleButton
Not pinned.
A button that stays pressed.
- ToggleButtonGroup
Aligned left.
Toggle buttons with one selection or several.
- Link
A link that presses as a button does.
- FileTrigger
No files yet.
Opens the file picker from a button.
- DropZoneDrop or paste text or files here
An area that takes drops and pastes of text and files.
- TextField
A labeled input, checked by the browser.
- SearchField
Press Enter to search, Escape to clear.
A search input that Escape clears.
- Checkbox
A native checkbox, with a box of your own.
- CheckboxGroupYou picked 1.
Checkboxes with one value.
- RadioGroup
Size: medium.
Native radios that the arrow keys move.
- Switch
A setting that applies at once.
- Form
Validation, and the errors of the server.
- Dialog
The content of an overlay, named by its title.
- Popover
An overlay beside its trigger, with layers inside.
- Modal
A dialog over the page, which it locks.
- Sheet
A modal along an edge of the window.
- Tooltip
A short description of a button, on hover and focus.
- PreviewTrigger
Written byAda Lovelacein 1843.
A preview of a link, on hover, focus and a long press.
- Toast
A notice that comes and goes, in a landmark.
- NumberField
2 guests, a budget of 120.
A field for a number, in the format of the locale.
- Slider
Volume 40, from 200 to 800.
A value, or a range of values, on a track.
- ColorPicker
The color is hsb(210, 80%, 90%).
One color, shared by the color parts inside it.
- ColorSwatch
A sample of a color, named for screen readers.
- ColorSlider
The color is hsl(210, 80%, 50%).
A slider for one channel of a color.
- ColorArea
The color is hsb(210, 80%, 90%).
Two channels of a color on a plane.
- ColorWheel
The color is hsl(210, 80%, 50%).
A circular track for the hue of a color.
- ColorField
A field for a color, as hex or as one channel.
- ColorSwatchPicker
#e2445a
A list of color swatches, to pick one.
- Calendar
Delivery date, October 2026
October 2026
S M T W T F S 2728293012345678910111213141516171819202122232425262728293031Delivery on no date yet.
The days of a month, to pick a date.
- RangeCalendar
Stay, October 2026
October 2026
S M T W T F S 2728293012345678910111213141516171819202122232425262728293031Pick the first night, then the last.
The days of a month, to pick a range of dates.
- DateFieldmmddyyyyType it, or use the arrow keys.
No date yet.
A date that the user types segment by segment.
- TimeField930AM
09:30
A time of day that the user types segment by segment.
- DatePickermmddyyyy
No date yet.
A date field with a button that opens a calendar.
- DateRangePickermmddyyyymmddyyyy
No range yet.
Two date fields and a button that opens a range calendar.
- ListBox
Mammals AardvarkCatDogKangarooBirds KiwiPenguinRobinSelected: cat.
A list of options to select, by keyboard and pointer.
- Menu
Last action: nothing yet. Sorted by name.
Actions and options that open from a button, with submenus.
- SelectPick the one you like best.
Selected: none.
A field that picks one item from a list.
- ComboBox
Selected: none.
A text field with a list of suggestions that filters as you type.
- Autocomplete
Last command: nothing yet.
A search field that filters a menu or a list next to it.
- TabsMercuryVenusEarthThe closest planet to the Sun.
Tabs that show one panel at a time.
- TagGroupNewsTravelGamingShoppingMusic
Selected: Travel.
Tags that the user can select and remove.
- GridListNotes.txtPhotosBudget.xlsxMusic
Selected: none. Opened: nothing yet.
Rows with buttons and checkboxes, to select and act on.
- Table
Name Kind Size (kB) Beach.jpg Image 2400 Budget.xlsx Sheet 48 Notes.txt Text 3 Song.mp3 Audio 5100 Selected: none.
Rows and columns that the user can select and sort.
- TreeDocumentscv.pdfWorkPhotosnotes.txt
Selected: none. Open: docs.
Rows that nest and open and close, such as files in folders.
- NavigationTree
A tree of links that shows the page that the user is on.
- TokenFieldAsk @ada about #launchType a @name or a #tag, then a space.
Tokens: @ada, #launch.
Text with mentions and tags that the user types.
- VirtualizerPhoto 0001.jpgPhoto 0002.jpgPhoto 0003.jpgPhoto 0004.jpgPhoto 0005.jpgPhoto 0006.jpgPhoto 0007.jpgPhoto 0008.jpgPhoto 0009.jpgPhoto 0010.jpgPhoto 0011.jpgPhoto 0012.jpgPhoto 0013.jpgPhoto 0014.jpgPhoto 0015.jpgPhoto 0016.jpgPhoto 0017.jpgPhoto 0018.jpgPhoto 0019.jpgPhoto 0020.jpg
Thousands of rows that render as they come into view.
- List and tree dataDocumentscv.pdfnotes.txt
Items that an app adds, moves and removes, with their selection.
- SelectionIndicatorOverviewActivitySettings and privacyThe overview view.
A mark of the selected item, which moves with the selection.
- Disclosure
Orders leave the shop in two days.
A section that expands and collapses.
- DisclosureGroup
Orders leave the shop in two days.
Send it back within thirty days.
Wash it cold, and dry it flat.
Disclosures that open one at a time.
- Breadcrumbs
A trail to the current page.
- Toolbar
The arrow keys move between its items.
- Meter
A value in a known range, in the locale.
- ProgressBar
The progress of a task.
- Group
Parts that belong together.
- Separator
Above the line.
Below the line.
A line between two parts of the content.
- TransitionThe note fades and slides as it comes and goes.
Animates content as it comes and goes.
- VisuallyHidden
Content for screen readers alone.
- Keyboard
Copy with Ctrl C.
A keyboard shortcut.
- I18nProvider
A locale and its direction for the parts.
What the parts give you
- Markup with the right roles and ARIA attributes, and native elements where the browser has them, such as
<button>,<input type="checkbox">and<a>. - Keyboard, pointer and screen reader behavior, the same for a mouse, a touch, a key and a screen reader.
- State as
data-*attributes, such asdata-pressedanddata-selected, for your CSS. - No styles. The demos on these pages use the style of this site. See Styling.
Use a part
Import a part from @brumate/ui, and use it as any component:
<script>
import Button from '@brumate/ui/Button.brm';
import { $signal } from 'brumate/signals';
let count = $signal(0);
</script>
<Button class="button" onPress=(() => count++)>Pressed {count} times</Button>
- The page renders on the server, with the markup of the part.
- The first press loads the code of the part and of your handler.
- Without scripts, a native element still works: a link follows, a box checks, and a form posts.
Note
@brumate/ui is in the brumate repository, and is not published yet.
How the parts work together
A part that holds other parts gives them their IDs and state through a context. A TextField names its Label, Input and FieldError for each other:
<TextField name="email" type="email" isRequired>
<Label>Email</Label>
<Input />
<Text slot="description">We send the receipt here.</Text>
<FieldError />
</TextField>
slotpicks between parts of one type, such asText slot="description".- State such as
isSelectedorvalueis one prop. A value starts the part's own copy, and$bindwrites yours. See State.
Browser support
A part uses a feature of the platform only when at least 95% of global usage supports it. So the parts use inert, :focus-visible and checkVisibility(), and not the Popover API, @starting-style or CSS anchor positioning.