Knobs
Knobs are interactive controls that let you test your custom elements by manipulating their attributes, properties, and CSS custom properties in real-time.
How Knobs Work
Knobs are automatically generated from your Custom Elements Manifest. The dev server reads your component’s API documentation and creates appropriate controls for each attribute, property, and CSS variable.
The Workflow
Everything derives from your component documentation - the manifest is the single source of truth.
Manifest to Knobs Mapping
Knobs are generated from the manifest entries for each element. The dev server looks at:
Attributes (attributes array in manifest):
- Each attribute becomes a knob based on its
typefield type: { text: "boolean" }→ Switch controltype: { text: "string" }→ Text inputtype: { text: "'a' | 'b' | 'c'" }→ Select dropdown
Properties (members array where kind: "field"):
- JavaScript properties not reflected to attributes
- Same type-to-control mapping as attributes
- Useful for complex data that doesn’t serialize to strings
CSS Custom Properties (cssProperties array):
- CSS variables defined on the element
- Color values get a color picker
- Other values get text input
To document your components for knobs, see the Generate documentation
which covers JSDoc syntax for @attr, @property, @cssprop, and other tags.
Knob Types
The dev server generates different controls based on the type information in your manifest:
| Type | Control | Notes |
|---|---|---|
boolean | Switch | Toggle on/off for boolean values |
string | Text input | Single-line text entry |
number | Number input | Numeric entry with increment/decrement |
'a' | 'b' | 'c' | Select dropdown | Dropdown with defined options |
| CSS color value | Color picker | Visual color selector with hex input |
Boolean Knobs
For boolean attributes/properties:
/**
* @attr {boolean} disabled
*/Generates a checkbox. When checked, the attribute is added; unchecked, it’s removed.
Enum Knobs
For union types (enums):
/**
* @attr {'primary' | 'secondary' | 'danger'} variant
*/Generates a select dropdown with options: primary, secondary, danger.
Number Knobs
For numeric types:
/**
* @property {number} count
*/Generates a number input with increment/decrement controls.
Color Knobs
CSS custom properties with color values:
/**
* @cssprop --bg-color - Background color (default: #ff0000)
*/Generates a dual control: color picker + text input for precise hex values.
Knob Categories
Knobs are organized into three collapsible sections:
- Attributes - DOM attributes (e.g.,
disabled,variant) - Properties - JavaScript properties (e.g.,
value,data) - CSS Properties - CSS custom properties (e.g.,
--bg-color)
You can expand/collapse each section in the UI.
Knobs for All Elements
The dev server generates knobs for every custom element in your demo that’s documented in the manifest. Each element gets its own labeled group of controls.
Element detection:
- The dev server scans your demo HTML for custom elements
- For each element found, it looks up the manifest documentation
- If documented, a knob group is created with controls for that element’s API
Instance labeling: When you have multiple instances of the same element, each gets a unique label using:
#id(if element has anidattribute)- Text content (first 20 characters)
aria-label- Fallback: “tag-name No. N”
Example:
<my-card id="card-1">
<h2 slot="title">First Card</h2>
</my-card>
<my-card id="card-2">
<h2 slot="title">Second Card</h2>
</my-card>
<my-button variant="primary">Click Me</my-button>The sidebar shows:
- my-card section:
- #card-1 (knobs for first card)
- #card-2 (knobs for second card)
- my-button section:
- my-button No. 1 (knobs for button)
Each element’s knobs are independent - changing a knob updates only that specific instance.
State Synchronization
Knobs stay synchronized with your elements:
- Initial values come from demo HTML attributes
- Changing a knob updates the element immediately
- Manual changes (via DevTools) don’t update knobs (one-way binding)
How to Use Knobs
- Run your demo in
cem serve - Open the sidebar (desktop) or menu (mobile)
- Find your element in the knobs section
- Adjust controls to test different states
- See live updates in the demo
Troubleshooting
No knobs appearing
Check:
- Manifest has API docs - Run
cem generateand verifycustom-elements.jsonhas attributes/properties/cssProperties - Component is in demo - The element must be present in your demo HTML
- Documentation syntax - Use proper JSDoc tags (
@attr,@property,@cssprop)
Wrong control type
If a string shows a checkbox or vice versa:
- Check type annotation - Ensure
@attr {boolean}or@attr {string}is correct - Regenerate manifest - Run
cem generateafter fixing JSDoc - Restart serve - Changes to manifest require server restart
Knob doesn’t update element
If changing a knob has no effect:
- Check attribute reflection - Ensure your component responds to attribute changes
- Use attributeChangedCallback - For reactive attributes
- Check console - Look for JavaScript errors
Multiple instances not working
If multi-instance detection fails:
- Add IDs - Give elements unique
idattributes for better labels - Check HTML structure - Elements must be at same level or nested consistently
- Verify tag names - All instances must have the same tag name
Example: Complete Component
Here’s a well-documented component that gets full knobs support:
/**
* A customizable button component
*
* @attr {string} variant - Visual style: 'primary', 'secondary', 'danger'
* @attr {boolean} disabled - Disables the button
* @attr {string} label - Accessible label for the button
*
* @property {number} clickCount - Number of times button was clicked
*
* @cssprop --button-bg - Background color (default: #0066cc)
* @cssprop --button-padding - Internal padding (default: 8px 16px)
*
* @customElement my-button
*/
class MyButton extends HTMLElement {
// Implementation...
}This generates:
- Attributes: variant (select), disabled (checkbox), label (text)
- Properties: clickCount (number)
- CSS Properties: –button-bg (color), –button-padding (text)
What’s Next?
- Generate Docs - Learn JSDoc syntax for documentation
- Buildless Development - Write TypeScript and import CSS without build steps
- Getting Started - Set up your first demo