@marioschmidt/design-system-components
v1.8.2
Published
BILD Design System Web Components - Stencil-based component library
Maintainers
Readme
🧩 BILD Design System Components
Part of the BILD Design Ops Pipeline | Token Documentation | Icon Documentation
Stencil-based Web Components for the BILD Design System. Components consume design tokens via CSS Custom Properties and work in any framework.
Framework-specific wrappers available:
- React Wrappers -
@marioschmidt/design-system-react - Vue 3 Wrappers -
@marioschmidt/design-system-vue
These wrappers are co-located in the same packages/components/ directory as they are tightly coupled to the core Stencil components.
📋 Table of Contents
- 📦 Installation
- 🚀 Usage
- ⚛️ React & Vue
- 🧩 Available Components
- 🎨 Theming
- 🌓 Shadow DOM
- 📁 Project Structure
- ⚙️ Development
- 📚 Storybook
- 🔗 Related
- 📄 License
📦 Installation
npm install @marioschmidt/design-system-componentsRecommended: Install together with design tokens:
npm install @marioschmidt/design-system-tokens @marioschmidt/design-system-components🚀 Usage
Option 1: Lazy Loading (Recommended)
import { defineCustomElements } from '@marioschmidt/design-system-components/loader';
// Register all components (lazy-loaded on first use)
defineCustomElements();Option 2: Custom Elements (Auto-Define)
// Import and auto-register all components
import '@marioschmidt/design-system-components/components';Option 3: Individual Components
import { DsButton, DsCard } from '@marioschmidt/design-system-components';HTML Usage
<!DOCTYPE html>
<html>
<head>
<!-- Load design tokens CSS -->
<link rel="stylesheet" href="node_modules/@marioschmidt/design-system-tokens/dist/css/bundles/bild.css">
<!-- Load components -->
<script type="module" src="node_modules/@marioschmidt/design-system-components/dist/esm/index.js"></script>
</head>
<body data-color-brand="bild" data-content-brand="bild" data-theme="light" data-density="default">
<ds-button variant="primary">Click me</ds-button>
<ds-card>
<h2>Card Title</h2>
<p>Card content goes here.</p>
</ds-card>
</body>
</html>⚛️ React & Vue
For better framework integration, use our auto-generated wrapper packages:
React
npm install @marioschmidt/design-system-reactimport { DsButton, DsCard } from '@marioschmidt/design-system-react';
import '@marioschmidt/design-system-tokens/css/bundles/bild.css';
function App() {
return (
<div data-color-brand="bild" data-theme="light">
<DsButton variant="primary" onClick={() => console.log('clicked')}>
Click me
</DsButton>
</div>
);
}Vue 3
npm install @marioschmidt/design-system-vue<script setup>
import { DsButton, DsCard } from '@marioschmidt/design-system-vue';
</script>
<template>
<div data-color-brand="bild" data-theme="light">
<DsButton variant="primary" @click="handleClick">
Click me
</DsButton>
</div>
</template>
<style>
@import '@marioschmidt/design-system-tokens/css/bundles/bild.css';
</style>🧩 Available Components
| Component | Tag | Variants | Description |
|-----------|-----|----------|-------------|
| Button | <ds-button> | primary, secondary, ghost | Interactive button with hover/active states |
| Card | <ds-card> | - | Content container with shadow and padding |
Button
<!-- Primary (default) -->
<ds-button variant="primary">Primary Button</ds-button>
<!-- Secondary -->
<ds-button variant="secondary">Secondary Button</ds-button>
<!-- Ghost -->
<ds-button variant="ghost">Ghost Button</ds-button>Card
<ds-card>
<h2>Card Title</h2>
<p>Card content with automatic styling.</p>
</ds-card>🎨 Theming
Components automatically adapt to brand/theme/density changes via CSS Custom Properties.
Data Attributes
Set these on <body> or any parent element:
| Attribute | Values | Purpose |
|-----------|--------|---------|
| data-color-brand | bild, sportbild | Colors & effects |
| data-content-brand | bild, sportbild, advertorial | Typography & spacing |
| data-theme | light, dark | Color mode |
| data-density | default, dense, spacious | Spacing density |
Brand Examples
<!-- BILD Brand (Light) -->
<body data-color-brand="bild" data-content-brand="bild" data-theme="light" data-density="default">
<ds-button variant="primary">BILD Button</ds-button> <!-- Red -->
</body>
<!-- SportBILD Brand (Dark, Dense) -->
<body data-color-brand="sportbild" data-content-brand="sportbild" data-theme="dark" data-density="dense">
<ds-button variant="primary">Sport Button</ds-button> <!-- Blue -->
</body>
<!-- Advertorial in BILD context -->
<body data-color-brand="bild" data-content-brand="advertorial" data-theme="light">
<ds-button variant="primary">Advertorial Button</ds-button> <!-- BILD colors, Advertorial typography -->
</body>Runtime Switching
// Switch brand at runtime - components update automatically!
document.body.dataset.colorBrand = 'sportbild';
document.body.dataset.theme = 'dark';🌓 Shadow DOM
All components use Shadow DOM for style encapsulation. Design tokens are inherited through CSS Custom Properties:
Light DOM Shadow DOM
─────────────────────────────────────────────────────
<body data-color-brand="bild"> <ds-button>
│ #shadow-root
│ CSS Variables set here: .button {
│ --button-primary-bg: #DD0000 background: var(--button-primary-bg);
│ --button-label-color: #FFF color: var(--button-label-color);
│ /* Inherits from body! */
└────────────────────────────► }
Variables inherit
through Shadow DOMHow It Works
- Token CSS is loaded in the Light DOM (on
<body>or<html>) - CSS Custom Properties inherit through the Shadow DOM boundary
- Components read tokens using
var(--token-name) - No JavaScript needed for theming - pure CSS inheritance
What Inherits
| Token Type | Inheritance | Example |
|------------|-------------|---------|
| Color tokens | ✅ Inherits | var(--button-primary-bg-color) |
| Spacing tokens | ✅ Inherits | var(--button-inline-space) |
| Typography tokens | ✅ Inherits | var(--button-label-font-size) |
| Effects (shadows) | ✅ Inherits | var(--shadow-soft-md) |
📁 Project Structure
apps/
└── docs/ # @bild/docs (Storybook documentation)
├── package.json # Isolated Storybook dependencies
└── stories/
└── foundations/ # Auto-generated foundation docs
├── intro.mdx # Introduction (manual)
├── colors.mdx # Color tokens (auto-generated)
├── typography.mdx # Typography (auto-generated)
├── spacing.mdx # Spacing & density (auto-generated)
└── effects.mdx # Shadows & effects (auto-generated)
packages/components/
├── core/ # This package (@marioschmidt/design-system-components)
│ ├── src/ # Stencil component source
│ │ ├── ds-button/
│ │ │ ├── ds-button.tsx # Component logic
│ │ │ ├── ds-button.css # Component styles (uses tokens)
│ │ │ └── ds-button.stories.ts # Storybook stories
│ │ ├── ds-card/
│ │ │ └── ...
│ │ └── components.d.ts # Generated type definitions
│ │
│ ├── dist/ # Built output (gitignored)
│ │ ├── esm/ # ES Modules
│ │ ├── cjs/ # CommonJS
│ │ ├── components/ # Custom Elements (auto-define)
│ │ ├── loader/ # Lazy loader
│ │ └── types/ # TypeScript definitions
│ │
│ ├── package.json
│ └── README.md
│
├── react/ # @marioschmidt/design-system-react
│ ├── src/ # Auto-generated React wrappers
│ ├── dist/ # Built output
│ └── README.md
│
└── vue/ # @marioschmidt/design-system-vue
├── src/ # Auto-generated Vue wrappers
├── dist/ # Built output
└── README.md⚙️ Development
Prerequisites
Build tokens first (components depend on token CSS):
npm run build:tokensCommands
# Start dev server with hot reload
npm run dev:stencil # Port 3333
# Build components
npm run build:components
# Build everything (tokens + icons + components)
npm run build:all
# Clean build output
npm run cleanCreating New Components
Create component directory:
packages/components/core/src/ds-{name}/ ├── ds-{name}.tsx ├── ds-{name}.css └── ds-{name}.stories.tsComponent structure:
import { Component, Prop, h } from '@stencil/core'; @Component({ tag: 'ds-{name}', styleUrl: 'ds-{name}.css', shadow: true, }) export class Ds{Name} { @Prop() variant: string = 'default'; render() { return ( <div class={`ds-{name} ds-{name}--${this.variant}`}> <slot></slot> </div> ); } }Use design tokens in CSS:
:host { display: block; } .ds-{name} { /* Tokens inherit from Light DOM automatically */ background: var(--surface-color-primary); color: var(--text-color-primary); padding: var(--space-2-x); border-radius: var(--border-radius-md); }
📚 Storybook
Interactive component documentation with live theming.
npm run storybook # Start dev server (port 6006)
npm run build:storybook # Build static site
npm run build:docs # Regenerate foundation docs from tokensFeatures
- 4-Axis Controls: Color Brand, Content Brand, Theme, Density
- Component Stories: All variants with controls
- Styleguide Pages: Colors, Typography, Spacing, Effects (auto-generated)
- Dark Mode Toggle: Synced with design tokens
Auto-Generated Documentation
Foundation pages (Colors, Typography, Spacing, Effects) are automatically generated from token JSON files by scripts/tokens/generate-docs.js. This ensures documentation stays in sync with the actual token values.
# Regenerate docs after token changes
npm run build:docs| Page | Source |
|------|--------|
| Colors | Semantic > Color tokens |
| Typography | Semantic > Typography tokens |
| Spacing | Semantic > Space tokens (Inline, Stack, Gap) |
| Effects | Semantic shadow tokens |
Writing Stories
// ds-button.stories.ts
import type { Meta, StoryObj } from '@storybook/web-components';
import { html } from 'lit';
const meta: Meta = {
title: 'Components/Button',
tags: ['autodocs'],
render: (args) => html`
<ds-button variant=${args.variant}>
${args.label}
</ds-button>
`,
argTypes: {
variant: {
control: 'select',
options: ['primary', 'secondary', 'ghost'],
},
},
};
export default meta;
export const Primary: StoryObj = {
args: { variant: 'primary', label: 'Click me' },
};🔗 Related
| Document | Description | |----------|-------------| | 📖 Main README | Project overview | | 📖 React Wrappers | React wrapper components | | 📖 Vue Wrappers | Vue 3 wrapper components | | 📖 Tokens README | Design tokens documentation | | 📖 Icons README | Icon library documentation | | 📖 CSS Documentation | CSS Custom Properties & Shadow DOM |
📄 License
MIT
Built with ❤️ for the BILD Design System
| Feature | Status | |---------|--------| | Shadow DOM | ✅ | | CSS Custom Properties | ✅ | | 4-Axis Theming | ✅ | | TypeScript | ✅ | | Storybook | ✅ | | React Wrappers | ✅ | | Vue 3 Wrappers | ✅ |
