Skip to main content
Light Dark System

Changelog

Versions prefixed with -alpha or -beta are prereleases published from main under their respective npm dist-tag. See Releasing for details on how releases are cut and published.

1.6.0

  • Added <cw-video-embed>, a lazy-loading facade for third-party video (YouTube, Vimeo and similar). It shows a static thumbnail and a play button, and only activates the real embed, supplied as markup inside an inert <template>, once someone clicks, so nothing loads or tracks before then
  • Added <cw-picture>, a responsive image wrapping the browser’s native <picture> and srcset handling. It adds resolution switching, art direction, format negotiation, reserved layout space from width and height so loading doesn’t shift the page, a placeholder, and an explicit way to mark an image as decorative
  • Added <cw-grid>, which lays its children out in columns, one child per cell, with no wrappers to add. Columns respond to the grid’s own width rather than the viewport’s, so the same grid works in a full-width band and in a narrow sidebar, dropping to fewer columns as it narrows. Set columns, min-column-width, gap and align to tune it
  • Added <cw-stack>, which lays its children out top to bottom with one consistent gap between them, and an align option for the cross axis
  • Added <cw-section>, a full-width band of page content with a content width (narrow, default, wide or full) that stops growing on wide screens, padding-block and gutter spacing, a flush option for edge-to-edge content on narrow screens, a surface background (default, alt, primary or inverse) that runs the full width, and a label that names the band for assistive technology
  • Added the --cw-layout-width-narrow, --cw-layout-width-default and --cw-layout-width-wide design tokens (720px, 1200px and 1440px) to the light and dark themes, used by <cw-section>’s width. See Layout tokens
  • Added a Page Layout guide showing how sections, grids and stacks nest to build a full page without breakpoints or utility classes
  • The layout components warn in the console when an enumerated attribute, such as gap or align, is given a value they don’t recognize, then fall back to the default instead of silently changing the layout

1.5.5

  • Fixed <cw-logo> showing no image when its markup had whitespace between the tags, such as <cw-logo image="…"> and </cw-logo> on separate lines. The images were the default slot’s fallback content, which any assigned node hides, including whitespace text. They’re now rendered whenever image or dark-image is set and the default slot has no content other than whitespace

1.5.4

  • Fixed the <cw-logo> docs examples pointing at /assets/images/wordmark.svg, an asset that was never shipped, causing every example on the page to 404. They now use the Cordwainer-logo-light-mode-vector.svg / Cordwainer-logo-dark-mode-vector.svg files that actually exist under /assets/images

1.5.3

  • Added the missing top-level style field to package.json, pointing at dist/themes/light.css. Without it, bundlers and tools that resolve a package’s default stylesheet from that field couldn’t locate the light theme CSS

1.5.2

  • Fixed <cw-segmented-button> sometimes coming up with nothing selected, on some page loads, when components load lazily (for example through the autoloader). It synced its segments — writing each one’s checked state and size — even when <cw-radio-button> hadn’t registered yet; a segment that hasn’t been upgraded yet can’t know its value, so the selected segment was written as unselected, and that value was applied when the segment did upgrade and never corrected. It now skips segments that haven’t been upgraded yet and syncs again once <cw-radio-button> registers. The form value was never affected, only what was shown as selected
  • Fixed a disabled <cw-radio-button> becoming the tab stop of a <cw-segmented-button> when nothing was selected and it was the first segment. The tab stop now goes to the first enabled segment, and moves off a segment that’s disabled later
  • Fixed <cw-segmented-button> not passing a changed size on to its segments — size was only applied when segments were first added, so changing it afterward had no effect
  • Fixed the “Custom Validity” example on the <cw-radio-group> docs page throwing radioGroup.setCustomValidity is not a function on some page loads, and then not starting out invalid as intended. The example waited for <cw-radio> to be defined, not <cw-radio-group>, so with lazy loading it could run before the group had registered. Also fixed the React version of the same example, which referenced a variable that didn’t exist

1.5.1

  • Fixed a radio that’s disabled in markup sometimes coming up enabled and selectable, on some page loads, when components load lazily (for example through the autoloader). Every component is its own import(), so <cw-radio> and <cw-radio-button> can register before or after <cw-radio-group>, in any order. The group synced its radios whenever either kind was registered, including ones that hadn’t been upgraded yet, and assigned disabled = false to them; once they did upgrade, that value silently overrode the disabled attribute, leaving the radio enabled but still reporting aria-disabled="true". <cw-radio-group> now skips radios that haven’t upgraded yet and waits only for the kinds of radio it actually contains. <cw-radio-button> was affected in the opposite registration order
  • Fixed a radio disabled or re-enabled directly (for example radio.disabled = true) being silently reverted the next time the group synced its radios, such as when a radio was added or the group’s size changed. <cw-radio-group> now only changes a radio’s disabled when the group’s own disabled changes, and a radio that was individually disabled still stays disabled after the group is re-enabled
  • Disabled <cw-radio>s can no longer take focus: clicking one used to focus it, and a disabled first (or checked) radio could be the group’s tab stop, so tabbing into the group landed on it. The tab stop now skips disabled radios, and moves off a radio that’s disabled later
  • Disabled <cw-radio-button>s now disable their inner button, so they’re no longer reachable by keyboard focus
  • <cw-radio>’s aria-disabled now always matches its disabled value from its first render; before, the two could disagree until disabled next changed

1.5.0

  • Added <cw-accordion> and <cw-accordion-item> — group multiple collapsible items, keeping only one open at a time by default, or add the multiple attribute to allow several open at once
  • Added <cw-popover>, a trigger-anchored panel for rich or interactive content that doesn’t fit a tooltip (hover-only) or a dropdown (menu-only), positioned with floating-ui and rendered through the native Popover API’s top layer. Setting disabled now also reaches onto the trigger element itself (using its own disabled property when it has one, so it gets correctly-specific disabled styling instead of a CSS override that can lose to the page’s own cascade), and the popup’s box is now exposed as its own body CSS part, split out from the outer popup part
  • Added <cw-segmented-button>, joining radio buttons into a single row that looks like a button group but behaves like a radio group — one selection at a time, submitted with the form like a native radio input
  • Added <cw-stepper> and <cw-stepper-item> for showing progress through multi-step forms, checkouts, and onboarding flows, with horizontal (default) or orientation="vertical" layouts, optional linear step-order enforcement, and per-item error/disabled states
  • Added <cw-avatar-group>, stacking avatars to represent a set of people or objects and collapsing anything past a configurable count into a ”+N” indicator
  • Implemented overflow collapsing for <cw-breadcrumb>: items that don’t fit the available width now collapse into a dropdown menu instead of wrapping or overflowing

1.4.3

  • Added a disabled property to <cw-radio-group> — it implemented CwFormControl (which marks disabled as optional) but never actually declared the property, so radioGroup.disabled = true silently did nothing. Setting it now disables every child <cw-radio>/<cw-radio-button> too, so each one gets its own already-correct disabled styling rather than just looking disabled from the outside; a radio that was individually disabled beforehand stays disabled if the group is later re-enabled. Also excludes the group from constraint validation and blocks click/keyboard interaction while disabled, matching <cw-segmented-button>’s existing behavior.

1.4.2

1.4.1

  • cw-migrate reached 1.0.0 stable after running end-to-end against GoogleChrome/chromium-dashboard (chromestatus.com), a production Lit + TypeScript Shoelace codebase — the real-world test case called for in the v1.4 roadmap. That run surfaced and fixed four gaps: the elements command wasn’t scanning .ts/.js files at all (missing sl-* tags inside Lit html templates, the majority of that project’s Shoelace usage), no command renamed sl-* CSS type selectors, plain style="..." attributes inside Lit templates weren’t covered by the token rewrite, and sl-* selector strings passed to .querySelector/.querySelectorAll/.closest/.matches weren’t renamed. Documented in a new Real-world testing section on the cw-migrate docs page, with a link to the sample migration
  • Added shoelace, shoelace alternative, shoelace fork, shoelace replacement, and migrate from shoelace to the npm package’s keywords, to help people searching for a Shoelace alternative find it

1.4.0

  • Added @cordwainer/cw-migrate, a CLI that automates migrating a Shoelace project to Cordwainer Elements — renaming element tags, CSS custom properties, event names, and TypeScript class/type references across HTML, JSX/TSX, Vue, Angular, and Svelte templates, CSS/SCSS/LESS, and TypeScript/JSX files, plus updating import specifiers and package.json. Ships as its own standalone package rather than living in this repo — run directly against a target project with npx @cordwainer/cw-migrate <path>, independently versioned from @cordwainer/cw-elements, following the same pattern already established by @cordwainer/cw-animations and @cordwainer/cw-localize
  • Added a new Tooling nav section to this docs site for cw-migrate’s documentation (cw-migrate is a command people run, not something they import, so it didn’t fit the existing nav structure) — its docs are authored here alongside everything else even though the code lives in cw-migrate’s own repo, since this Eleventy site is what builds cordwainer.dev
  • Called out cw-migrate from the README and docs homepage for anyone coming from Shoelace

1.3.1

  • Fixed the “An Unlisted Platform” <cw-social-link> example rendering no icon: the docs used name="rss", but the system icon library never had an rss icon. Added it.

1.3.0

  • Added <cw-header>, <cw-footer>, <cw-primary-navigation> (with <cw-primary-navigation-item> and <cw-primary-navigation-menu> for dropdown submenus), <cw-secondary-navigation> (with <cw-secondary-navigation-item>), <cw-social-link>, and <cw-logo> — a full header, footer, and navigation component set, with responsive mobile breakpoints and inline dropdown menus in the primary navigation
  • Added dark/light theme detection to <cw-logo>, automatically falling back between light and dark image variants, plus Spanish localization
  • Added dark-mode support to <cw-data-table>’s loading overlay
  • Added bell, bluesky, cart, discord, facebook, gear, github, instagram, linkedin, mastodon, person, search, threads, tiktok, and youtube icons to the system icon library
  • Gave <cw-data-table-column> its own docs page instead of documenting it inline on the <cw-data-table> page

1.2.3

  • Fixed <cw-data-table> row selection in multi-select mode failing when <cw-data-table> and <cw-data-table-column> load lazily and register out of order
  • Added the missing arrow-up, arrow-down, and arrow-down-up icons to the system icon library, fixing <cw-data-table> sortable columns showing no sort-direction indicator
  • Removed a stray [component-metadata:...] placeholder left over in the <cw-data-table>, <cw-pagination>, <cw-date-picker>, and <cw-time-picker> docs pages
  • Replaced the npm logo in the docs header with a single-color version that themes with the other icons instead of npm’s fixed red/white brand colors
  • Added a full favicon set (favicon.ico, favicon.svg, apple-touch-icon.png, site.webmanifest, and Android/maskable icons)
  • Fixed the Cordwainer logo images 404ing on every docs page except the homepage, caused by a relative path that only resolved correctly from the site root

1.2.2

  • Moved the docs site to a custom domain, cordwainer.dev, replacing the default GitLab Pages URL
  • Added an npm link next to the existing GitLab link in the docs header, and to the README

1.2.1

  • Updated Prettier to 3.9.6 and refreshed dependencies via npm update

1.2.0

  • Added <cw-data-table> and <cw-data-table-column> with sortable columns and single/multi row selection
  • Added a Releasing page documenting how techdocs are published and the steps for cutting alpha/beta and stable releases
  • Backfilled this changelog with entries for every release since 1.0.0
  • Promoted the components added since the 1.0 fork at the top of the README and docs homepage
  • Corrected the Roadmap’s component count (the 1.0 fork shipped 58 components, not 65) and linked the components added since
  • Fixed make-icons.js, build.js, and eleventy.config.cjs resolving node_modules paths relative to the working directory instead of through Node’s module resolution, which broke local builds whenever node_modules is hoisted to a parent workspace root

1.1.1

  • Fixed a documentation regression that listed an incorrect “Since” version for <cw-date-picker>

1.1.0

  • Added <cw-combobox>, a filterable, searchable input with type-ahead filtering, free-text and constrained-to-list selection modes, and multi-select tag chips
  • Added <cw-date-picker> and <cw-time-picker> for calendar- and clock-based selection
  • Added <cw-pagination> for paging through lists and search results
  • Fixed <cw-option> not respecting its hidden attribute
  • Fixed combobox layout, input filtering, and focus-loss issues found during the 1.1 alpha series
  • Cut the release/1.1 maintenance branch; GitLab Pages now publishes the live docs from it instead of main

1.0.3

  • Fixed <cw-option> not respecting its hidden attribute

1.0.2

  • Added the Roadmap page and expanded the Community resources page

1.0.1

  • Republished with no functional changes

1.0.0

  • Hard fork of Shoelace rebranded as Cordwainer Elements. All sl- element prefixes renamed to cw-, CSS variables renamed from --sl- to --cw-, and the npm package changed from @shoelace-style/shoelace to @cordwainer/cw-elements.