Repository navigation
v0.3.0
Upgrading with a coding agent? Point it at the LLM upgrade notes.
Breaking
- The default theme is redesigned. Surfaces are white plates on a grey stage, every neutral is derived from the foreground color, every control shares one radius, and filled buttons are lit. Explicit themes keep their colors, and every theme picks up the new shapes and motion.
- The default fonts are Inter Tight and Geist Mono instead of Manrope and JetBrains Mono.
ui.cssimports them from@fontsource/inter-tightand@fontsource/geist-mono, and the package no longer depends on the old two. - Text weight stops at 500.
font-semiboldandfont-boldresolve to 500, and--font-weight-headeris 500. Build hierarchy from size and color, or set--font-weight-semiboldand--font-weight-boldback to 600 and 700. --color-border,--color-border-strong, and--color-inputare translucent mixes of the foreground instead of opaque greys. A theme that setsfoundation.borderkeeps its own color.- Two-layer surfaces swap their layers. The frame is now the card color and the inner surface is the page background, so content in an inset Card, a Dialog, a CodeBlock, or a Composer sits on the recessed stage color with white fields on top.
- The default edge highlight is 33% instead of 50%. Borders stay single and cards and menus stay without shadows, as before.
- The radius scale changes.
--radius-xlis 18px instead of 20px, plates use the new--radius-2xl(26px), and controls use the new--radius-control: 4px in the sharp scale, 12px in the default scale, and a pill in the rounded scale. Buttons were 14px before. - Primary, secondary, and destructive buttons are lit like
glow. Outline is flat: a hairline on the field color with no inset shading. - The primary button's text is dark on the default brand in light mode as well as dark, so it passes contrast.
--color-on-primaryis#21151ein both. - Text fields, native selects, select and combobox triggers, and number fields take
--radius-controllike buttons. Textarea and TagInput use--radius-xl. - The focus ring is 3px at half the primary color instead of 2px at 80%.
- Menus, selects, and popovers spring open in 220ms from their trigger's side and close on a 100ms fade. Dialogs pop from 96% scale in 400ms and leave in 150ms. The blur on both is gone.
--motion-duration-panel-in,--motion-duration-modal-in, and the menu and modal offset tokens have new defaults. - ToggleGroup sits in a segmented track, so it is two spacing units taller and wider. Its selected item is a lit fill that glides between items.
- Table's default variant has no outer frame or header fill.
variant="inset"and DataTable put the header and footer on the frame and the rows on a recessed surface. - Alert is one notice strip. Status variants tint the icon only, with no colored fill or border.
- ScrollArea no longer shows chevrons at an edge with more content.
showCuesfades the edge instead, and the thumb stays hidden until hover, focus, or scroll. - Composer is a recessed frame holding a white writing surface. Its focus ring shows only while the textarea is focused.
- The default Toolbar paints a grey track behind its keys.
- Badges take
--radius-controlinstead of a pill, and status variants have no colored border. - Tag Input renders its tags as secondary badges instead of outline badges.
- The Checkbox card row (
variant="card", formerlyprimary) no longer tints with the primary color. - Collapsible content is muted and inset to line up with its trigger text.
- Breadcrumb items are padded, so the trail's text starts one item padding further in.
- Tooltips reposition instantly when the pointer moves to the next trigger instead of gliding there.
- Switch thumbs no longer stretch while pressed.
- Calendar, RangeCalendar, DatePicker, DateRangePicker, and OTPField parts expose their DOM node as
bind:element, like every other component.bind:refon those parts no longer works. HugeiconsIcon'srefprop iselementtoo. - The exported
PopoverStatetype losesfocusedInside,trigger,focusedElement,onclick, andhovering. Nothing read them. closeMenuLayersis no longer exported from@mielui/svelte/utils. No component used it.- The internal overlay module no longer exports
useOverlay,OverlayOptions, orparentOverlayDepth. Dialog and Sheet stopped using them when Bits UI took over focus and dismissal. - Tabs, CodeBlock, FileDiff, and the
labelsof every family share state under private keys. Code that read them withgetContext('tabs')or a similar string key getsundefined. - Button takes a
labelsobject (ButtonLabels) instead ofloadingLabel,successLabel, anderrorLabel. Menu items, select and combobox options, dialog buttons,Form.Submit, and other parts built on Button follow. - CopyButton takes
labelsinstead oflabelandcopiedLabel.CodeBlock.Copydrops both props and readscopyandcopiedfrom thelabelson CodeBlock. - ShowMore takes
labels(more,less,region) instead ofmoreLabel,lessLabel, andlabel. Command.Contentdropslabel. Name the palette withlabels.paletteonCommand.Root.- TaskSteps takes
labelsinstead oflabel. The same object translates the summary sentence. FolderCard.Countdropsunit. Set the count text withlabels.countonFolderCard.Root, which now says "1 file" for one.- DataTable's
labels.rowsandlabels.selectedreturn the whole phrase and receive the counts, so a translation can place the number.selectedalso receives the total. Composer.RootdropserrorMessage, andComposer.Submitdropslabel,queueLabel,stopLabel, andloadingLabel. PasslabelstoComposer.Rootinstead.Question.RootdropserrorMessage, andQuestion.SubmitdropslabelandloadingLabel. Uselabels.submitError,labels.submit, andlabels.submittingonQuestion.Root.Conversation.ScrollButtondropslabel. PasslabelstoConversation.Rootinstead.- Reasoning's
labels.thoughtapplies only without aduration. With a duration,labels.thoughtForsets the whole status line. AccordionContext,AlertDialogState,CollapsibleState,ContextMenuCheckboxItemState,TabsState, andToggleGroupContextare no longer exported.ContextMenu.ItemandDropdownMenu.Itemaccept onlyvariant="destructive". Menu rows no longer acceptsizeorunstyled, which they ignored.DropdownMenu.SubTriggerno longer accepts Button props it ignored, such asicon,variant,size, andunstyled.Select.Triggerno longer acceptsicon,Select.Itemno longer acceptsunstyled,Select.Valueaccepts onlyplaceholderandclass, and Slider no longer acceptschildren. None of them were used.DatePicker.Rootrenders a wrappingdivso it can exposebind:element.- Dialog and Alert Dialog no longer accept
orientation, andDialogOrientationis no longer exported.sizeon Content is now the only width control, and it accepts a newxsstep. - Popover and Combobox no longer accept
stateKeyorstate_key, andDialog.Contentno longer acceptsrole,contentClass, orpanelIdPrefix. Combobox Content no longer acceptsfocusTrap, which it ignored. Select.ItemandCombobox.Itemno longer acceptvariant,size, orunstyled, which they ignored.- TagInput's
requiredMessageis replaced bylabels.required. AlertDialog.Exitis renamedAlertDialog.Close, matching Dialog.Sheet.HeadertakesshowClosein place ofclose, matchingDialog.Content.- TagInput takes
invalidandissuesin place oferror, matchingField.Root. - Hover Card takes
placementon Root in place ofsideandalignon Content, anddelayin place ofopenDelay, matching Popover and Tooltip. - Checkbox's
variant="primary"is renamedvariant="card". - Spinner's
curvedis renamedeased.
Features
- Composer has a
Footerpart: a strip on the frame under the writing surface for hints, connected apps, or message-wide settings. - Button has a
glowvariant: a lit fill for a page's headline action, with--mielui-glow-colorand--mielui-glow-lightto change its color and brightness. ui.cssships four class contracts:mielui-platefor a resting surface,mielui-float-framefor a floating panel,mielui-glowfor the lit fill of filled actions, andmielui-glow-neutralfor the white selected fill on a track.--color-washis the one hover and selected-row fill.--mielui-glow-ringsets the outer edge of a lit control.- Four spring curves are theme tokens:
--ease-spring-panel,--ease-spring-layout,--ease-spring-pop, and--ease-spring-flick, with--motion-duration-spring,--motion-duration-pop, and--motion-duration-flick.springEasein@mielui/svelte/transitionbuilds the same curves for Svelte transitions. - Plates and frames use continuous-curvature corners where the browser supports
corner-shape: squircle. - The theme's edge highlight now scales the light on every lit control.
- Tabs, ToggleGroup, Toggle, and Pagination mark selection with a lit fill. Tabs and ToggleGroup indicators glide between items.
- Switch and Slider thumbs, the checked Checkbox and Radio, and the selected Calendar day are lit.
DropdownMenu.ItemandContextMenu.Itemrendervariant="destructive"as an error-colored row with a tinted highlight. Radio items show a dot.- A direct button or link inside Alert becomes its one action, at the end on wide layouts and last when stacked.
- SkeletonSwap lines sweep out of phase, and arriving content sharpens from a slight blur.
- Composer's send button becomes a lit stop control while streaming.
- Reasoning's label shimmers while thinking.
- Chart, pie, and heatmap tooltips and the crosshair follow the pointer on the layout spring.
- Calendar days take the control radius with a dot under today, and a selected range is a continuous wash.
- Date and color pickers open as floating panels.
- Kbd is a mono keycap and takes an inverse look inside tooltips.
- Spinner is a thin ring.
- A selected Question option takes the neutral wash instead of a primary tint, and its radio or check mark is lit.
- FolderCard is a single plate with the cover flush to its edge and a card-colored body.
- The theme's motion feel scales the spring, pop, flick, item, panel, and dialog durations together, and
--ease-draweris a theme token. - A second agent skill,
mielui-design, teaches coding agents to lay out whole pages with Mielui: app shells, dashboards, data tables, settings, chat workspaces, and marketing sites. Install it withnpx skills add mielsense/mielui --skill mielui-design. - Slider, NumberField, Dialog, Sheet, Notch, Toaster, Command, ColorPicker, Question, and Gauge take a
labelsprop that translates their built-in text and accessible names. Each exports its<Name>Labelstype; Toaster's isToastLabels. TagInputLabelsaddsadded,removed, andrequired.FileUploadLabelsaddsuploadFailed.DataTableLabelsaddsremoveFilter,done,previous, andnext.ChartLabelsaddsnoData, andHeatmapLabelsaddssummaryPending.createContextfrom@mielui/svelte/utilsreturnsfind()next toget()andset().find()returnsundefinedoutside the root instead of throwing.@mielui/svelte/utilsexports theWithElementtype, which swaps a primitive'srefprop for a bindableelement.- Button, Kbd,
Form.ErrorSummary, SkeletonSwap, CopyButton, ShowMore, TaskSteps, FolderCard, Composer, and Conversation take alabelsprop. Each exports its<Name>Labelstype. CommandLabelsaddspaletteandavailable.ToastLabelsaddscount.ColorPickerLabelsadds the trigger name and a name for each channel slider.DataTableLabelsaddsrow,selectPage, and the filter summary keys.QuestionLabelsaddssubmit,submitting,answer, andplaceholder.ReasoningLabelsaddstitle.- Chart, Heatmap, Table, Group, and NativeSelect export a prop type for every part. Select adds
SelectTriggerProps,SelectContentProps, andSelectLabelProps, and HoverCard addsHoverCardTitlePropsandHoverCardDescriptionProps. - The root entry exports every public prop, labels, and variant type, including the PieChart, EmptyState, and Notch types.
DatePicker.Rootsupportsbind:element, likeDateRangePicker.Root.
Fixes and docs
- Outline buttons inside a Group use the same border color as the inputs, text, and dividers beside them. They kept a lighter border, so the frame changed color partway around.
- Composer gives the input and its joined toolbar more padding.
- Outline buttons wrapped in a Tooltip or another trigger inside a Group take the group's border color too, so the frame no longer changes color at the wrapped button.
- The traveling highlight in menus and the command palette is measured correctly while its panel is still scaling in, so the first highlighted row is no longer too narrow after a keyboard open.
- The traveling highlight snaps to the active row for arrow keys and selection changes, and only glides for a pointer.
- Combobox results no longer animate their height on every keystroke.
- An indeterminate Progress pulses under reduced motion instead of freezing as a one-third bar.
- Tooltips scale from their trigger instead of their center.
- Toasts fade in as they rise instead of appearing at full opacity.
- Nested corners share a centre. Dialog, Sheet, Drawer, inset Card, Table, and Composer frames take their radius from the control radius plus their two-unit strip padding, menus and popovers from their rows, and CodeBlock, Toolbar, and the Reorder List handle follow the same rule.
- A closed Select or Combobox no longer intercepts clicks on whatever sits below its trigger.
- Dropdown menus, context menus, their submenus, and Select and Combobox lists keep an 8px margin from the window edge instead of sitting flush against it.
- Collapsing an Accordion, Collapsible, Reasoning, or Tool no longer logs an "Invalid keyframe value for property height" warning.
Message.Contentcaps assistant and system text at 65 characters per line, as intended. The cap was losing to a full-width class.- Closing a Dialog or Sheet from a menu item or confirmation inside it, in the same tick, no longer logs Svelte's
derived_inertwarning. - The info status color and the accent tint follow
--color-primary, so setting that one token rebrands them too. Command.Headerleaves the palette when it is removed instead of staying until the page reloads.Popover.Triggerrenders the chevron itsiconprop describes. It is off by default and turns while the popover is open.- CodeBlock keeps its gutter beside the code when
theme="custom"is combined with line numbers or an inline copy button. Toolbar.Groupstacks its items in a vertical toolbar, and vertical items share one width.- Calendar, Range Calendar, Date Picker, and Date Range Picker keep the visible month when their props change, which also stops a crash in the month and year selects when props are spread onto the root.
- Long weekday names are cut with an ellipsis instead of overlapping in the calendar header.
- A date field with
granularity="hour"no longer shows a stray "(second: 00)" after the hour. Select.Triggeracceptsaria-invalidin its type.- The placeholder and chevron on primary, destructive, and glow Select and Combobox triggers take the button's text color, so they are readable on the fill.
- A Combobox search field keeps the typed query after a pick instead of showing the picked label.
- A Textarea with a footer no longer shows the browser's resize grip inside its frame.
Group.Textmatches the height of the controls beside it in a vertical group.- Checked task items in Markdown show a tick instead of a dash.
- The Conversation scroll button no longer catches clicks while it is hidden.
- User messages are capped at 90% of the transcript width and system messages at their own measure. Both caps were losing to a full-width class.
- A selected radio and a selected Toggle Group item keep their lit edge while focused, instead of showing only the focus ring.
- A disabled radio's label shows the not-allowed cursor.
- The Reorder List handle darkens while its row is lifted.
- A tabbed CodeBlock scrolls in one place. Its panels no longer carry a second, competing height limit.
Tabs.Listacceptsid,aria-label, andaria-labelledbyin its type, andCombobox.Triggeracceptsaria-labelledby.- A standalone Label uses the same line height as the labels built into fields.
mielui add kbdinstalls the two modules Kbd imports. Its manifest left them out, so a CLI install could not compile.mielui add data-tablelists the shared context helper its parts use.- A part of Accordion, Radio Group, Toggle Group, Hover Card, Tooltip, or File Upload used outside its root throws an error that names the missing root.
Combobox.Labelno longer copies its own props onto the paragraph as HTML attributes.FileUpload.Triggershowslabels.choosewhen it has no children. It ignored the label before.- Chart tooltips, the crosshair, and the line marker appear at the hovered point instead of sliding in from the chart's corner.
- Chart, Pie Chart, and Heatmap tooltips move instantly when the keyboard drives them, and glide only for the pointer.
- Chart axes keep as many decimals as their ticks need, so 0.25 no longer reads as 0.3.
- The chart's screen-reader data table formats dates and numbers the same way as the visible chart.
- Gauge and Pie Chart read a unitless motion duration token as milliseconds instead of seconds.
- Reasoning no longer renders
data-streaming="false"while idle, so[data-streaming]selectors match only a live trace. - The Composer error notice uses the accessible error text color.
- Closed popovers no longer recompute their position on every scroll and resize.
DropdownMenu.Triggerdraws its chevron wheniconis set instead of writing aniconattribute onto the button.- File Upload adds files on pages served over plain HTTP. It threw because it relied on
crypto.randomUUID(). Group.Textrenders at the label size.Buttonstays a non-submit button whentype={undefined}is passed.- Checkbox keeps the native input in sync when an
oninputhandler cancels the change, and after a form reset. - Checkbox items inside a
ContextMenu.Subkeep their checked state after the menu closes and reopens. - Alert Dialog's Exit and Confirm buttons sit on the correct sides in right-to-left layouts.
- Link badges show the shared focus ring and use the theme's interactive cursor.
- The highlight in menus, Select, and Combobox no longer sits a fraction of a pixel off its row.
- SkeletonSwap stops its loading sweep once the placeholder is hidden, offscreen, or in a background tab.
- Tag Input tags use the theme's interactive cursor instead of always showing a pointer.
- Folder Card titles keep the same id between server and client render.
- The Toast position counter is announced to screen readers.
mielui addinstalls the peers and shared modules that Command, Data Table, Toast, Popover, Select, Radio Group, and the date pickers import, and no longer copies files they do not use.- Manifests declare the Svelte version Mielui actually requires,
^5.56.0, somielui addno longer accepts an older Svelte that cannot compile the copied files. Select.Triggerbinds its node withbind:element, as its docs said.- CopyButton's
oncopyaccepts a(text) => voidhandler without a type error. - Server-rendered inset cards, code blocks, and other two-layer surfaces put their header or footer strip on the theme's inset edge from the first paint, instead of moving it once scripts load.
- Tabs show the selected tab's indicator in server-rendered HTML, before scripts measure it.
- The Toast close button uses the small control size, the control radius, the shared hover wash, and press feedback.
- Data Table filter options hover with the shared wash instead of the secondary fill.
- OTP Field cells take the control radius, so the sharp and rounded radius scales apply to them.
- The Hover Card trigger shows the shared focus ring.
- An empty Data Table shows "No pages" without a page button beside it.
- The File Upload dropzone's default description starts in lowercase, so it reads as one sentence with its title.
- Heatmap reads the theme's motion once per chart instead of once per cell, so year-long heatmaps mount faster.
- The Toast stack computes each toast's offset once per change instead of re-summing every height for each toast.
- Copied component folders name their context module
context.tsinstead ofcontext.svelte.ts. Re-adding a component leaves the old file behind; delete it. - The docs, Theme Studio, Themes, and Changelog share a new shell: a near-black frame with an icon rail, around one panel that holds the sidebar and the page. The frame is the same in light and dark mode.
- The rail holds the brand and the sidebar toggle at the top, Docs, Components, Theme Studio, Themes, and Changelog in the middle, and search, the theme toggle, and GitHub at the bottom. One highlight marks the current page and slides to the next.
- The docs shell drops the status line under the page.
- Sidebar navigation is a plain text list with more space between groups. Search moves to the rail, or the header on small screens, and stays on Cmd/Ctrl+K.
- The sidebar's current page is marked by a highlight sized to its label that slides between pages.
- Pinned section titles in the sidebar stay fully legible while their section scrolls.
- Open pages are tabs in a floating dock at the bottom of the page, styled like a toggle group.
- Documentation pages center the article in a column at most 60rem wide, with more space between sections and a larger page title.
- Docs text runs the full width of the article, level with previews and code.
- The docs page outline is a minimap of dashes at the right edge instead of an "On this page" list. Dashes grow toward the pointer and the nearest one shows its heading.
- Copy page sits at the top end of the page and is smaller, with less space around its buttons.
- The fade at the bottom edge of the page and the sidebar is shorter and no longer blurs far into the text.
- Every component page opens with a playground. Pick a variant in the toolbar, change the other props in the Props menu, and the code under the preview follows.
- Every example frame keeps its preview in view: the Code button slides the source open under it, long sources start collapsed and expand with the same motion, and Full screen opens the preview on its own.
- Slider, Number Field, Dialog, Sheet, Notch, Toast, Command, Color Picker, Question, and Gauge pages have a Labels section.
- The calendar and date picker pages say that days outside the month are disabled by default, and the API tables list that default.
- The Data Table
variantdescription says what each variant frames. - Theme Studio shows its preview on the panel, with its tools in a floating menu at the top end.
- Theme Studio switches preview modes with a floating segmented control at the bottom center of the preview instead of tabs in the top bar.
- Theme Studio no longer has a Primary button border setting. Lit buttons draw their own edge, so it had no effect.
- Theme Studio undo keeps recording after the page settles, and separate edits stay separate steps.
- Theme Studio counts a brand color edit as one changed setting.
- A share link request that fails late no longer clears a link built from a newer draft.
- A live theme saved by an earlier version of the docs is rebuilt from the Studio draft instead of being applied as stale CSS, which left the page and the content plate the same color in light mode.
- The Workspace address field in the Studio preview has a divider between the
mielui.dev/prefix and the slug, so the two no longer read as one field with a gap in it. - The Markdown theming guide at
/docs/theming.mdnow carries the full guide: token overrides, the public token table, presets, theme JSON, and selectors. - Component Markdown references include the modules their examples import, such as the Data Table and Heatmap
data.tsfiles. - The Markdown references for Alert, Badge, Button, and Toolbar no longer list sixteen example files that no docs page showed.
- The agent skill explains
bind:elementand thelabelsprop. - Usage snippets on component pages are complete Svelte files with a
<script lang="ts">block and every import they use. - Component pages no longer document props that parts do not accept, such as
styleon parts,childrenon Checkbox and Radio Group items, andicon={false}on Select. - The Card page gives the correct
chrome.bordersdefault,single. - The Tabs page says that an unset or unmatched
valueselects the first enabled tab. - Field and Form examples no longer print a second "(required)" beside the label's built-in required mark.
- The Theming guide names the current Theme Studio controls and lists every Theme JSON field.
- The Markdown changelog uses the same section names as the changelog page.
- Docs examples render with the page instead of mounting once they scroll into view, so they no longer pop in.
- The docs load Theme Studio's optional Google Fonts without blocking the first paint.
- Playground selects, the current sidebar page, and installation tabs look the same before and after scripts load.
- The Accordion, Breadcrumb, Pagination, and Radio Group examples use realistic content instead of placeholder labels.
- Numeric playground options name their control, so Folder Card's tone reads "Tone 1" instead of "1".
- Dialog examples use sentence case for their trigger labels.
- The docs apply your saved Theme Studio theme and docs font before the first paint, instead of showing the default theme until scripts load.
- Unit tests pass on Node 25 and newer, whose built-in
localStorageused to shadow jsdom's.