Tegel Design System

Tegel is Scania's open-source design system, powering digital products across vanilla web, React, Angular, and Power Apps. I joined as a consultant in October 2024 and have been a collaborator and codeowner on the repo since, working across the library rather than owning a single component.

The problem Tegel solves is scale. Components ship to teams across multiple frontend stacks, so any drift between Figma and code — or any single accessibility regression — multiplies across every product downstream. When I joined, components had inconsistent focus, contrast, and aria handling, motion was hand-rolled per component, and there was no shared semantic-token layer keeping design and code in sync.

My work has spanned several threads. The biggest was a sustained accessibility sweep across the component library — standardizing the aria-label pattern, forwarding aria-invalid to inputs, and adding a dedicated Accessibility section to Storybook so every component documents its compliance. A parallel color-contrast pass hit WCAG targets without breaking the Scania palette. I built the motion system from scratch — motion variables, Storybook docs, then a rollout through the core components — and approached the focus system the same way: shared mixin and color variables, then a migration of the focus ring onto the new tokens layer. Currently I'm driving the Figma-to-semantic-token rollout: I wrote the sync script and have been migrating components, foundations, and brand-aware primitives onto the new layer. Alongside that I've shipped new components, expanded the icon library, and extended the color system. On the infra side I automated the beta-release workflow, owned a major Stencil core upgrade end-to-end (ship → revert → re-ship with a type-defs patch), and tag production releases. On docs I flipped Tegel from beta to production, wrote the testing guide, and added a designer-approval checklist to the PR template.

Architecturally, Tegel is a Stencil-based monorepo. Components are authored once as web components and shipped as native custom elements, with auto-generated React and Angular wrappers so each ecosystem feels native. Tokens flow Figma → JSON → Style Dictionary → CSS custom properties consumed by every component, which is why a token PR ripples across the whole library. Storybook is the canonical playground; Playwright + axe-core handle visual and accessibility regression. The runtime is CSP-safe via Constructable StyleSheets and csp-nonce support. A few decisions worth calling out: Stencil over Lit or native custom elements buys auto-generated wrappers and typed JSX at the cost of a build dependency; web components over a React-first approach was slower to staff but meant Angular and vanilla teams weren't stranded; and Tegel intentionally stops at components and tokens, leaving layout decisions to consumers.

The harder problems were standardizing focus across heterogeneous components without breaking each one's existing styles, and a Stencil core upgrade that broke type defs downstream — I owned the rollback and re-shipped with a postinstall patch. Looking back, earlier investment in automated accessibility and contrast checks in CI would have caught most of the issues before review, and the Figma-to-token round-tripping should have started a year earlier — would have made every component PR cheaper.

Tegel is in production today, consumed across Scania's internal and customer-facing products, and published on npm as @scania/tegel and its React, Angular, and styles wrappers. Across 19 months I've shipped 100 merged PRs, authored new components, driven a system-wide token migration, and watched the package move from beta to 1.x production status during my contribution.