Menu


0.2.1 alpha


The release notes for version 0.2.1-alpha.

Released

0.2.1 alpha adds five components: an alert dialog, a collapsible, a one-time code input, a navigation menu and a menubar. The checkbox, radio, accordion and sidebar now move as they change. Every part that scrolls inside itself draws a thin scrollbar that takes no room. The rest is fixes and small additions found while building real pages with the system. Two small things break, and What breaks says what to use instead.

New


  • Combobox active option. onActiveChange tells the page which option is active, the one Enter would pick, and what made it active: the arrow keys, the pointer, or a mouse at rest that the list opened under. Closing the list or typing tells it nothing is. A page can show the option in a preview before it's picked.
  • Pagination as links. Give each page's address with href, and every page, Previous and Next become links. They work with no script, for sites built ahead of time and pages a search engine should follow. The current page keeps its look.
  • Selectable list without its tick. tickless draws a selectable list's chosen row by its fill and a bolder title alone, with no tick. It's for rows that open as they're chosen, such as an inbox beside its reading pane, where a tick would read as kept for later. The keyboard and what a screen reader hears stay the same. In plain HTML it's smbk-list--tickless.
  • List rows that open a new tab. A link row takes target and rel, so a row that leads to another site can open in a new tab. Its name then ends with "(opens in a new tab)" for screen readers. In plain HTML, end the row's title with a smbk-visually-hidden span holding those words.
  • Synonym list. synonym-list.json says which common design-system name each Simbolik name means, such as brand for primary. It also says which token files hold raw values and which hold roles, and lists the four modes and their values.
  • Theme wipe. A new applyTheme(), beside the theme switch, sets the page's theme with a wipe. The new theme grows over the whole page in a circle from the option pressed, in one second. Call it from the switch's onChange, which now also passes the option pressed. Readers who ask for reduced motion, and browsers without view transitions, get the change at once, as before. The timing is 2 new motion design tokens, --smbk-motion-theme-wipe-duration and --smbk-motion-theme-wipe-easing.
  • Alert dialog. A new component that asks before something that can't be undone, such as deleting a project. It looks like the modal, with its icon in red when the confirm action is a danger one. Focus starts on Cancel, and a click beside it doesn't close it, so the reader has to choose. Escape and Cancel close it; the confirm action calls onConfirm and closes it.
  • Button width and content. A button takes full-width to stretch across its space, its label still centered. It also takes leadingContent, such as a small avatar before the label, and count, a number after the label in the badge's small pill. In plain HTML they're smbk-btn--full-width, smbk-btn__leading-content and a badge with smbk-btn__count.
  • Large input. The input takes size="lg", 48 tall, to stand beside large buttons. It keeps the medium text and icons. In plain HTML it's smbk-input--size-lg.
  • Date range. The date picker takes type="date-range", with 2 date fields for a first and a last day, typed or picked on the range calendar. Its value is one string, the 2 days as YYYY-MM-DD/YYYY-MM-DD, and a form gets both days under one name. On a phone the fields stack.
  • Toast shortcut. F6 moves focus to the newest toast, and F6 again goes back. A toast with an action no longer takes a trip through the whole page to reach.
  • Stat trend and chart. A stat takes trend, a mark of the change after its figure, such as a small badge with "+12%". It also takes chart, a small chart under its line, such as a sparkline. In plain HTML they're smbk-stat__trend inside the figure and smbk-stat__chart after the line.
  • Select groups and rich choices. A select's choices can sit in groups, each under a small heading, with a line between groups. Screen readers say which group a choice is in. A choice can also show a picture or an icon before its label, and a second line under it, such as a person's role. In plain HTML a group is smbk-select__group. A rich choice is smbk-select__option--rich, with smbk-select__option-lead, smbk-select__option-text and smbk-select__option-description.
  • Collapsible. A new component, one row that shows or hides the content under it, for detail most readers can skip, such as older releases. It opens and closes with the accordion's motion. Its block is smbk-collapsible.
  • One-time code input. A new component for a code sent by email or text message, in 6 boxes, 2 groups of 3. They act as one field, so pasting a code, the phone's suggested code and screen readers all treat it as one value. It takes a field's label, help and error. Its block is smbk-one-time-code-input.
  • Navigation menu. A new component for a site header's links. An item with a caret opens a wide panel of links, each with a line of description, and a featured column. On a phone the list stacks and a panel opens in place under its item. Its block is smbk-navigation-menu.
  • Menubar. A new component, a row of menus as at the top of a desktop app (File, Edit, View). The arrow keys move along the bar and from one open menu to the next, and the pointer does the same. Its menus are the dropdown's, with second menus and single choices. Its block is smbk-menubar.
  • Dropdown submenus and single choice. An item can open a second menu beside it, by the pointer, the right arrow or Enter. The left arrow or Escape closes it again. A group of items can be a single choice, the chosen one marked with a tick after its label. In plain HTML, smbk-dropdown__submenu holds the item and its second menu.
  • Right-click menu. A dropdown given an area opens where the pointer is, on a right click on that area. A finger held on it does the same on a touch screen, as do Shift+F10 and the menu key from the keyboard. Focus goes back where it was when the menu closes. The hold is a new motion design token, --smbk-motion-hold-delay.
  • Page header without a main action. mainAction={false} draws every action as an outline button, for a page whose main action sits somewhere else, such as the app's toolbar. In plain HTML, mark each action smbk-page-header__action--secondary. An action can also be the system's own button or button with a note, given as its button. The header still folds it behind More actions on a phone.
  • Narrow sidebar. width="sm" makes a sidebar's open panel 240 wide, for a dense app's list of pages. The column of icons keeps its width. In plain HTML it's smbk-sidebar--width-sm.
  • Medium sidebar children. child="md" draws a sidebar's children as tall as their parent, 40 with 16 px text. It's for children a reader opens as often as the item above them. Their labels and the tree line stay where they were. Without it they stay a step smaller, as before, and a small sidebar keeps every row small. The navigation alone, SidebarNav, takes it too. In plain HTML it's smbk-sidebar--child-md.
  • Keys in tooltips. A toolbar tool, a segmented control and the tooltip take a shortcut. The tooltip shows the key after the name as a small key cap, and the control gives it to screen readers as aria-keyshortcuts. The page still listens for the key itself. In plain HTML the key cap is smbk-tooltip__key.
  • Small empty state. An empty state takes size="sm" for one panel among many, such as on a dashboard. Its title is a label, and its icon and gaps are smaller, so an empty panel no longer reads louder than its neighbors. In plain HTML it's smbk-empty-state--size-sm.
  • Small description list. A description list takes size="sm" for a narrow panel, such as a settings column about 320 to 360 wide. It uses the small text sizes and closer rows. Side by side, the names take about a quarter of the row, so short values stay on one line. It keeps its columns on a phone. In plain HTML it's smbk-description-list--size-sm.
  • Field group help with blocks. A field group's description can hold paragraphs, a list and code, and screen readers still read all of it as the group's description. The field message takes as="div" for this. In plain HTML, write the help as a div with the field message's classes, its words in a div with smbk-field-message__text.
  • Combobox swatches, badges and groups. A combobox option can show an icon or a color swatch before its label. After it, it can show quieter detail words or a badge, such as a color's contrast. Screen readers read those words with the label. Options can sit in groups under a heading, and typing hides a group with nothing that matches. With one choice, the box shows the chosen swatch or icon before its label. The new parts are smbk-combobox__option-lead, smbk-combobox__option-detail and smbk-combobox__option-badge.
  • Bar chart colors and focus. A stacked series can keep its own color whichever series are shown, with swatch (1 to 8). legendEmpty={false} leaves series with nothing in them out of the legend. With focusable, each bar takes focus and says its figures, as one Tab stop moved with the arrow keys. onActiveChange tells the page which bar is pointed at or focused, for a readout under the chart.
  • Donut chart colors and focus. A part can keep its own color with swatch, and legendEmpty={false} leaves parts of zero out of the legend. With focusable, each part takes focus and says its name, value and share, and onActiveChange tells the page which part is pointed at or focused.
  • Table rows left out of choosing. In a selectable table, a row given selectable: false shows no checkbox but keeps its room, so the column lines up. The checkbox in the heading counts only the rows that can be chosen. A row also passes any data- attribute it's given to its row element. In plain HTML the kept room is smbk-table__choose-space.
  • Board groups that fold. A board group's label can be a heading in the page's outline, with headingLevel. A group can fold under its label, always or only on a phone (fold="always" or fold="narrow"), and starts closed unless defaultExpanded is set. In plain HTML it's a details element with smbk-board-column__group--fold-always or smbk-board-column__group--fold-narrow.
  • Timeline events that unfold. An event can hold more text, given as more, that unfolds under it in place when it's pressed. Its row tells screen readers whether it's open. In plain HTML the event's body holds a details element with smbk-timeline__disclosure.
  • Contained slider. The slider takes look="contained", a filled bar as tall as a button with its label and value inside. Where the red passes under the words, they turn white, so they read on both parts. A long label wraps and the bar grows to hold it. In plain HTML it's smbk-slider--look-contained, with the label row inside the rail and a white copy of it inside the fill.

Changed


  • Compact tools. The rules every project keeps now let a tool set the compact density on <html>: a screen its own people use at a desk to make or manage something. A site's readers still get the comfortable density. The checker never asked for one or the other, so nothing changes there.
  • Tooltip wait. A tooltip now waits a second while the mouse rests on its control. A pointer passing over a toolbar no longer pops up a row of bubbles. A label's info icon waits about a third of a second, since pointing at it is asking for help. Keyboard focus still shows both at once. The waits are 2 new motion design tokens, --smbk-motion-tooltip-open-delay and --smbk-motion-help-open-delay.
  • Stat in a card. A stat in a card's slot drops its own padding and surface, so its name lines up with the card's header. The card gets shorter too.
  • Badge and tag edges. A soft badge and a tag in a feedback tone now draw a pale edge in their tone, so a row of them reads quieter. Info and warning get the pale edge colors success and danger already had, 2 design tokens: --smbk-color-feedback-info-border-subtle and --smbk-color-feedback-warning-border-subtle.
  • Popover focus. Opening a popover now moves focus into it: to its first field, or to the panel itself, named by its title. Screen readers announce it as it opens. Before, focus stayed on the button.
  • Menu keys. In a dropdown menu, typing a letter jumps to the item that starts with it. Disabled items can be reached with the arrows and are read as unavailable; pressing one does nothing. A click opens the menu with focus on the menu itself, not its first item. Enter and Space still open it on the first item.
  • Toast announcements. A danger toast is announced at once, interrupting. The others are announced politely, as before. The toast region is now a named landmark, with 2 hidden announcers beside it that read each toast. A page's own tests that looked for the region as a status now look for a region.
  • Error look from aria-invalid. A field, checkbox, radio, choice card or file upload marked aria-invalid="true" now draws the error look, with or without the error class. Plain HTML that marks its errors for screen readers gets the red edge too; add the warning icon in the markup.
  • Accordion. A disabled item now stays in the Tab order and is read as unavailable. It still doesn't open.
  • Accordion motion. An item now unfolds and folds back the same way, on a soft curve. Its content fades in from a slight blur, the foot of the text fades as it moves, and the caret turns in step. A second press halfway turns it round, and it moves the same in every browser. With reduced motion, an item opens at once and its content fades in; closing, the content fades out first. The timing is 3 new motion design tokens, --smbk-motion-expand-duration, --smbk-motion-expand-easing and --smbk-motion-expand-blur. They use a new curve, --smbk-easing-cubic-out. In plain HTML, Chrome and Edge move it the same way, without the fading foot. Other browsers still open it at once.
  • Checkbox motion. Ticking a box now fills it from a little smaller as the fill fades in. Then the tick draws itself from its start to its tip. Unticking erases the tick at once while the fill shrinks away, and a mixed box draws its dash without the wait. A box ticked as the page loads simply shows it. With reduced motion, the fill and the tick only fade. The fill is drawn on the box's own ::before. The timing is 5 new motion design tokens, --smbk-motion-fill-duration, --smbk-motion-fill-easing, --smbk-motion-draw-duration, --smbk-motion-draw-delay and --smbk-motion-draw-easing.
  • Radio motion. Choosing a radio fills its circle the same way. Its dot pops in, growing a little past its size and settling back, while the dot it replaces shrinks away. The circle gives a little while it's pressed. With reduced motion, the fill and the dot only fade. The timing is 2 new motion design tokens, --smbk-motion-pop-duration and --smbk-motion-pop-easing. The curve, --smbk-easing-back-out, is the first in the system that runs past its end.
  • Sidebar motion. The sidebar now folds and unfolds on a curve that is slow to leave and slow to land. Pressed on the way, it turns round where it is. Closing, the words fade into a slight blur before the rows narrow. Opening, they come back as the rows reach full width. Group labels and open groups fold with it in every browser, and the rows below follow smoothly. Going from kept open to kept closed now moves the same way. In the auto column, the icons below an open group no longer sit lower than the rest. A group's children now unfold like an accordion item, the same in every browser. With reduced motion, the sidebar changes at once and the words still fade in. The timing is 5 new motion design tokens, each starting with --smbk-motion-fold-: duration, easing, label-duration, label-easing and blur.
  • Scrollbars. Parts that scroll inside themselves now draw the system's own scrollbar, over their content at the edge. That covers menus, the select's and combobox's lists, popovers, the modal's and drawer's bodies, the command palette, the sidebar, logs, code, tables, boards, the tabs' row and the text area. The bar takes no room. So where a computer always shows scrollbars, a list no longer grows wider and a code block no longer grows taller. It shows while the mouse is over the part or the part scrolls, and fades half a second after the last scroll. Its thumb is thin and see-through and widens under the mouse. Drag it, or press its track to jump there. A touch screen keeps the browser's own bar. The thin hint under a wide table or board fades while the bar shows. Markup written by hand keeps the browser's thin bar too. The data-scrollbar mark and the smbk-scrollbar part come from the script. The wait is a new motion design token, --smbk-motion-scrollbar-hide-delay.
  • Showroom home page. Every component now drifts past on a wall of their card pictures, seen from above at an angle, in place of the 14 working examples. Point at one, or reach it with Tab and the arrow keys, to lift it and see its name; it opens its page. Behind the title, a faint field of characters breathes from edge to edge. Both stand still with reduced motion.
  • Select keys. Home and End open a closed select on its first or last choice.
  • Server components. Every component file that uses state or events starts with 'use client', so a Next.js App Router page can import it. Files that only draw markup, like the button, stay usable on the server.
  • Popover and dropdown wrapper. The element around the button and its panel is now a div, which HTML allows to hold the panel. Its class and its look are the same.
  • Sunken wells. Fields, checkboxes, slider bands, logs, table headers and other sunken parts were the page's own gray. Now they draw a see-through shade. They sit a step below whatever is under them, the page included. A field on the page no longer shows by its edge alone. On a card they look about as before. --smbk-color-surface-sunken is now see-through, so a part that draws it over a picture or a colored fill lets that show through.

Fixed


  • Hidden parts. Any part of the design system given the hidden attribute is now hidden, such as a tag, an empty state or a list row that a page's own script filters out. Before, a part's own display outweighed the attribute, so it stayed on screen. Panels still fade out as they close, and hidden="until-found" still works.
  • Tooltip on a select. A tooltip given a select as its target now shows at once when the select takes keyboard focus, and hides when focus leaves, as it does on a button. Before, it showed only on pointing. Pointing still waits a second.
  • Toggle chip pressed by a script. A toggle chip now shows its tick whenever it's on, including when a page's own script presses it by setting aria-pressed="true". Before, only a chip React rendered as selected showed the tick, so a chip pressed by a script showed it was on by color alone. Every toggle chip now carries its tick in the markup, hidden while it is off.
  • Bars beside a held first column. Bars and meters in the columns that scroll sideways now pass under the held first column. Before, they drew over the names in it as they scrolled past.
  • Popover in a table heading. A table heading's info popover now wraps its words onto as many lines as they need. Before, it took the heading's single line, so a long explanation ran past the panel and had to be scrolled sideways. Any popover opened from a place that keeps its words on one line, such as a bar, wraps the same way.
  • Pinned rows in Firefox. In a table that keeps its first column in view, a pinned row no longer draws a thin red line along its foot in Firefox. Its red edge on the start side is unchanged.
  • Required date picker. A required date picker, or date range, left empty now stops the form from sending, as a required select does. Its first empty field takes focus, and it shows its error look until it holds a value. A disabled or read-only picker never stops the form.
  • Lines through a held first column. In a table that keeps its first column in view (pin-first), the lines between rows and under the headings now run straight through that column. Before, the column drew its own copy a pixel off the table's, so its lines looked heavier and stepped at its edge.
  • Backup fonts. Light, medium, semibold and bold text now each have a stand-in face of their own width, in assets/fonts/fallback.css and assets/fonts/fonts.css. A line drawn before its font arrives breaks at about the same word as after, so the page barely moves when the font comes in. Before, one stand-in sized to the regular weight set light text a line longer and bold text a line shorter. Geist and Funnel Display's regular stand-ins are a little narrower too, measured as browsers set the text.
  • Sidebar touch. On a touch screen, the first and last items in a sidebar group now take a press halfway into the gap beside them. The other rows already did. Before, their press area stopped at their own edge.
  • Sparkline entrance in Chrome. A sparkline below the fold now draws when it's scrolled into view in Chrome, Edge and other Chromium browsers. It used to stay empty. The line and its dot now sit in a new smbk-sparkline__plot part. Markup written by hand can leave it out and still shows the sparkline, just without the reveal.
  • Forms. A required select, combobox or number field left empty now stops the form from sending. The browser focuses it, and it shows its error look until it's filled. The select also writes its value to a hidden native select, so the browser's autofill can fill it. A disabled number field no longer sends its value. A form's Reset button now puts the select, combobox, date picker, slider, color picker, radio group and selectable list back where they started.
  • A page's own handlers. A page's own onClick or onCancel on a modal or drawer no longer switches off closing on Escape and on the scrim. Both run now. The same goes for a page's key handler on a date picker, and its click and focus handlers on a selectable list's rows. A popover or dropdown keeps its own open state over a hidden the page passes.
  • Tabs in right-to-left pages. The arrow keys follow the reading direction, so in Arabic or Hebrew the left arrow moves to the next tab.
  • Select placement. A select or combobox given a boundary now places its list inside it the first time it opens.
  • Font files. The icon font's stylesheet and the font stylesheets in assets/ now name only each font's WOFF2 file, the one every browser takes. A site's build tool no longer copies about 3.4 MB of WOFF, TTF and SVG files into what it uploads.
  • Checker and touch areas. The checker no longer flags a touch screen's press area that stops halfway into the gap beside it. That's half the gap's space token made negative, such as var(--smbk-space-inline-sm) / -2. That form passes only on the inset of a ::before or ::after inside @media (pointer: coarse). Anywhere else it's still a new value made from a token.

What breaks


  • Dropdown sizes. The dropdown's default and small sizes are gone, as props and as the classes smbk-dropdown--size-default and smbk-dropdown--size-small. Use md and sm, as on the other controls, and the classes smbk-dropdown--size-md and smbk-dropdown--size-sm. They're also on the list of a select, a combobox or a sidebar flyout written in plain HTML.
  • Keys on the segmented control and toolbar tool. SegmentedControl and ToolbarTool no longer pass an aria-keyshortcuts prop through. Give the key as shortcut. Screen readers are told it the same way, and the tooltip shows it as a key cap.

Hotfix 1 · 2026-10-30


  • Sidebar flyout. In a kept-closed sidebar, the menu that opens from an item with children shows above the page again. Since this Release's scrollbars, a part of the page beside the sidebar on a layer of its own, such as a card, a chart or a sticky bar, drew over it. The menu now opens in the browser's top layer, as the dropdown's menus do.

Known gaps


  • Table rows can't be reordered. The table has no drag handle in this Release, so a site that needs to move rows builds that itself for now.
  • Five components are new and Proposed. The alert dialog, collapsible, one-time code input, navigation menu and menubar are marked Proposed. Their look and props may still change in a later Release.
  • Some color pairs fall short of contrast. A few colors measure below the contrast ratio WCAG asks for against the background they sit on. Text needs 4.5 to 1; the edge or mark that shows a control or its state needs 3 to 1. Some pairs are still to be fixed. Others are kept on purpose, a choice of taste for the system's look. The Contrast section of the color page lists every pair, what it measures and what it needs.

Take it


The code is on GitHub, https://github.com/simbolik-lab/simbolik-design-system (opens in a new tab), tagged v0.2.1-alpha. On that Release, download simbolik-0.2.1-alpha.zip. It holds one design-system/ folder with what a site builds with and every license, ready to use with no build. The README on GitHub says how to use each part.

A site on 0.2 alpha swaps its copy of the bundle for this one, then moves off every name What breaks lists. The conformance checker names each class and custom property the site still uses that is gone; React props it can't see, so search the site's code for the props listed there. A site still on 0.1.2 alpha or earlier reads the 0.2 alpha notes first.

The Figma file the design is drawn in is on Figma Community, https://www.figma.com/community/file/1688324308358870630 (opens in a new tab), where anyone can open it and copy it.

The code is under the MIT License and the Figma file under CC BY 4.0. The Licenses page says what each one asks.