DataTable: table-level sort and on:sort for server-driven sorting
For custom sorting, you can now provide a top-level sort comparator on the table that applies to every sortable column unless a header defines its own.
For server-side sorting, listen with on:sort: the event includes detail.key (column) and detail.direction. Call preventDefault() so the table does not reorder rows in the browser; fetch sorted data from your API (or a loader), assign rows, and keep sortKey / sortDirection in sync with what the server used.
See the DataTable docs.
<script>
import { DataTable } from "carbon-components-svelte";
let headers = [
{ key: "name", value: "Name" },
{ key: "port", value: "Port" },
];
let rows = [
{ id: "a", name: "Item A", port: 443 },
{ id: "b", name: "Item B", port: 80 },
];
let sortKey = null;
let sortDirection = "none";
</script>
<DataTable
sortable
bind:sortKey
bind:sortDirection
{headers}
{rows}
sort={(a, b, { key }) => (key === "port" ? a - b : String(a).localeCompare(String(b)))}
on:sort={(e) => {
// Server-side sorting
e.preventDefault();
sortKey = e.detail.key;
sortDirection = e.detail.direction;
await loadRows({ sortKey: detail.key, sortDirection: detail.direction });
rows = result;
}}
/>TreeView: multiselect and link nodes
multiselect with bind:selectedIds supports Ctrl/Cmd/Shift-style selection; multiselectMode controls whether a gesture selects a single node, a subtree, or related groups. Nodes may set href so the label is a real link (e.g. file browser or docs tree) while keeping tree semantics.
See the TreeView docs.
<script>
import { TreeView } from "carbon-components-svelte";
let selectedIds = [];
let nodes = [
{
id: "1",
text: "Docs",
href: "/docs",
nodes: [{ id: "2", text: "Guide", href: "/docs/guide" }],
},
];
</script>
<TreeView {nodes} multiselect bind:selectedIds />
UI Shell: classic theme
v0.105.0 fully themed the UI Shell.
Header and SideNav now accept theme="classic" for the mixed shell look (Gray 100 header with White side nav), matching Carbon's classic UI shell guidance. Closes #2836.
Note: you must use the all.css StyleSheet since it uses CSS variables.
<script>
import "carbon-components-svelte/css/all.css";
import { Header, SideNav, SideNavItems, SideNavLink } from "carbon-components-svelte";
</script>
<Header theme="classic" />
<SideNav theme="classic">
<SideNavItems>
<SideNavLink href="/" text="Home" />
</SideNavItems>
</SideNav>
ComboBox: reopen after clear (openOnClear)
By default, the menu closes immediately when the value is cleared.
Set openOnClear to true to keep the list open after the user clears the field, so they can choose another option without having to click the trigger again.
See the ComboBox docs.
ComboBox: typeahead with custom filter (shouldFilterItem)
Built-in typeahead now respects shouldFilterItem, so filtering can follow your own rules: extra fields, aliases, diacritics, fuzzy matching, or anything beyond the default label substring behavior.
See the ComboBox docs.
<script>
import { ComboBox } from "carbon-components-svelte";
</script>
<ComboBox
shouldFilterItem={(item, value) => {
const q = value.trim().toLowerCase();
if (!q) return true;
return item.text.toLowerCase().includes(q);
}}
labelText="Country"
placeholder="Search or select"
items={[
{ id: "us", text: "United States" },
{ id: "ca", text: "Canada" },
]}
/>
ComboBox: auto-highlight first match (autoHighlight)
By default, no list item is highlighting when filtering values.
Set autoHighlight="first-match" so the first row that survives filtering is highlighted as the user types, reducing the use of arrow keys and providing a smoother keyboard path from search to selection.
See the ComboBox docs.
<script>
import { ComboBox } from "carbon-components-svelte";
</script>
<ComboBox
autoHighlight="first-match"
labelText="Contact"
placeholder="Select contact method"
items={[
{ id: "0", text: "Slack" },
{ id: "1", text: "Email" },
{ id: "2", text: "Fax" },
]}
/>
Dropdown: optional selectedId
selectedId can be omitted for an empty initial state, useful for placeholders and "choose one" flows without the need for a sentinel value.
See the Dropdown docs.
<script>
import { Dropdown } from "carbon-components-svelte";
</script>
<Dropdown
titleText="Role"
label="Select a role"
items={[
{ id: "admin", text: "Admin" },
{ id: "user", text: "User" },
]}
on:select={({ detail }) => console.log(detail.selectedId)}
/>Tag: large size
size="lg" aligns tags with other large Carbon controls when density or touch targets need to match the rest of the form.
See the Tag docs.
<script>
import { Tag } from "carbon-components-svelte";
</script>
<Tag size="lg">Large tag</Tag>
Performance: faster list components and leaner DataTable
Several hot paths now use Map / Set for O(1) id and index lookups instead of repeated linear scans; ComboBox, Dropdown, and MultiSelect benefit most on long lists (especially virtualized lists containing thousands of items).
DataTabledoes less redundant work: virtualized tables avoid re-running scroll setup on every reactive tick, row updates are guarded when the array reference is unchanged, and header-driven cell maps rebuild only when headers change. An unused header-key reactive variable was removed.Dropdown,MultiSelect, andComboBoxuse Maps to track items for O(1) lookups for finding items (e.g., highlighting).MultiSelectavoids an extra sort pass whenselectionFeedback="top"NumberInputcachesIntl.NumberFormatper locale, to avoid computing per keystroke.TreeViewdrops unused reactive tree-walker setup.
These changes are incremental per interaction but benefit dense UIs and large datasets.
What's Changed
- feat(combo-box): add
openOnClearby @metonym in #2861 - feat(combo-box): support auto-highlighting the first match by @metonym in #2859
- feat(combo-box): typeahead supports custom
shouldFilterItemby @metonym in #2862 - feat(data-table): add top-level
sortprop by @metonym in #2835 - feat(data-table): dispatch
sortevent by @metonym in #2829 - feat(dropdown):
selectedIdis optional by @metonym in #2814 - feat(tag): support large size by @metonym in #2818
- feat(theme): support rendering as a
Dropdownby @metonym in #2815 - feat(tree-view): support
multiselectby @metonym in #2852 - feat(tree-view): support links by @metonym in #2811
- feat(ui-shell): support classic theme by @metonym in #2850
- fix(combo-box): do not auto-select partial match when pressing "Enter" by @metonym in #2847
- fix(combo-box): do not trap focus when clicking outside element by @metonym in #2846
- fix(dropdown): button uses
comboboxrole, apply missing ARIA attributes by @metonym in #2840 - fix(dropdown): do not spread
translateWithIdto rawbuttonelement by @metonym in #2838 - fix(dropdown): selected item has checkmark icon by @metonym in #2813
- fix(list-box): add missing "lg" size mapping by @metonym in #2844
- fix(multi-select): Backspace/Delete should clear selection by @metonym in #2837
- fix(multi-select): fix typo in
sizeprop description by @metonym in #2845 - fix(multi-select): invalid/warn, filterable variant should only render one icon by @metonym in #2831
- fix(multi-select): narrow
itemToStringreturn type by @metonym in #2848 - fix(multi-select):
sortItemcomparator returns a number, notItemby @metonym in #2830 - fix(number-input): remove
patternfor number type input by @metonym in #2842 - fix(number-input): text mode should also apply min/max/step attributes to
inputby @metonym in #2841 - fix(tree-view): escape node ID when using
querySelectorfor focusing by @metonym in #2843 - fix(tree-view):
expandNodesshould expand all by default by @metonym in #2849 - fix: prevent infinite loop when all items are disabled by @metonym in #2824
- perf(data-table): avoid virtualized scroll set-up after any reactive update by @metonym in #2822
- perf(data-table): guard rows assignment with reference check by @metonym in #2826
- perf(data-table): rebuild
tableCellsByRowIdfor changed headers only by @metonym in #2821 - perf(data-table): remove unused
thKeyscomputation by @metonym in #2820 - perf(multi-select): avoid double re-sort for
selectionFeedback="top"by @metonym in #2832 - perf(multi-select): optimize
isSelectAlllogic by @metonym in #2828 - perf(number-input): cache
Intl.NumberFormatlocale usage by @metonym in #2833 - perf(tree-view): remove unused tree walker reactive initialization by @metonym in #2823
- perf: use Set/Map for O(1) lookups in hot paths by @metonym in #2825
Full Changelog: v0.105.1...v0.106.0