Download Latest Version v0.112.0 source code.zip (3.4 MB) Google Add to Preferred Sources
Home / v0.111.1
Name Modified Size InfoDownloads / Week
Parent folder
README.md 2026-08-24 36.3 kB
v0.111.1 source code.tar.gz 2026-08-24 1.7 MB
v0.111.1 source code.zip 2026-08-24 3.2 MB
Totals: 3 Items   4.9 MB 0

This release focuses on performance and bug fixes. Components and helpers were benchmarked with mitata across wall-clock speed and memory, which drove the wins on list boxes, tables, trees, tabs, and the CSS bundle. The 70 fixes cover form invalid-state accessibility, menu selectable layout, modal scrolling, combo box typeahead, list-box form serialization, pagination, keyboard behavior, and ARIA.

90 changes in this release:

Category Count
Breaking changes 0
Features 0
Bug fixes 70
Performance 20

Full Changelog: https://github.com/carbon-design-system/carbon-components-svelte/compare/v0.111.0...v0.111.1


Performance: benchmarks

Benchmarks use mitata to find the slow spots. Two kinds of benches:

  • Pure speed. DataTable and MultiSelect sorting, virtualization math, tree helpers, fuzzy match, and similar hot paths.
  • Component mount and interaction (vitest + jsdom). Wall-clock time to mount Tabs, OverflowMenu, UserAvatarGroup, TreeView, MultiSelect, and others at increasing child counts. Also times interactions like ArrowDown highlight, filter keystrokes, first expand, and menu open.

The main findings were O(n²) child registration, rebuilding Intl.Collator on every sort comparison, mounting whole trees while branches stayed collapsed, and fanning highlight state through every list-box option on ArrowDown. Each fix has a paired before/after run in the PR.

Perf PRs:

PR Focus
#3651 Baseline suite; DataTable Intl.Collator sort cache
#3652 MultiSelect sort cache; lazy TreeView collapsed mounts
#3653 batchStoreUpdates; Tabs, OverflowMenu, UserAvatarGroup
#3654 TabsVertical, TagSet, ProgressIndicator registration batching
#3657 List-box highlight cursor; MultiSelect unmount; Pagination; DataTable paint window; ContentSwitcher
#3715 CSS prune for dead bx-- selectors

Gains

Path N Before After Factor PR
css/all.css gzip (minified) shipped bundle 85,164 B 83,306 B -1.8 KB #3715
css/all.css raw (minified) shipped bundle 912,825 B 898,320 B -14.2 KB #3715
DataTable string-column sort 10,000 rows 131.93ms 4.60ms ~29x #3651
MultiSelect default item sort 10,000 items 1x ~10x faster ~10x #3652
MultiSelect mount (virtualized) 1,000 items 1x ~3x faster ~3x #3652
TreeView collapsed mount (suite default) 1x ~3.5x faster ~3.5x #3652
TreeView nodes update (non-virtualized) 1,000 1x ~120x faster ~120x #3652
Tabs mount 10 12.11ms 2.66ms ~4.6x #3653
Tabs mount 80 1.09s 15.76ms ~69x #3653
Tabs mount 100 1.72s 20.33ms ~85x #3653
OverflowMenu mount 10 11.65ms 2.44ms ~4.8x #3653
OverflowMenu mount 80 1.34s 14.27ms ~94x #3653
OverflowMenu mount 100 2.12s 16.88ms ~126x #3653
UserAvatarGroup mount 10 31.01ms 2.55ms ~12x #3653
UserAvatarGroup mount 80 2.70s 16.39ms ~165x #3653
UserAvatarGroup mount 100 4.56s 22.83ms ~200x #3653
TabsVertical mount 10 11.97ms 2.48ms ~4.8x #3654
TabsVertical mount 80 1.10s 16.82ms ~65x #3654
TabsVertical mount 100 1.71s 24.34ms ~70x #3654
TagSet mount 10 8.40ms 2.75ms ~3.1x #3654
TagSet mount 80 74.84ms 15.37ms ~4.9x #3654
TagSet mount 100 98.41ms 20.00ms ~4.9x #3654
ProgressIndicator mount 10 16.28ms 2.92ms ~5.6x #3654
ProgressIndicator mount 80 1.31s 20.58ms ~64x #3654
ProgressIndicator mount 100 2.03s 24.87ms ~82x #3654
Dropdown ArrowDown highlight 1,000 5.05ms 641µs ~8x #3657
MultiSelect closed mount 100 92ms 3.5ms ~26x #3657
MultiSelect closed mount (no virt.) 1,000 967ms 8.6ms ~110x #3657
ContentSwitcher mount 10 10.3ms 2.6ms ~4.0x #3657
ContentSwitcher mount 80 54.3ms 17.5ms ~3.1x #3657
ContentSwitcher mount 1,000 1.25s 365ms ~3.4x #3657
Pagination mount (100k items) pageWindow 1000 212ms 103ms ~2.1x #3657
Pagination mount (100k items) pageWindow 100 26.2ms 7.2ms ~3.6x #3657
DataTable virtualized mount 30k×20 270ms 172ms ~1.6x #3657
DataTable virtualized rows swap 30k×20 399ms 86ms ~4.6x #3657

Closed MultiSelect at 1,000 items also dropped heap from ~119MB to ~1.4MB (#3657). ComboBox filterMode defaults to "remove" (100-item keystroke ~3.7ms vs ~20.5ms for "hide").

What changed

  • CSS. Dead bx-- selectors removed from vendored SCSS after an AST diff of css/all.css (#3715).
  • Intl.Collator cache. DataTable string sorts and MultiSelect default sortItem reuse one collator instead of rebuilding per comparison.
  • Lazy tree mount. Collapsed TreeView branches mount on first expand and stay mounted, so collapsed mount and nodes updates scale with visible nodes.
  • Batched registration. Tabs, TabsVertical, OverflowMenu, UserAvatarGroup, TagSet, ProgressIndicator, and ContentSwitcher flush child registration in one store update via batchStoreUpdates (was O(n²) per-child store.update()).
  • List-box highlight cursor. ArrowDown updates only the previous and next highlighted options instead of every item.
  • Closed MultiSelect unmount. Menu DOM stays off until open, same as ComboBox. Selection still serializes through hidden inputs (see form serialization below).
  • ComboBox / SearchMenu filterMode. "hide" keeps unmatched options mounted. Default "remove" is faster per keystroke.
  • Pagination. Page numbers render as native <option>s.
  • DataTable. Under virtualization, cell records are built for the painted window only.

    :::svelte <script> import { TreeView, Tabs, Tab, TabContent } from "carbon-components-svelte";</p> <p>const nodes = [ { id: 0, text: "Analytics", nodes: [{ id: 1, text: "Spark" }] }, { id: 2, text: "Blockchain" }, ]; </script>

    <treeview labeltext="Products" {nodes}>

    <tabs> <tab label="Overview"> <tab label="Metrics"> <svelte:fragment slot="content"> <tabcontent>Overview</tabcontent> <tabcontent>Metrics</tabcontent> </svelte:fragment> </tabs>


Form invalid state: aria-errormessage and live alerts

Invalid fields now point at their error text with aria-errormessage and announce it with role="alert". That covers text input, text area, password input, combo box, and date picker. Date picker also links invalid, warn, and helper text through aria-describedby, and calendar day labels include the weekday.

See TextInput, ComboBox, and DatePicker.

:::svelte
<script>
  import { TextInput, ComboBox } from "carbon-components-svelte";
</script>

<TextInput
  labelText="Workspace name"
  invalid
  invalidText="Name is required"
/>

<ComboBox
  labelText="Region"
  invalid
  invalidText="Select a region"
  items={[
    { id: "us-east", text: "US East" },
    { id: "eu-de", text: "EU Germany" },
  ]}
/>

Combo box: Tab commit, controlled blur, and typeahead

Keyboard-highlighted items commit on Tab. Controlled selection restores the label when blur leaves a non-matching query. Typeahead skips disabled items. Use filterMode="hide" to keep filtered options mounted (hidden) so option state survives filtering. It falls back to "remove" under virtualization.

See ComboBox typeahead and filter mode.

:::svelte
<script>
  import { ComboBox } from "carbon-components-svelte";

  let selectedId = "us-east";
</script>

<ComboBox
  bind:selectedId
  typeahead
  filterMode="hide"
  labelText="Region"
  items={[
    { id: "us-east", text: "US East" },
    { id: "eu-de", text: "EU Germany", disabled: true },
  ]}
/>

Modal: native select mouseup, stacked Escape, scrolling content

Picking an option from a native <select> inside a modal no longer closes the dialog on the orphaned mouseup. Same for composed modal. Escape closes only the topmost stacked modal. With hasScrollingContent, modals show a bottom overflow gradient and scroll newly focused elements out from under it. Popover ignores clicks on a portaled date picker calendar so nested calendars stay open.

See Modal and ComposedModal.

:::svelte
<script>
  import { Modal, Select, SelectItem } from "carbon-components-svelte";

  let open = true;
</script>

<Modal bind:open modalHeading="Export" hasScrollingContent>
  <Select labelText="Format">
    <SelectItem value="csv" text="CSV" />
    <SelectItem value="json" text="JSON" />
  </Select>
</Modal>

List-box form serialization

Dropdown writes selectedId through a hidden input. Multi-select serializes selection with hidden inputs instead of the open menu DOM, so native form submit works whether the menu is open or closed. Select-all only applies to currently filtered items. Clearing the filter with the button forwards input.

:::svelte
<script>
  import { Dropdown, MultiSelect } from "carbon-components-svelte";
</script>

<form method="post">
  <Dropdown
    name="region"
    labelText="Region"
    selectedId="us-east"
    items={[
      { id: "us-east", text: "US East" },
      { id: "eu-de", text: "EU Germany" },
    ]}
  />
  <MultiSelect
    name="tags"
    labelText="Tags"
    items={[
      { id: "a", text: "Alpha" },
      { id: "b", text: "Beta" },
    ]}
  />
</form>

Menu: selectable layout and keyboard

Selectable and radio items get a checkmark column separate from leading icons. If any sibling is selectable or radio, every label indents to line up. Tab closes the menu and returns focus to the anchor, same as Escape. Title tooltips sit on the interactive element. Disabled items no longer take mouse focus.

See Menu and MenuButton.

:::svelte
<script>
  import { MenuButton, MenuItem } from "carbon-components-svelte";
</script>

<MenuButton labelText="View">
  <MenuItem selectable selected>Grid</MenuItem>
  <MenuItem selectable>List</MenuItem>
  <MenuItem disabled>Archive</MenuItem>
</MenuButton>

Pagination: labels, tooltips, focus, and narrow layouts

pageSelectLabelText customizes the page-number select label. backwardTextTooltipPosition and forwardTextTooltipPosition place the prev/next tooltips. A pageSelect slot replaces the default page picker. Below the medium breakpoint, item count and nav buttons stack. Disabled forwards to the page-size and page-number selects. When one nav button becomes disabled, focus moves to the sibling. pageSize syncs when pageSizes drops the current value. Page numbers are native options.

See Pagination.

:::svelte
<script>
  import { Pagination } from "carbon-components-svelte";
</script>

<Pagination
  totalItems={240}
  pageSizes={[10, 20, 50]}
  pageSelectLabelText={(total) => `Go to page, ${total} pages total`}
  backwardTextTooltipPosition="bottom"
  forwardTextTooltipPosition="bottom"
/>

Data table and side nav

Wide tables get a horizontal scroll wrapper so sticky headers and selection columns stay usable. Side nav applies the fixed class on rail layouts so the rail does not expand on hover.

See DataTable and UIShell side navigation.


Number input: readonly, inputmode, and digit normalization

Readonly fields block arrow-key value changes. type="number" defaults inputmode to decimal for mobile keyboards. Non-Western digit glyphs normalize before parsing so pasted or IME input still resolves.

See NumberInput.

:::svelte
<script>
  import { NumberInput } from "carbon-components-svelte";
</script>

<NumberInput labelText="Quantity" value={12} />
<NumberInput labelText="Locked total" value={100} readonly />

More in this release

  • Checkbox group. Invalid and warn states propagate to child checkboxes.
  • Clickable tile. Space fires the click handler, not only Enter.
  • Code snippet. Inline variant respects disabled.
  • Data table. Horizontal scroll wrapper for wide tables. Expanded row content aligns with checkbox/radio columns. Skeleton gains the missing medium size class.
  • File uploader. Invalid icon spaced from the close button.
  • Link. visited forces visited styling. Icon wrapper is a span. Disabled clicks are blocked.
  • List box. Singular clear label when exactly one item is selected.
  • Multi-select. Rest props forward to the non-filterable trigger.
  • Popover / toggletip. Outside-click resolves through shadow DOM. Toggletip no longer closes on browser window blur.
  • Progress bar / radio button. Label-text class for truncation on progress bar and readonly radio labels.
  • Progress indicator. Steps stay tabbable. Labels use spans inside buttons.
  • Search. Native type="search". Collapsed expandable input is hidden from assistive tech.
  • Search menu. Escape-clear no longer reopens the menu.
  • Structured list. Hover highlight suppressed on selected rows.
  • Tabs. Scroll buttons appear only when overflow is greater than 1px.
  • Text input. Fluid maxCount counter sits opposite the label.
  • Time picker. Invalid/warn suppressed when disabled or readonly.
  • Tooltip. Stops stacking and off-center caret.
  • UI Shell. HeaderPanelLink supports isSelected. Current-page class on nav items. HeaderPanelDivider wraps hr in an li.

What's Changed

Bug Fixes

Performance

Source: README.md, updated 2026-08-24