Components
Components are the building blocks of your design system. In StyleScribe, you document components directly in your SCSS files using annotations.
Creating a Component
File Structure
Each component lives in its own folder:
sass/components/
└── button/
└── button.scss
The folder name becomes the component's slug (URL path).
Basic Annotations
Add a documentation block at the top of your SCSS file:
/**
* @title Button
* @description Interactive button element for user actions
* @group Actions
*/
.ds-button {
/* styles */
}
Required Annotations
| Annotation | Description |
|---|---|
@title |
Display name in documentation |
@description |
What the component does |
@group |
Category for navigation (Actions, Forms, Layout, etc.) |
Using the CLI
The fastest way to create a component:
stylescribe create-component button --group="Actions"
This creates the folder structure and a starter SCSS file with annotations.
Variations
Variations are modifier classes that change appearance.
Simple Format
@variations primary, secondary, danger, outline, ghost
With Descriptions
@variations
- name: primary
description: Main call-to-action, use sparingly per page
- name: secondary
description: Secondary actions, less visual weight
- name: danger
description: Destructive actions like delete
- name: outline
description: Bordered style, transparent background
- name: ghost
description: Minimal styling, blends with background
How Variations Render
StyleScribe generates a preview for each variation. The first @example is used as the template — the variation class is swapped in automatically.
For nested components (dropdown, modal, tabs), ensure your first example has the complete HTML structure:
@examples
- title: Basic Dropdown
code: |
<div class="ds-dropdown">
<button class="ds-dropdown__trigger">Open</button>
<div class="ds-dropdown__menu">
<button class="ds-dropdown__item">Edit</button>
<button class="ds-dropdown__item">Delete</button>
</div>
</div>
Elements
Elements are BEM child elements (e.g., button__icon, button__label).
Simple Format
@elements icon, label, spinner
With Custom HTML
For proper rendering in the interactive playground:
@elements
- name: icon
description: Leading icon
html: <span class="{{class}} ds-icon ds-icon--add"></span>
- name: label
description: Button text
html: <span class="{{class}}">Button</span>
- name: spinner
description: Loading indicator
html: <span class="{{class}} ds-spinner"></span>
The {{class}} placeholder is replaced with the full BEM class.
Examples
Examples show your component in action with real code.
@examples
- title: Primary Button
description: Use for main actions
code: |
<button class="ds-button ds-button--primary">
<span class="ds-button__label">Submit</span>
</button>
- title: With Icon
code: |
<button class="ds-button ds-button--primary">
<span class="ds-button__icon ds-icon ds-icon--add"></span>
<span class="ds-button__label">Add Item</span>
</button>
- title: Button Group
fullWidth: true
code: |
<div class="ds-button-group">
<button class="ds-button">One</button>
<button class="ds-button">Two</button>
<button class="ds-button">Three</button>
</div>
Example Properties
| Property | Description |
|---|---|
title |
Example name (required) |
description |
Optional explanation |
code |
HTML code (use | for multiline) |
fullWidth |
Render at full width (default: false) |
Dependencies
If your component uses other components, declare them:
@dependencies icon, spinner
This ensures the required CSS is loaded in previews.
Complete Example
/**
* @title Button
* @navtitle Button
* @description Interactive button for user actions with multiple variants
* @group Actions
* @order 1
* @verified true
*
* @variations
* - name: primary
* description: Main call-to-action
* - name: secondary
* description: Secondary actions
* - name: danger
* description: Destructive actions
* - name: outline
* description: Bordered, transparent background
* - name: ghost
* description: Minimal styling
* - name: sm
* description: Small size
* - name: lg
* description: Large size
*
* @elements
* - name: icon
* description: Optional icon
* html: <span class="{{class}} ds-icon ds-icon--add"></span>
* - name: label
* description: Button text
* html: <span class="{{class}}">Button</span>
* - name: spinner
* description: Loading state indicator
* html: <span class="{{class}} ds-spinner ds-spinner--sm"></span>
*
* @dependencies icon, spinner
*
* @examples
* - title: Primary Button
* code: |
* <button class="ds-button ds-button--primary">
* <span class="ds-button__label">Get Started</span>
* </button>
* - title: With Icon
* code: |
* <button class="ds-button ds-button--secondary">
* <span class="ds-button__icon ds-icon ds-icon--download"></span>
* <span class="ds-button__label">Download</span>
* </button>
* - title: Loading State
* code: |
* <button class="ds-button ds-button--primary" disabled>
* <span class="ds-button__spinner ds-spinner ds-spinner--sm"></span>
* <span class="ds-button__label">Saving...</span>
* </button>
*/
@layer components {
.ds-button {
/* Component tokens */
--button-bg: var(--color-semantic-surface);
--button-text: var(--color-semantic-text);
--button-border: var(--color-semantic-border);
--button-radius: var(--border-radius-md);
--button-padding-x: var(--spacing-md);
--button-padding-y: var(--spacing-sm);
/* Base styles */
display: inline-flex;
align-items: center;
gap: var(--spacing-xs);
padding: var(--button-padding-y) var(--button-padding-x);
background: var(--button-bg);
color: var(--button-text);
border: 1px solid var(--button-border);
border-radius: var(--button-radius);
font-family: var(--font-family-base);
font-weight: var(--font-weight-medium);
cursor: pointer;
transition: all 0.2s ease;
&:hover {
filter: brightness(0.95);
}
&:disabled {
opacity: 0.5;
cursor: not-allowed;
}
/* Variations */
&--primary {
--button-bg: var(--color-primary-500);
--button-text: var(--color-accessibility-on-primary);
--button-border: var(--color-primary-500);
}
&--secondary {
--button-bg: var(--color-neutral-100);
--button-text: var(--color-neutral-700);
--button-border: var(--color-neutral-200);
}
&--danger {
--button-bg: var(--color-danger-500);
--button-text: white;
--button-border: var(--color-danger-500);
}
/* Size variants */
&--sm {
--button-padding-x: var(--spacing-sm);
--button-padding-y: var(--spacing-xs);
font-size: var(--font-size-sm);
}
&--lg {
--button-padding-x: var(--spacing-lg);
--button-padding-y: var(--spacing-md);
font-size: var(--font-size-lg);
}
}
}
Adding to Navigation
Components are automatically grouped by their @group annotation. Control the order within a group with @order:
@group Actions
@order 1 // First in the Actions group
Group Order
Configure group order in .stylescriberc.json:
{
"components": {
"groupOrder": ["Actions", "Forms", "Layout", "Feedback", "Navigation"]
}
}
Class Prefix
Use ds- prefix in your source files. The configured prefix is applied at build time:
{
"classPrefix": "myapp-"
}
Source: .ds-button → Output: .myapp-button
Additional Annotations
| Annotation | Description |
|---|---|
@navtitle |
Short name for navigation |
@order |
Sort order within group |
@verified |
Mark as production-ready |
@draft |
Mark as work-in-progress |
@role |
ARIA role for examples |
@maintag |
Primary HTML tag (default: div) |
@classname |
Override auto-detected class name |
See Annotations Reference for complete documentation.