@c8y/style
Version:
Styles for Cumulocity IoT applications
486 lines (350 loc) • 13.5 kB
Markdown
# Variables Directory
> **⚠️ Important Notice**: This directory contains LESS variable files for **backward compatibility only**. LESS variable overriding is deprecated and no longer functional.
---
## For End Users: LESS Variable Deprecation
### ⚠️ What Changed
**LESS variable overriding is deprecated and no longer applies branding changes.**
If you were previously customizing your application with LESS variable overrides like this:
```less
// ❌ DEPRECATED - No longer works
@import '~@c8y/style/extend.less';
@brand-primary: #custom-color;
@navigator-bg-color: #custom-nav;
@header-text-color: #custom-header;
```
**This approach no longer applies your customizations** because `@c8y/style` now uses SCSS, not LESS, as the primary build system (January 2026).
### ✅ Migration Options
#### Option 1: CSS Custom Properties (Recommended)
Use CSS custom properties for theming at build time or runtime:
```css
/* Override in your custom CSS/SCSS */
:root {
--brand-primary: #1976d2;
--navigator-bg-color: #1565c0;
--main-header-background-default: #ffffff;
--main-header-text-color-default: #333333;
}
```
**Runtime configuration** using application options:
```typescript
import { ApplicationOptions } from '@c8y/ngx-components';
export const options: ApplicationOptions = {
brandingCssVars: {
'brand-primary': '#1976d2',
'navigator-bg-color': '#1565c0',
'main-header-background-default': '#ffffff'
}
};
```
#### Option 2: Branding Editor (No Code Required)
Use the **Branding Editor** in the Cumulocity Administration app to configure:
- Brand colors
- Logos
- Fonts
- Custom CSS
This provides a UI for customization without any code changes.
#### Option 3: SCSS Variables (Advanced)
For build-time customization with SCSS:
```scss
// Import with variable configuration
@use '~@c8y/style/variables' with (
$use-relative-paths: true
);
```
> **Note:** SCSS uses a modern module system where variables are scoped and must be explicitly configured using `@use ... with` syntax.
### Variable Mapping Reference
| LESS (Deprecated) | CSS Custom Property | Description |
|-------------------|---------------------|-------------|
| `@brand-primary` | `--brand-primary` | Primary brand color |
| `@brand-complementary` | *deprecated* | Use `--brand-dark` or `--brand-light` instead |
| `@brand-dark` | `--brand-dark` | Dark brand color |
| `@navigator-bg-color` | `--navigator-bg-color` | Navigator background |
| `@navigator-text-color` | `--navigator-text-color` | Navigator text color |
| `@headerColor` | `--main-header-background-default` | Header background |
| `@header-text-color` | `--main-header-text-color-default` | Header text color |
| `@font-family-base` | `--font-family-base` | Base font family |
### Documentation & Resources
- [Branding Tokens](../../codex/content/design-system/design-tokens/branding-tokens.md) - Complete list of CSS custom properties
- [Application Styles](../../codex/content/common-tasks/application-styles.md) - Styling guide
- [c8y-design-tokens](https://github.com/Cumulocity-IoT/c8y-design-tokens) - Design tokens repository
---
## For Contributors: Technical Guide
This directory contains SCSS and LESS variable files. SCSS files use the SASS module system (`@use` and `@forward`), while LESS files are maintained for backward compatibility.
### Table of Contents
- [Directory Structure](#directory-structure)
- [Usage](#usage)
- [Variable Organization](#variable-organization)
- [Migration from LESS](#migration-from-less)
- [Adding New Variables](#adding-new-variables)
- [SCSS Module System](#scss-module-system)
- [Troubleshooting](#troubleshooting)
## Directory Structure
```
variables/
├── index.scss # SCSS main entry point - import this file
├── index.less # LESS main entry point (maintained for releases)
├── README.md # This file
│
├── dashboard-themes/ # Dashboard theme overrides
│ ├── _branded-dashboard.{scss,less}
│ ├── _dark-dashboard.{scss,less}
│ ├── _transparent-dashboard.{scss,less}
│ └── _white-dashboard.{scss,less}
│
├── tokens/ # Design tokens from design system
│ ├── c8y-design-tokens.scss
│ └── c8y-design-tokens-dark.scss
│
└── [variable files] # 34 paired SCSS/LESS files
├── _color-defaults.{scss,less}
├── _color-vars.{scss,less}
├── _components-vars.{scss,less}
├── _forms-vars.{scss,less}
├── _buttons-vars.{scss,less}
├── _alert-vars.{scss,less}
├── _badge-vars.{scss,less}
├── _typography-vars.{scss,less}
├── _layout-vars.{scss,less}
└── ... (and 25 more paired files)
```
**Note:** Each variable file exists in both `.scss` and `.less` formats. SCSS files are used for builds; LESS files are maintained for backward compatibility.
## Usage
### Basic Import
To use variables in your SCSS file, import the main index:
```scss
@use "../../variables/index" as *;
.my-component {
color: $brand-primary;
padding: $size-16;
background: $component-background-default;
}
```
### With Namespace (Recommended for Clarity)
```scss
@use "../../variables/index" as vars;
.my-component {
color: vars.$brand-primary;
padding: vars.$size-16;
}
```
### Configuring Variables
Some variable modules accept configuration:
```scss
@use "../../variables/index" with (
$use-relative-paths: true
);
```
## Variable Organization
### Current Structure
Variables are organized in flat files with paired SCSS/LESS implementations:
- **_color-defaults.scss** - Default color palette
- **_color-vars.scss** - Semantic color mappings
- **_components-vars.scss** - Component-level variables
- **_forms-vars.scss** - Form-specific variables
- **_buttons-vars.scss** - Button-specific variables
- **_typography-vars.scss** - Font and text variables
- **_layout-vars.scss** - Grid and layout variables
- **_scaffolding.scss** - Base scaffolding with asset paths
### Variable Naming Convention
Variables follow the pattern:
```scss
// Component-based
$component-{property}-{variant}
$component-background-default
$component-border-width
$component-padding-base-horizontal
// Semantic colors
$brand-primary
$brand-dark
$brand-light
// Layout/spacing (size system)
$size-base // 8px base unit
$size-8 // 8px
$size-16 // 16px
$size-24 // 24px
$size-32 // 32px
// Typography
$font-size-base
$font-size-small
$line-height-base
$font-family-base
```
## Migration from LESS
### Key Differences
| LESS | SCSS | Notes |
|------|------|-------|
| `@import` | `@use` / `@forward` | Module system with namespacing |
| `@variable` | `$variable` | Variable prefix changed |
| `.mixin()` | `@include mixin()` | Mixin calls |
| Lazy loading | Explicit dependencies | Must declare all imports |
| Guards `when` | `@if` / `@else` | Conditional logic changed |
### Variable Resolution
The `index.scss` file handles duplicate variables using `@forward hide`:
```scss
// Hide duplicate variables from color-vars
@forward '_color-vars' hide
$component-background-default,
$component-border-width,
$component-border-style;
```
This prevents conflicts when multiple modules define the same variable.
### Removed Features
**LESS Guards** - SCSS doesn't support LESS-style conditional guards (`& when`). Code that depended on guards has been:
- Removed if it was legacy/deprecated behavior
- Converted to always-on if it's standard behavior
- Documented with instructions for custom override if needed
Example from `_navigator.scss`:
```scss
// LESS (conditional):
& when not(@appBranding='') {
.c8y-icon { display: none !important; }
}
// SCSS (removed - document override path):
// To hide icons, add to your custom CSS:
// .navigator .title .c8y-icon { display: none !important; }
```
## LESS/SCSS Dual Maintenance
### Overview
Both LESS and SCSS files are maintained in this directory:
- **SCSS files**: Used for builds (primary)
- **LESS files**: Maintained for backward compatibility
- **Both must be kept in sync** to ensure consistency
### When Working with Variables
**Important**: When modifying variables, you must update both SCSS and LESS files:
1. **Make changes in SCSS file** (primary)
```scss
// _buttons-vars.scss
$btn-primary-bg: $brand-primary !default;
```
2. **Sync to LESS file** (convert syntax)
```less
// _buttons-vars.less
@btn-primary-bg: @brand-primary;
```
3. **Commit both files together**
```bash
git add packages/style/variables/_buttons-vars.{scss,less}
git commit -m "Update button variables"
```
### Syntax Quick Reference
| SCSS | LESS | Notes |
| ---- | ---- | ----- |
| `$variable` | `@variable` | Variable prefix |
| `@include mixin()` | `.mixin()` | Mixin calls |
| `@mixin name()` | `.name()` | Mixin definitions |
| `@use 'file'` | `@import 'file'` | Imports |
| `#{$var}` | `@{var}` | Interpolation |
### Pre-commit Hook
A pre-commit hook verifies LESS/SCSS sync:
- Detects SCSS changes
- Checks if corresponding LESS file is updated
- Compiles both preprocessors
- Blocks commit if compilation fails
## Adding New Variables
### 1. Choose the Right File
- **Component-specific** → Add to `_components-vars.scss`
- **Form-related** → Add to `_forms-vars.scss`
- **Color** → Add to `_color-vars.scss`
- **Layout/spacing** → Add to `_layout-vars.scss`
- **New category** → Create new file (see step 2)
### 2. Create a New Variable File
If creating a new category:
```scss
// variables/_my-new-vars.scss
@use 'color-defaults' as *; // Import dependencies if needed
$my-variable: value !default;
$my-other-variable: $gray-60 !default;
```
### 3. Register in index.scss
Add your new file to `variables/index.scss`:
```scss
// Import and make available
@use '_my-new-vars' as *;
@forward '_my-new-vars';
```
Position matters! Place it after dependencies but before files that use it.
### 4. Use !default Flag
Always use `!default` for variables that should be customizable:
```scss
$my-variable: #007bff !default; // ✅ Can be overridden
$my-constant: #007bff; // ❌ Cannot be overridden
```
## SCSS Module System
### @use vs @import
**Never use `@import`** - it's deprecated and will be removed in Dart Sass 3.0.
```scss
// ❌ Old way (deprecated)
@import 'variables/index';
// ✅ New way
@use 'variables/index' as *;
```
### @use Rules
1. **Must be at the top** - No @use statements after regular CSS
2. **Each file once** - Can't @use the same file twice in one file
3. **Namespaced by default** - Use `as *` to add to global scope
4. **Private members** - Variables starting with `-` or `_` are private
### @forward for Re-exporting
The `index.scss` uses `@forward` to re-export all variables:
```scss
@use '_color-vars' as *; // Make available in this file
@forward '_color-vars'; // Re-export for consumers
```
This allows a single import point: `@use 'variables/index' as *;`
### Configuration with 'with'
Pass configuration to modules:
```scss
@use '_scaffolding' with (
$use-relative-paths: true
);
```
Note: Can't use both `with` and `as *` together. Use separately:
```scss
@use '_scaffolding' with ($use-relative-paths: true); // Configure
@forward '_scaffolding' hide $use-relative-paths; // Re-export but hide config var
```
## Troubleshooting
### "Undefined variable"
**Cause**: File doesn't import variables index.
**Solution**: Add to top of file:
```scss
@use "../../variables/index" as *;
```
### "This variable is available from multiple global modules"
**Cause**: Multiple modules define the same variable without hiding duplicates.
**Solution**: Use `@forward hide` in `index.scss`:
```scss
@forward '_color-vars' hide $duplicate-variable;
```
### "expected ';'"
**Cause**: Can't use `@use ... with (...) as *;`
**Solution**: Remove `as *`:
```scss
// ❌ Wrong
@use '_module' with ($var: value) as *;
// ✅ Right
@use '_module' with ($var: value);
@forward '_module';
```
### Circular dependency
**Cause**: File A imports B, B imports A.
**Solution**: Restructure to use a third file for shared variables, or use `@forward` instead of `@use` where appropriate.
### "The target selector was not found"
**Cause**: `@extend` references a class that doesn't exist or isn't loaded yet.
**Solution**: Add `!optional` flag:
```scss
@extend .some-class !optional;
```
## Best Practices
1. **Always import variables/index** - Don't import individual variable files
2. **Use semantic variable names** - Prefer `$component-background-default` over `$white`
3. **Document custom variables** - Add comments explaining usage
4. **Use !default for customization** - Allow variables to be overridden
5. **Avoid duplication** - Reuse existing variables when possible
6. **Namespace complex imports** - Use `as vars` for clarity in large files
7. **Keep variables DRY** - Define once, reference everywhere
## Related Documentation
- [SASS Module System](https://sass-lang.com/documentation/at-rules/use)
- [SASS @forward](https://sass-lang.com/documentation/at-rules/forward)
- [SASS Variables](https://sass-lang.com/documentation/variables)
- [Branding Tokens](../../codex/content/design-system/design-tokens/branding-tokens.md) - CSS custom properties
- [Application Styles](../../codex/content/common-tasks/application-styles.md) - Styling guide