Smoothie
4. Patterns
Implementation Guide
Page Structure
Always nest header inside container:
<labs-container medium>
<labs-header center>
<div slot="title">Page Title</div>
<labs-theme-toggle slot="actions" icon-only></labs-theme-toggle>
</labs-header>
<main>
<!-- Your content -->
</main>
</labs-container>
Why? Container provides layout control, header sits at top with consistent spacing. Theme toggle goes in actions slot for toolbar placement.
Header Component Usage
Correct pattern: Use div with slot="title", not h1 attribute
<!-- ✓ CORRECT -->
<labs-header center>
<div slot="title">Page Title</div>
<labs-theme-toggle slot="actions" icon-only></labs-theme-toggle>
</labs-header>
Wrong pattern: Don't use title attribute or h1 tag without slot
<!-- ✗ WRONG -->
<labs-header title="Page Title" center></labs-header>
<labs-header center><h1>Page Title</h1></labs-header>
Button Component Icons
labs-button only supports two icon slots:
- slot="icon-left" — Icon before text
- slot="icon-right" — Icon after text
<!-- ✓ CORRECT -->
<labs-button>
<labs-icon name="add" slot="icon-left"></labs-icon>
Add Item
</labs-button>
<!-- ✓ CORRECT (icon only) -->
<labs-button aria-label="Settings">
<labs-icon name="settings" slot="icon-left"></labs-icon>
</labs-button>
⚠ Using slot="icon" will render as empty circle placeholder (icon won't load)
Container Attributes
Use boolean attributes, not key-value:
<!-- ✓ CORRECT -->
<labs-container medium>...</labs-container>
<labs-container large>...</labs-container>
<labs-container fill>...</labs-container>
<!-- ✗ WRONG -->
<labs-container size="medium">...</labs-container>
Icon Names
Verify icon names exist in labs-icon.js mapping:
<!-- ✓ These exist -->
<labs-icon name="add"></labs-icon>
<labs-icon name="settings"></labs-icon>
<labs-icon name="electric_bolt"></labs-icon>
<labs-icon name="play_arrow"></labs-icon>
<labs-icon name="check"></labs-icon>
<!-- ✗ These DON'T exist (will show empty circle) -->
<labs-icon name="send"></labs-icon>
<labs-icon name="favorite_border"></labs-icon>
<labs-icon name="light_mode"></labs-icon>
For theme toggle, use <labs-theme-toggle> component (handles light/dark mode internally). For other icons, check /libs/smoothie-design-system/v3.0/src/components/labs-icon.js.
Theme Toggle Component
Use labs-theme-toggle for light/dark mode switching:
<!-- Standard with label -->
<labs-theme-toggle></labs-theme-toggle>
<!-- Icon only (compact, for headers) -->
<labs-theme-toggle icon-only></labs-theme-toggle>
Don't build custom theme selectors. The labs-theme-toggle component:
- Handles localStorage persistence
- Broadcasts theme changes to iframes
- Emits 'mode-changed' event
- Manages all internal state
Component Initialization
Import component modules at the top of your page:
<script type="module">
import '/libs/smoothie-design-system/v3.0/src/components/labs-header.js';
import '/libs/smoothie-design-system/v3.0/src/components/labs-button.js';
import '/libs/smoothie-design-system/v3.0/src/components/labs-container.js';
import '/libs/smoothie-design-system/v3.0/src/components/labs-theme-toggle.js';
import '/libs/smoothie-design-system/v3.0/src/components/labs-icon.js';
</script>
CSS Classes for Theming
Apply theme classes to document root:
<script>
(function () {
const root = document.documentElement;
const theme = localStorage.getItem('app-theme') || 'vanilla';
const appearance = localStorage.getItem('app-appearance') || 'light';
root.classList.add(`theme-${theme}`, `appearance-${appearance}`);
})();
</script>
Available themes: vanilla, blueberry, strawberry
Available appearances: light, dark
Common Mistakes Checklist
- Header outside container (should be inside)
- Using h1 without slot in header (use <div slot="title">)
- Using slot="icon" with labs-button (use slot="icon-left" or "icon-right")
- Using size="medium" with labs-container (use just medium attribute)
- Icon names that don't exist in mapping (verify in labs-icon.js)
- Custom theme logic instead of labs-theme-toggle (use the component)
- CSS with escaped newlines (use actual line breaks in stylesheets)