Initial commit
This commit is contained in:
12
.claude-plugin/plugin.json
Normal file
12
.claude-plugin/plugin.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "quarto",
|
||||
"description": "Collection of skills for Quarto document creation",
|
||||
"version": "0.0.0-2025.11.28",
|
||||
"author": {
|
||||
"name": "Garrick Aden-Buie (Posit, PBC)",
|
||||
"email": "garrick@posit.co"
|
||||
},
|
||||
"skills": [
|
||||
"./skills/brand-yml"
|
||||
]
|
||||
}
|
||||
3
README.md
Normal file
3
README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# quarto
|
||||
|
||||
Collection of skills for Quarto document creation
|
||||
68
plugin.lock.json
Normal file
68
plugin.lock.json
Normal file
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"$schema": "internal://schemas/plugin.lock.v1.json",
|
||||
"pluginId": "gh:posit-dev/skills:quarto",
|
||||
"normalized": {
|
||||
"repo": null,
|
||||
"ref": "refs/tags/v20251128.0",
|
||||
"commit": "f026c20bc2cfe1047a6bc3351b6c4d7902ef1720",
|
||||
"treeHash": "ce436a7c5d8d9ef05ddffe2881164ced6bc9608f69ed15a10a6d5eb791a26fb7",
|
||||
"generatedAt": "2025-11-28T10:27:40.229594Z",
|
||||
"toolVersion": "publish_plugins.py@0.2.0"
|
||||
},
|
||||
"origin": {
|
||||
"remote": "git@github.com:zhongweili/42plugin-data.git",
|
||||
"branch": "master",
|
||||
"commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390",
|
||||
"repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data"
|
||||
},
|
||||
"manifest": {
|
||||
"name": "quarto",
|
||||
"description": "Collection of skills for Quarto document creation"
|
||||
},
|
||||
"content": {
|
||||
"files": [
|
||||
{
|
||||
"path": "README.md",
|
||||
"sha256": "4b23f4c6f5763c0ceea2addbe86c6fcfb02db59745e85c637a2516a507832d94"
|
||||
},
|
||||
{
|
||||
"path": ".claude-plugin/plugin.json",
|
||||
"sha256": "1e734b1cecbf4327e77dce3f79afd900ccaf4fc93c44d718b859257b31e9cc84"
|
||||
},
|
||||
{
|
||||
"path": "skills/brand-yml/README.md",
|
||||
"sha256": "3ead89473df4809ad5d7effbbe513a691de054acd985e808025ff0726d0241e6"
|
||||
},
|
||||
{
|
||||
"path": "skills/brand-yml/SKILL.md",
|
||||
"sha256": "25ac6c5b31223486df06ea742f952ff608a186dfa07f801d3dab10fdf52a0ebc"
|
||||
},
|
||||
{
|
||||
"path": "skills/brand-yml/references/brand-yml-in-r.md",
|
||||
"sha256": "780fb3bbe9a2750ca5b8ad6e26ee33252442111a6f2304cb94b9dfacf3ca1f40"
|
||||
},
|
||||
{
|
||||
"path": "skills/brand-yml/references/shiny-r.md",
|
||||
"sha256": "0109581d56119a7a6c1dbb1b06254deee018ef922da2ceec2a7039b1244cb59d"
|
||||
},
|
||||
{
|
||||
"path": "skills/brand-yml/references/quarto.md",
|
||||
"sha256": "81427cd4b7154faa638d5e5e56a569239cca83d13f3a208bbf2d20f43e29d30e"
|
||||
},
|
||||
{
|
||||
"path": "skills/brand-yml/references/brand-yml-spec.md",
|
||||
"sha256": "4c1c8800cb9a80563a78ba3b7ac7590f775535fc91c338f04e0b9ed61e5ec606"
|
||||
},
|
||||
{
|
||||
"path": "skills/brand-yml/references/shiny-python.md",
|
||||
"sha256": "6d034f3bba828070478c62e2b8272ea6572971f2fd607b1128504d50125cf2db"
|
||||
}
|
||||
],
|
||||
"dirSha256": "ce436a7c5d8d9ef05ddffe2881164ced6bc9608f69ed15a10a6d5eb791a26fb7"
|
||||
},
|
||||
"security": {
|
||||
"scannedAt": null,
|
||||
"scannerVersion": null,
|
||||
"flags": []
|
||||
}
|
||||
}
|
||||
82
skills/brand-yml/README.md
Normal file
82
skills/brand-yml/README.md
Normal file
@@ -0,0 +1,82 @@
|
||||
# brand.yml Skill
|
||||
|
||||
Create and use `_brand.yml` files for consistent branding across Shiny applications and Quarto documents.
|
||||
|
||||
## What This Skill Does
|
||||
|
||||
This skill helps Claude:
|
||||
- Create `_brand.yml` files from brand guidelines
|
||||
- Apply brand styling to Shiny for R apps using bslib
|
||||
- Apply brand styling to Shiny for Python apps using ui.Theme
|
||||
- Use brand.yml in Quarto documents, presentations, and PDFs
|
||||
- Troubleshoot brand integration issues
|
||||
|
||||
## When to Use
|
||||
|
||||
Use this skill when working with:
|
||||
- Brand styling and corporate identity
|
||||
- Colors, fonts, and logos in Shiny or Quarto
|
||||
- Creating or modifying brand.yml files
|
||||
- Applying consistent branding across multiple projects
|
||||
|
||||
## What is brand.yml?
|
||||
|
||||
brand.yml is a YAML-based specification that translates brand guidelines into a portable, machine-readable format. It enables consistent styling across Shiny apps (R and Python) and Quarto documents (HTML, PDFs, presentations, dashboards) from a single `_brand.yml` file.
|
||||
|
||||
## Key Features
|
||||
|
||||
- **Complete specification**: Full brand.yml spec with all sections, fields, and validation rules
|
||||
- **Framework integration guides**: Separate guides for Shiny R, Shiny Python, and Quarto
|
||||
- **Self-contained**: All necessary information to create and use brand.yml files without external documentation
|
||||
- **Best practices**: Guidance on file structure, naming conventions, and common patterns
|
||||
|
||||
## Skill Structure
|
||||
|
||||
```
|
||||
brand-yml/
|
||||
├── SKILL.md # Main skill file with workflows and decision tree
|
||||
└── references/
|
||||
├── brand-yml-spec.md # Complete brand.yml specification
|
||||
├── shiny-r.md # Shiny for R integration (bslib)
|
||||
├── shiny-python.md # Shiny for Python integration (ui.Theme)
|
||||
└── quarto.md # Quarto integration (all formats)
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
The skill automatically loads based on keywords related to brand styling, colors, fonts, or brand.yml files. Claude will:
|
||||
|
||||
1. Determine the user's goal (creating, using, or troubleshooting)
|
||||
2. Load the appropriate reference documentation
|
||||
3. Guide the user through the workflow
|
||||
4. Create or modify files as needed
|
||||
|
||||
## Examples
|
||||
|
||||
**Creating a brand.yml file:**
|
||||
> "Create a _brand.yml file for our company with primary color #0066cc and Inter font from Google Fonts"
|
||||
|
||||
**Applying to Shiny R:**
|
||||
> "Add brand styling to this Shiny app using our _brand.yml file"
|
||||
|
||||
**Applying to Quarto:**
|
||||
> "Use our brand colors in this Quarto presentation"
|
||||
|
||||
**Troubleshooting:**
|
||||
> "Why aren't the brand colors showing up in my Shiny app?"
|
||||
|
||||
## Marketplace Registration
|
||||
|
||||
This skill is registered in two marketplace categories:
|
||||
|
||||
- **shiny**: For Shiny app developers
|
||||
- **quarto**: For Quarto document creators
|
||||
|
||||
Both point to the same skill directory but provide context-appropriate discovery.
|
||||
|
||||
## Related Resources
|
||||
|
||||
- [brand.yml project](https://posit-dev.github.io/brand-yml/)
|
||||
- [Shiny for R brand.yml guide](https://rstudio.github.io/bslib/articles/brand-yml/)
|
||||
- [Shiny for Python brand.yml docs](https://shiny.posit.co/py/api/core/ui.Theme.html#shiny.ui.Theme.from_brand)
|
||||
- [Quarto brand.yml docs](https://quarto.org/docs/authoring/brand.html)
|
||||
383
skills/brand-yml/SKILL.md
Normal file
383
skills/brand-yml/SKILL.md
Normal file
@@ -0,0 +1,383 @@
|
||||
---
|
||||
name: brand-yml
|
||||
description: >
|
||||
Create and use brand.yml files for consistent branding across Shiny apps and Quarto documents.
|
||||
Use when working with brand styling, colors, fonts, logos, or corporate identity in Shiny or
|
||||
Quarto projects. Covers: (1) Creating new _brand.yml files from brand guidelines, (2) Applying
|
||||
brand.yml to Shiny for R apps with bslib, (3) Applying brand.yml to Shiny for Python apps with
|
||||
ui.Theme, (4) Using brand.yml in Quarto documents, presentations, dashboards, and PDFs, (5)
|
||||
Modifying existing brand.yml files, (6) Troubleshooting brand integration issues. Includes
|
||||
complete specifications and framework-specific integration guides.
|
||||
---
|
||||
|
||||
# brand.yml Skill
|
||||
|
||||
Create and use `_brand.yml` files for consistent branding across Shiny applications and Quarto documents.
|
||||
|
||||
## What is brand.yml?
|
||||
|
||||
brand.yml is a YAML-based format that translates brand guidelines into a machine-readable file usable across Shiny and Quarto. A single `_brand.yml` file defines:
|
||||
|
||||
- **Colors** - Palette and semantic colors (primary, success, warning, etc.)
|
||||
- **Typography** - Fonts, sizes, weights, line heights
|
||||
- **Logos** - Multiple sizes and light/dark variants
|
||||
- **Meta** - Company name, links, identity information
|
||||
|
||||
## File Naming Convention
|
||||
|
||||
- **Standard name**: `_brand.yml` (auto-discovered by Shiny and Quarto)
|
||||
- **Custom names**: Any name like `company-brand.yml` (requires explicit paths)
|
||||
- **Location**: Typically at project root, or in `_brand/` or `brand/` subdirectories
|
||||
|
||||
## Decision Tree
|
||||
|
||||
Determine the user's goal and follow the appropriate workflow:
|
||||
|
||||
1. **Creating a new _brand.yml file?** → Follow "Creating brand.yml Files"
|
||||
2. **Using brand.yml in Shiny for R?** → Read `references/shiny-r.md`
|
||||
3. **Using brand.yml in Shiny for Python?** → Read `references/shiny-python.md`
|
||||
4. **Using brand.yml in Quarto?** → Read `references/quarto.md`
|
||||
5. **Using brand.yml in R (general)?** → Read `references/brand-yml-in-r.md` (R Markdown, theming functions, programmatic access)
|
||||
6. **Modifying existing _brand.yml?** → Follow "Modifying Existing Files"
|
||||
7. **Troubleshooting integration?** → Follow "Troubleshooting"
|
||||
|
||||
## Creating brand.yml Files
|
||||
|
||||
When creating `_brand.yml` files from brand guidelines:
|
||||
|
||||
### Step 1: Gather Information
|
||||
|
||||
Collect brand information:
|
||||
- **Colors**: Primary, secondary, accent colors with hex values
|
||||
- **Fonts**: Font families and where they're sourced (Google Fonts, local files, etc.)
|
||||
- **Logos**: Logo file paths or URLs for different sizes
|
||||
- **Company info**: Name, website, social links (optional)
|
||||
|
||||
### Step 2: Read the Specification
|
||||
|
||||
Load `references/brand-yml-spec.md` to understand the complete brand.yml structure, field options, and syntax.
|
||||
|
||||
### Step 3: Build the File Incrementally
|
||||
|
||||
Start with the essential sections and add optional elements:
|
||||
|
||||
**Minimum viable _brand.yml:**
|
||||
|
||||
```yaml
|
||||
color:
|
||||
palette:
|
||||
brand-blue: "#0066cc"
|
||||
primary: brand-blue
|
||||
background: "#ffffff"
|
||||
|
||||
typography:
|
||||
fonts:
|
||||
- family: Inter
|
||||
source: google
|
||||
weight: [400, 600]
|
||||
base: Inter
|
||||
```
|
||||
|
||||
**Add colors as needed:**
|
||||
|
||||
```yaml
|
||||
color:
|
||||
palette:
|
||||
brand-blue: "#0066cc"
|
||||
brand-orange: "#ff6600"
|
||||
brand-gray: "#666666"
|
||||
primary: brand-blue
|
||||
secondary: brand-gray
|
||||
warning: brand-orange
|
||||
foreground: "#333333"
|
||||
background: "#ffffff"
|
||||
```
|
||||
|
||||
**Add typography details:**
|
||||
|
||||
```yaml
|
||||
typography:
|
||||
fonts:
|
||||
- family: Inter
|
||||
source: google
|
||||
weight: [400, 600, 700]
|
||||
style: [normal, italic]
|
||||
- family: Fira Code
|
||||
source: google
|
||||
weight: [400, 500]
|
||||
base:
|
||||
family: Inter
|
||||
size: 16px
|
||||
line-height: 1.5
|
||||
headings:
|
||||
family: Inter
|
||||
weight: 600
|
||||
monospace: Fira Code
|
||||
```
|
||||
|
||||
**Add logos:**
|
||||
|
||||
```yaml
|
||||
logo:
|
||||
small: logos/icon.png
|
||||
medium: logos/header.png
|
||||
large: logos/full.svg
|
||||
```
|
||||
|
||||
**Add meta information:**
|
||||
|
||||
```yaml
|
||||
meta:
|
||||
name: Company Name
|
||||
link: https://example.com
|
||||
```
|
||||
|
||||
### Step 4: Apply Best Practices
|
||||
|
||||
Follow these rules from `references/brand-yml-spec.md`:
|
||||
|
||||
- All fields are optional - only include what's needed
|
||||
- Use hex color format: `"#0066cc"`
|
||||
- Prefer simple syntax (strings over objects) when possible
|
||||
- Use lowercase names with hyphens: `brand-blue`, `success-green`
|
||||
- Include `https://` in all URLs
|
||||
- Define colors/fonts before referencing them
|
||||
- For color ranges (shades/tints), choose the midpoint color
|
||||
|
||||
### Step 5: Validate Structure
|
||||
|
||||
Check that:
|
||||
- YAML syntax is valid (proper indentation, quotes on hex colors)
|
||||
- Color references match palette names
|
||||
- Font families are defined before use
|
||||
- File paths are relative to `_brand.yml` location
|
||||
- All URLs include protocol (`https://`)
|
||||
|
||||
## Modifying Existing Files
|
||||
|
||||
When modifying existing `_brand.yml` files:
|
||||
|
||||
1. **Read the current file** to understand existing structure
|
||||
2. **Consult brand-yml-spec.md** for valid field options
|
||||
3. **Maintain consistency** with existing naming patterns
|
||||
4. **Preserve references** - if other colors/elements reference a name, update consistently
|
||||
5. **Test integration** - verify changes apply correctly in Shiny/Quarto
|
||||
|
||||
Common modifications:
|
||||
- **Adding colors**: Add to `color.palette`, then reference in semantic colors
|
||||
- **Changing fonts**: Update in `typography.fonts`, ensure weights/styles are available
|
||||
- **Adding logo variants**: Use `light`/`dark` structure for multiple variants
|
||||
- **Light/dark mode**: Add `light` and `dark` variants to colors
|
||||
|
||||
## Using with Shiny for R
|
||||
|
||||
When the user wants to apply brand.yml to a Shiny for R app:
|
||||
|
||||
1. **Read `references/shiny-r.md`** for complete integration guide
|
||||
2. **Key function**: `bs_theme(brand = TRUE)` or `bs_theme(brand = "path")`
|
||||
3. **Automatic discovery**: Place `_brand.yml` at app root
|
||||
4. **Page functions**: Works with `page_fluid()`, `page_sidebar()`, etc.
|
||||
|
||||
Quick example:
|
||||
|
||||
```r
|
||||
library(shiny)
|
||||
library(bslib)
|
||||
|
||||
ui <- page_fluid(
|
||||
theme = bs_theme(brand = TRUE),
|
||||
# ... UI elements
|
||||
)
|
||||
```
|
||||
|
||||
## Using with Shiny for Python
|
||||
|
||||
When the user wants to apply brand.yml to a Shiny for Python app:
|
||||
|
||||
1. **Read `references/shiny-python.md`** for complete integration guide
|
||||
2. **Key function**: `ui.Theme.from_brand(__file__)`
|
||||
3. **Automatic discovery**: Place `_brand.yml` at app root
|
||||
4. **Installation**: Requires `pip install "shiny[theme]"`
|
||||
|
||||
Quick example (Shiny Express):
|
||||
|
||||
```python
|
||||
from shiny.express import ui
|
||||
|
||||
ui.page_opts(theme=ui.Theme.from_brand(__file__))
|
||||
```
|
||||
|
||||
Quick example (Shiny Core):
|
||||
|
||||
```python
|
||||
from shiny import App, ui
|
||||
|
||||
app_ui = ui.page_fluid(
|
||||
theme=ui.Theme.from_brand(__file__),
|
||||
# ... UI elements
|
||||
)
|
||||
```
|
||||
|
||||
## Using with Quarto
|
||||
|
||||
When the user wants to apply brand.yml to Quarto documents:
|
||||
|
||||
1. **Read `references/quarto.md`** for complete integration guide
|
||||
2. **Automatic discovery**: Place `_brand.yml` at project root with `_quarto.yml`
|
||||
3. **Supported formats**: HTML, dashboards, RevealJS, Typst PDFs
|
||||
4. **Theme layering**: Use `brand` keyword to control precedence
|
||||
|
||||
Quick example (document):
|
||||
|
||||
```yaml
|
||||
---
|
||||
title: "My Document"
|
||||
format:
|
||||
html:
|
||||
brand: _brand.yml
|
||||
---
|
||||
```
|
||||
|
||||
Quick example (project in `_quarto.yml`):
|
||||
|
||||
```yaml
|
||||
project:
|
||||
brand: _brand.yml
|
||||
|
||||
format:
|
||||
html:
|
||||
theme: default
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Brand Not Applying
|
||||
|
||||
**Shiny:**
|
||||
- Verify file is named `_brand.yml` (with underscore)
|
||||
- Check file location (app directory or parent directories)
|
||||
- Try explicit path: `bs_theme(brand = "path/to/_brand.yml")` or `ui.Theme.from_brand("path")`
|
||||
- For Python: Ensure `libsass` is installed
|
||||
|
||||
**Quarto:**
|
||||
- Verify `_brand.yml` is at project root
|
||||
- Ensure `_quarto.yml` exists for project-level branding
|
||||
- Try explicit path in document frontmatter
|
||||
- Check theme layering order if using custom themes
|
||||
|
||||
### Colors Not Matching
|
||||
|
||||
- Ensure hex colors have quotes: `"#0066cc"` not `#0066cc`
|
||||
- Verify color names match palette definitions exactly
|
||||
- Check semantic colors (primary, success, etc.) reference valid palette names
|
||||
- Ensure palette is defined before semantic colors
|
||||
|
||||
### Fonts Not Loading
|
||||
|
||||
- Verify Google Fonts spelling and availability
|
||||
- Check internet connection (required for Google Fonts)
|
||||
- Ensure `source: google` or `source: bunny` is specified
|
||||
- Verify font family names match exactly in typography elements
|
||||
- For Typst: Check font cache with `quarto typst fonts`
|
||||
|
||||
### YAML Syntax Errors
|
||||
|
||||
- Check indentation (use spaces, not tabs)
|
||||
- Ensure hex colors have quotes: `"#447099"`
|
||||
- Verify colons have space after them: `primary: blue`
|
||||
- Check list items have hyphens: `- family: Inter`
|
||||
- Use YAML validator if syntax issues persist
|
||||
|
||||
## Reference Documentation
|
||||
|
||||
Load these as needed for detailed information:
|
||||
|
||||
- **`references/brand-yml-spec.md`**: Complete brand.yml specification with all sections, fields, examples, and validation rules
|
||||
- **`references/shiny-r.md`**: Using brand.yml with Shiny for R via bslib (bs_theme, automatic discovery, Shiny-specific integration)
|
||||
- **`references/shiny-python.md`**: Using brand.yml with Shiny for Python via ui.Theme (from_brand(), installation, performance)
|
||||
- **`references/quarto.md`**: Using brand.yml with Quarto (formats, light/dark mode, layering, extensions, Typst)
|
||||
- **`references/brand-yml-in-r.md`**: General R usage including R Markdown integration, theming functions (ggplot2, gt, flextable, plotly, thematic), and programmatic brand access
|
||||
|
||||
## Key Principles
|
||||
|
||||
- **Start simple**: Begin with colors and one font family
|
||||
- **Keep it concise**: Only include fields directly relevant to the brand
|
||||
- **Prefer standard names**: Use Bootstrap color names when possible (blue, green, red, etc.)
|
||||
- **Use automatic discovery**: Name file `_brand.yml` for auto-detection
|
||||
- **Test across targets**: Verify brand applies correctly in all intended formats
|
||||
- **Version control**: Include `_brand.yml` in git repository
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Light/Dark Mode Colors
|
||||
|
||||
```yaml
|
||||
color:
|
||||
primary:
|
||||
light: "#0066cc"
|
||||
dark: "#3399ff"
|
||||
background:
|
||||
light: "#ffffff"
|
||||
dark: "#1a1a1a"
|
||||
foreground:
|
||||
light: "#333333"
|
||||
dark: "#e0e0e0"
|
||||
```
|
||||
|
||||
Light/dark color modes were added in Quarto version 1.8 and currently are not supported in the R or Python brand.yml packages.
|
||||
|
||||
### Logo Variants
|
||||
|
||||
```yaml
|
||||
logo:
|
||||
images:
|
||||
logo-dark: logos/logo-dark.svg
|
||||
logo-white: logos/logo-white.svg
|
||||
icon: logos/icon.png
|
||||
small: icon
|
||||
medium:
|
||||
light: logo-dark
|
||||
dark: logo-white
|
||||
```
|
||||
|
||||
### Multiple Font Weights
|
||||
|
||||
```yaml
|
||||
typography:
|
||||
fonts:
|
||||
- family: Inter
|
||||
source: google
|
||||
weight: [300, 400, 500, 600, 700]
|
||||
style: [normal, italic]
|
||||
base:
|
||||
family: Inter
|
||||
weight: 400
|
||||
headings:
|
||||
family: Inter
|
||||
weight: 600
|
||||
```
|
||||
|
||||
### Color Aliases
|
||||
|
||||
```yaml
|
||||
color:
|
||||
palette:
|
||||
navy: "#003366"
|
||||
ocean-blue: "#0066cc"
|
||||
sky-blue: "#3399ff"
|
||||
primary-color: ocean-blue # Alias
|
||||
brand-blue: ocean-blue # Alias
|
||||
blue: sky-blue # Alias for primary colors
|
||||
primary: brand-blue
|
||||
```
|
||||
|
||||
Include Bootstrap color names when possible, either defined directly or as aliases: `blue`, `indigo`, `purple`, `pink`, `red`, `orange`, `yellow`, `green`, `teal`, `cyan`, `white`, `black`. This is useful for consistency and these colors are picked up automatically by tools that use brand.yml.
|
||||
|
||||
## Tips
|
||||
|
||||
- **Read specification first**: Always consult `brand-yml-spec.md` when creating or modifying files
|
||||
- **Framework-specific guides**: Load the appropriate reference (shiny-r.md, shiny-python.md, quarto.md) for integration details
|
||||
- **Validate incrementally**: Start with minimal structure, test, then add complexity
|
||||
- **Use references**: Define colors in palette, then reference by name in semantic colors
|
||||
- **Standard file name**: Use `_brand.yml` for automatic discovery
|
||||
- **Explicit paths**: Use custom file names only when necessary (shared branding, multiple variants)
|
||||
447
skills/brand-yml/references/brand-yml-in-r.md
Normal file
447
skills/brand-yml/references/brand-yml-in-r.md
Normal file
@@ -0,0 +1,447 @@
|
||||
# Using brand.yml in R
|
||||
|
||||
Guide for using brand.yml in R projects beyond Shiny, including R Markdown documents, theming functions for plots and tables, and programmatic access to brand data.
|
||||
|
||||
## Overview
|
||||
|
||||
The brand.yml R package provides tools for applying brand styling to R visualizations and documents. These tools work in any R context, including R Markdown documents, Quarto, standalone scripts, and Shiny applications.
|
||||
|
||||
## Installation
|
||||
|
||||
```r
|
||||
# Install brand.yml package
|
||||
install.packages("brand.yml")
|
||||
```
|
||||
|
||||
## R Markdown Integration
|
||||
|
||||
Use brand.yml in R Markdown documents (without `runtime: shiny`):
|
||||
|
||||
```yaml
|
||||
---
|
||||
title: "My Report"
|
||||
output:
|
||||
html_document:
|
||||
theme:
|
||||
version: 5 # Required for brand.yml
|
||||
brand: true # Auto-discover _brand.yml
|
||||
---
|
||||
```
|
||||
|
||||
Or specify a path:
|
||||
|
||||
```yaml
|
||||
---
|
||||
title: "My Report"
|
||||
output:
|
||||
html_document:
|
||||
theme:
|
||||
version: 5
|
||||
brand: "path/to/brand.yml"
|
||||
---
|
||||
```
|
||||
|
||||
**Important**: Set `version: 5` to use Bootstrap 5, which has the best brand.yml support.
|
||||
|
||||
### Other R Markdown Formats
|
||||
|
||||
Brand.yml works with various R Markdown output formats:
|
||||
|
||||
```yaml
|
||||
---
|
||||
title: "Branded Report"
|
||||
output:
|
||||
html_document:
|
||||
theme:
|
||||
version: 5
|
||||
brand: _brand.yml
|
||||
pdf_document: default
|
||||
---
|
||||
```
|
||||
|
||||
## Programmatic Access
|
||||
|
||||
Read and access brand data programmatically in any R script or document:
|
||||
|
||||
```r
|
||||
library(brand.yml)
|
||||
|
||||
# Read from default location (_brand.yml in project)
|
||||
brand <- read_brand_yml()
|
||||
|
||||
# Read from specific path
|
||||
brand <- read_brand_yml("path/to/brand.yml")
|
||||
|
||||
# Access brand elements
|
||||
brand$color$palette$blue # "#447099"
|
||||
brand$color$primary # blue -> "#447099"
|
||||
brand$typography$base$family # "Open Sans"
|
||||
brand$meta$name # "Company Name"
|
||||
|
||||
# Access all colors
|
||||
brand$color$palette # List of all palette colors
|
||||
brand$color$foreground # Foreground color
|
||||
brand$color$background # Background color
|
||||
```
|
||||
|
||||
Use programmatically accessed brand data to:
|
||||
- Display brand colors in custom visualizations
|
||||
- Show brand logo with correct paths
|
||||
- Apply brand fonts to custom elements
|
||||
- Build branded themes dynamically
|
||||
- Generate branded reports programmatically
|
||||
|
||||
## Branded Theming Functions
|
||||
|
||||
The brand.yml package includes helper functions to apply brand colors to plots and tables from popular R packages. These functions work in any R context (scripts, R Markdown, Quarto, Shiny).
|
||||
|
||||
### theme_brand_ggplot2()
|
||||
|
||||
Apply brand colors to ggplot2 visualizations:
|
||||
|
||||
```r
|
||||
library(ggplot2)
|
||||
library(brand.yml)
|
||||
|
||||
# Automatic brand detection
|
||||
ggplot(mtcars, aes(mpg, hp)) +
|
||||
geom_point() +
|
||||
theme_brand_ggplot2()
|
||||
|
||||
# Explicit brand file
|
||||
ggplot(mtcars, aes(mpg, hp)) +
|
||||
geom_point() +
|
||||
theme_brand_ggplot2(brand = "_brand.yml")
|
||||
|
||||
# Override specific colors
|
||||
ggplot(mtcars, aes(mpg, hp)) +
|
||||
geom_point() +
|
||||
theme_brand_ggplot2(
|
||||
background = "white",
|
||||
foreground = "brand-gray",
|
||||
accent = "brand-blue"
|
||||
)
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
- `brand`: NULL (auto-detect), file path, brand object, or FALSE
|
||||
- `background`, `foreground`, `accent`: Primary color settings
|
||||
- `base_size`: Base font size (default: 11)
|
||||
- Additional parameters for fine-grained control: `title_color`, `line_color`, `rect_fill`, `panel_background_fill`, `panel_grid_major_color`, etc.
|
||||
|
||||
### theme_brand_gt()
|
||||
|
||||
Apply brand colors to gt tables:
|
||||
|
||||
```r
|
||||
library(gt)
|
||||
library(brand.yml)
|
||||
|
||||
# Create branded table
|
||||
mtcars |>
|
||||
head() |>
|
||||
gt() |>
|
||||
theme_brand_gt()
|
||||
|
||||
# With explicit brand
|
||||
mtcars |>
|
||||
head() |>
|
||||
gt() |>
|
||||
theme_brand_gt(brand = "_brand.yml")
|
||||
|
||||
# Override colors
|
||||
mtcars |>
|
||||
head() |>
|
||||
gt() |>
|
||||
theme_brand_gt(
|
||||
background = "white",
|
||||
foreground = "brand-gray"
|
||||
)
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
- `table`: The gt table object to theme
|
||||
- `brand`: NULL (auto-detect), file path, brand object, or FALSE
|
||||
- `background`: Table background color (default: `brand.color.background`)
|
||||
- `foreground`: Text color (default: `brand.color.foreground`)
|
||||
|
||||
### theme_brand_flextable()
|
||||
|
||||
Apply brand colors to flextable tables:
|
||||
|
||||
```r
|
||||
library(flextable)
|
||||
library(brand.yml)
|
||||
|
||||
# Create branded flextable
|
||||
mtcars |>
|
||||
head() |>
|
||||
flextable() |>
|
||||
theme_brand_flextable()
|
||||
|
||||
# With explicit brand
|
||||
mtcars |>
|
||||
head() |>
|
||||
flextable() |>
|
||||
theme_brand_flextable(brand = "_brand.yml")
|
||||
|
||||
# Override colors
|
||||
mtcars |>
|
||||
head() |>
|
||||
flextable() |>
|
||||
theme_brand_flextable(
|
||||
background = "white",
|
||||
foreground = "brand-gray"
|
||||
)
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
- `table`: The flextable object to theme
|
||||
- `brand`: NULL (auto-detect), file path, brand object, or FALSE
|
||||
- `background`: Table background color (default: `brand.color.background`)
|
||||
- `foreground`: Text color (default: `brand.color.foreground`)
|
||||
|
||||
### theme_brand_plotly()
|
||||
|
||||
Apply brand colors to plotly visualizations:
|
||||
|
||||
```r
|
||||
library(plotly)
|
||||
library(brand.yml)
|
||||
|
||||
# Create branded plotly chart
|
||||
plot_ly(mtcars, x = ~mpg, y = ~hp, type = "scatter", mode = "markers") |>
|
||||
theme_brand_plotly()
|
||||
|
||||
# With explicit brand
|
||||
plot_ly(mtcars, x = ~mpg, y = ~hp, type = "scatter", mode = "markers") |>
|
||||
theme_brand_plotly(brand = "_brand.yml")
|
||||
|
||||
# Override colors
|
||||
plot_ly(mtcars, x = ~mpg, y = ~hp, type = "scatter", mode = "markers") |>
|
||||
theme_brand_plotly(
|
||||
background = "white",
|
||||
foreground = "brand-gray",
|
||||
accent = "brand-blue"
|
||||
)
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
- `plot`: The plotly plot object to theme
|
||||
- `brand`: NULL (auto-detect), file path, brand object, or FALSE
|
||||
- `background`: Plot background color (default: `brand.color.background`)
|
||||
- `foreground`: Text/foreground color (default: `brand.color.foreground`)
|
||||
- `accent`: Accent/highlight color (default: `brand.color.primary`)
|
||||
|
||||
### theme_brand_thematic()
|
||||
|
||||
Apply brand colors to base R graphics via thematic:
|
||||
|
||||
```r
|
||||
library(thematic)
|
||||
library(brand.yml)
|
||||
|
||||
# Create theme object
|
||||
theme <- theme_brand_thematic()
|
||||
|
||||
# Use with thematic_with_theme()
|
||||
thematic::thematic_with_theme(theme, {
|
||||
plot(mtcars$mpg, mtcars$hp)
|
||||
})
|
||||
|
||||
# Or use with ggplot2
|
||||
thematic::thematic_with_theme(theme, {
|
||||
ggplot(mtcars, aes(mpg, hp)) +
|
||||
geom_point()
|
||||
})
|
||||
```
|
||||
|
||||
### theme_brand_thematic_on()
|
||||
|
||||
Immediately activate brand theming globally for base R graphics:
|
||||
|
||||
```r
|
||||
library(thematic)
|
||||
library(brand.yml)
|
||||
|
||||
# Turn on brand theming globally
|
||||
theme_brand_thematic_on()
|
||||
|
||||
# Now all plots use brand colors
|
||||
plot(mtcars$mpg, mtcars$hp)
|
||||
hist(mtcars$mpg)
|
||||
|
||||
# Turn off later
|
||||
thematic::thematic_off()
|
||||
```
|
||||
|
||||
**Parameters (both functions):**
|
||||
- `brand`: NULL (auto-detect), file path, brand object, or FALSE
|
||||
- `background`: Background color (default: `brand.color.background`)
|
||||
- `foreground`: Foreground color (default: `brand.color.foreground`)
|
||||
- `accent`: Accent color (default: `brand.color.primary`)
|
||||
- `...`: Additional arguments passed to thematic package
|
||||
|
||||
**Difference:**
|
||||
- `theme_brand_thematic()`: Returns theme object for scoped use
|
||||
- `theme_brand_thematic_on()`: Immediately applies theme globally
|
||||
|
||||
## R Markdown Example
|
||||
|
||||
Complete example showing theming functions in R Markdown:
|
||||
|
||||
````markdown
|
||||
---
|
||||
title: "Branded Report"
|
||||
output:
|
||||
html_document:
|
||||
theme:
|
||||
version: 5
|
||||
brand: _brand.yml
|
||||
---
|
||||
|
||||
```{r setup}
|
||||
library(ggplot2)
|
||||
library(gt)
|
||||
library(brand.yml)
|
||||
```
|
||||
|
||||
## Sales Analysis
|
||||
|
||||
```{r plot}
|
||||
ggplot(mtcars, aes(mpg, hp, color = factor(cyl))) +
|
||||
geom_point(size = 3) +
|
||||
labs(title = "MPG vs Horsepower", color = "Cylinders") +
|
||||
theme_brand_ggplot2()
|
||||
```
|
||||
|
||||
## Data Summary
|
||||
|
||||
```{r table}
|
||||
mtcars |>
|
||||
head(10) |>
|
||||
gt() |>
|
||||
theme_brand_gt() |>
|
||||
tab_header(title = "Motor Trend Car Data")
|
||||
```
|
||||
````
|
||||
|
||||
## Quarto Integration
|
||||
|
||||
Works seamlessly in Quarto documents:
|
||||
|
||||
````markdown
|
||||
---
|
||||
title: "Branded Analysis"
|
||||
format:
|
||||
html:
|
||||
brand: _brand.yml
|
||||
---
|
||||
|
||||
```{r}
|
||||
#| label: branded-plot
|
||||
library(ggplot2)
|
||||
library(brand.yml)
|
||||
|
||||
ggplot(iris, aes(Sepal.Length, Sepal.Width, color = Species)) +
|
||||
geom_point() +
|
||||
theme_brand_ggplot2()
|
||||
```
|
||||
````
|
||||
|
||||
## Script Usage
|
||||
|
||||
Use in standalone R scripts:
|
||||
|
||||
```r
|
||||
#!/usr/bin/env Rscript
|
||||
|
||||
library(brand.yml)
|
||||
library(ggplot2)
|
||||
|
||||
# Read brand
|
||||
brand <- read_brand_yml("_brand.yml")
|
||||
|
||||
# Create branded plot
|
||||
p <- ggplot(mtcars, aes(mpg, hp)) +
|
||||
geom_point(color = brand$color$primary) +
|
||||
theme_brand_ggplot2()
|
||||
|
||||
# Save with brand colors
|
||||
ggsave("output.png", p, width = 8, height = 6)
|
||||
```
|
||||
|
||||
## Benefits
|
||||
|
||||
- **Consistency**: Same brand styling across all R outputs (plots, tables, documents)
|
||||
- **Automatic detection**: Functions find `_brand.yml` automatically
|
||||
- **Flexible override**: Easy to customize colors when needed
|
||||
- **Works everywhere**: R scripts, R Markdown, Quarto, Shiny
|
||||
|
||||
## Tips
|
||||
|
||||
- **Place `_brand.yml` at project root** for automatic discovery
|
||||
- **Use `read_brand_yml()`** for programmatic access to brand data
|
||||
- **Combine theming functions** for cohesive branded reports
|
||||
- **Set `version: 5`** in R Markdown YAML for Bootstrap 5 support
|
||||
- **Test theme functions** individually before combining in documents
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Branded Report with Multiple Visualizations
|
||||
|
||||
```r
|
||||
library(brand.yml)
|
||||
library(ggplot2)
|
||||
library(gt)
|
||||
|
||||
# Load brand
|
||||
brand <- read_brand_yml()
|
||||
|
||||
# Create consistent visualizations
|
||||
plot1 <- ggplot(data1, aes(x, y)) +
|
||||
geom_point() +
|
||||
theme_brand_ggplot2()
|
||||
|
||||
plot2 <- ggplot(data2, aes(x, y)) +
|
||||
geom_line() +
|
||||
theme_brand_ggplot2()
|
||||
|
||||
table1 <- data3 |>
|
||||
gt() |>
|
||||
theme_brand_gt()
|
||||
```
|
||||
|
||||
### Dynamic Brand Colors
|
||||
|
||||
```r
|
||||
library(brand.yml)
|
||||
|
||||
brand <- read_brand_yml()
|
||||
|
||||
# Use brand colors in custom visualizations
|
||||
my_colors <- c(
|
||||
brand$color$primary,
|
||||
brand$color$secondary,
|
||||
brand$color$success
|
||||
)
|
||||
|
||||
# Apply to plot
|
||||
plot(data, col = my_colors[factor(group)])
|
||||
```
|
||||
|
||||
### Conditional Branding
|
||||
|
||||
```r
|
||||
library(brand.yml)
|
||||
|
||||
# Use different brands for different contexts
|
||||
if (Sys.getenv("BRAND_MODE") == "internal") {
|
||||
brand <- read_brand_yml("internal-brand.yml")
|
||||
} else {
|
||||
brand <- read_brand_yml("external-brand.yml")
|
||||
}
|
||||
|
||||
# Apply to visualizations
|
||||
theme <- theme_brand_ggplot2(brand = brand)
|
||||
```
|
||||
408
skills/brand-yml/references/brand-yml-spec.md
Normal file
408
skills/brand-yml/references/brand-yml-spec.md
Normal file
@@ -0,0 +1,408 @@
|
||||
# brand.yml Specification
|
||||
|
||||
Complete specification for creating valid `_brand.yml` files for the brand.yml project.
|
||||
|
||||
## File Naming Convention
|
||||
|
||||
- **Conventional name**: `_brand.yml` (auto-discovered by Shiny and Quarto)
|
||||
- **Custom names**: Any `.yml` file (e.g., `my-brand.yml`) requires explicit paths
|
||||
- **Location**: Typically at project root or in `_brand/` or `brand/` subdirectories
|
||||
|
||||
## File Structure
|
||||
|
||||
All fields are **optional**. Only include fields directly relevant to the brand.
|
||||
|
||||
```yaml
|
||||
meta: # Company/project identity information
|
||||
logo: # Logo files and variants
|
||||
color: # Color palette and semantic colors
|
||||
typography: # Fonts and text styling
|
||||
defaults: # Framework-specific customizations
|
||||
```
|
||||
|
||||
## Meta Section
|
||||
|
||||
Company or project metadata.
|
||||
|
||||
### Simple Format
|
||||
|
||||
```yaml
|
||||
meta:
|
||||
name: Acme
|
||||
link: https://acmecorp.com
|
||||
```
|
||||
|
||||
### Extended Format
|
||||
|
||||
```yaml
|
||||
meta:
|
||||
name:
|
||||
short: Acme
|
||||
full: Acme Corporation International
|
||||
link:
|
||||
home: https://www.acmecorp.com
|
||||
docs: https://docs.acmecorp.com
|
||||
github: https://github.com/acmecorp
|
||||
bluesky: https://bsky.app/profile/acmecorp.bsky.social
|
||||
mastodon: https://mastodon.social/@acmecorp
|
||||
linkedin: https://www.linkedin.com/company/acmecorp
|
||||
facebook: https://www.facebook.com/acmecorp
|
||||
twitter: https://twitter.com/acmecorp
|
||||
```
|
||||
|
||||
**Requirements:**
|
||||
- All links must include `https://` prefix
|
||||
- Additional custom fields are allowed
|
||||
|
||||
## Logo Section
|
||||
|
||||
Logo files for different contexts and sizes.
|
||||
|
||||
### Structure
|
||||
|
||||
```yaml
|
||||
logo:
|
||||
images: # Named logo resources (optional)
|
||||
name: path # Map names to file paths or URLs
|
||||
small: path # Icon-sized logo (favicons, mobile)
|
||||
medium: path # Standard logo (headers, navigation)
|
||||
large: path # Large logo (hero, title slides)
|
||||
```
|
||||
|
||||
### File Paths
|
||||
|
||||
- **Local files**: Relative paths from `_brand.yml` location (e.g., `logos/logo.png`)
|
||||
- **Remote files**: Full URLs with `http://` or `https://`
|
||||
|
||||
### Light/Dark Variants
|
||||
|
||||
```yaml
|
||||
logo:
|
||||
medium:
|
||||
light: logo-dark.png # For light backgrounds
|
||||
dark: logo-white.png # For dark backgrounds
|
||||
```
|
||||
|
||||
### With Alt Text
|
||||
|
||||
```yaml
|
||||
logo:
|
||||
images:
|
||||
header:
|
||||
path: logos/header.svg
|
||||
alt: Company logo
|
||||
medium: header
|
||||
```
|
||||
|
||||
### Complete Example
|
||||
|
||||
```yaml
|
||||
logo:
|
||||
images:
|
||||
header: logos/header-logo.png
|
||||
header-white: logos/header-logo-white.png
|
||||
icon: logos/icon.png
|
||||
full:
|
||||
path: logos/full-logo.svg
|
||||
alt: Acme Corporation logo
|
||||
small: icon
|
||||
medium:
|
||||
light: header
|
||||
dark: header-white
|
||||
large: full
|
||||
```
|
||||
|
||||
## Color Section
|
||||
|
||||
Brand color palette and semantic color assignments.
|
||||
|
||||
### Structure
|
||||
|
||||
```yaml
|
||||
color:
|
||||
palette: # Named brand colors
|
||||
name: "#hex" # Flat list of color names and hex values
|
||||
# Semantic theme colors (all optional)
|
||||
foreground: "#color" # Main text color
|
||||
background: "#color" # Main background color
|
||||
primary: "#color" # Links, buttons, primary actions
|
||||
secondary: "#color" # Lighter text, disabled states
|
||||
tertiary: "#color" # Hover states, accents
|
||||
success: "#color" # Positive actions
|
||||
info: "#color" # Neutral information
|
||||
warning: "#color" # Cautions
|
||||
danger: "#color" # Errors, negative actions
|
||||
light: "#color" # High contrast on dark
|
||||
dark: "#color" # High contrast on light
|
||||
```
|
||||
|
||||
### Color Palette Best Practices
|
||||
|
||||
- Use hex color values: `"#447099"`
|
||||
- Use descriptive names following Sass conventions: `blue`, `brand-orange`, `success-green`
|
||||
- Create aliases by referencing other palette colors: `purple: burgundy`
|
||||
- Include Bootstrap color names when possible: `blue`, `indigo`, `purple`, `pink`, `red`, `orange`, `yellow`, `green`, `teal`, `cyan`, `white`, `black`
|
||||
- When brands define ranges of shades, choose the midpoint as the primary color
|
||||
|
||||
### Referencing Colors
|
||||
|
||||
Theme colors can reference palette names:
|
||||
|
||||
```yaml
|
||||
color:
|
||||
palette:
|
||||
brand-blue: "#447099"
|
||||
brand-orange: "#EE6331"
|
||||
primary: brand-blue # References palette
|
||||
warning: brand-orange # References palette
|
||||
```
|
||||
|
||||
### Complete Example
|
||||
|
||||
```yaml
|
||||
color:
|
||||
palette:
|
||||
white: "#FFFFFF"
|
||||
black: "#151515"
|
||||
blue: "#447099"
|
||||
orange: "#EE6331"
|
||||
green: "#72994E"
|
||||
teal: "#419599"
|
||||
burgundy: "#9A4665"
|
||||
foreground: black
|
||||
background: white
|
||||
primary: blue
|
||||
success: green
|
||||
info: teal
|
||||
warning: orange
|
||||
danger: burgundy
|
||||
```
|
||||
|
||||
## Typography Section
|
||||
|
||||
Font definitions and text element styling.
|
||||
|
||||
### Structure
|
||||
|
||||
```yaml
|
||||
typography:
|
||||
fonts: # Font definitions
|
||||
- family: Name
|
||||
source: type # file, google, bunny, or system
|
||||
# Additional source-specific fields
|
||||
base: # Body text (optional)
|
||||
headings: # Heading text (optional)
|
||||
monospace: # Code text (optional)
|
||||
monospace-inline: # Inline code (optional)
|
||||
monospace-block: # Code blocks (optional)
|
||||
link: # Hyperlinks (optional)
|
||||
```
|
||||
|
||||
### Font Sources
|
||||
|
||||
#### Local/Remote Files
|
||||
|
||||
```yaml
|
||||
fonts:
|
||||
- family: Open Sans
|
||||
source: file
|
||||
files:
|
||||
- path: fonts/OpenSans-Regular.ttf
|
||||
weight: 400
|
||||
style: normal
|
||||
- path: fonts/OpenSans-Bold.ttf
|
||||
weight: 700
|
||||
style: normal
|
||||
- path: https://example.com/fonts/OpenSans-Italic.ttf
|
||||
weight: 400
|
||||
style: italic
|
||||
```
|
||||
|
||||
Proprietary fonts, should be downloaded and stored adjacent to the brand.yml file and referenced via relative paths in the `path` field.
|
||||
|
||||
#### Google Fonts
|
||||
|
||||
```yaml
|
||||
fonts:
|
||||
- family: Roboto
|
||||
source: google
|
||||
weight: [400, 700] # Optional: specific weights
|
||||
style: [normal, italic] # Optional: specific styles
|
||||
display: block # Optional: font-display property
|
||||
```
|
||||
|
||||
Weight options:
|
||||
- Array of numbers: `[400, 700]`
|
||||
- Range (variable fonts): `400..900`
|
||||
- Named weights: `[thin, normal, bold]`
|
||||
|
||||
#### Bunny Fonts (GDPR-compliant alternative)
|
||||
|
||||
```yaml
|
||||
fonts:
|
||||
- family: Inter
|
||||
source: bunny
|
||||
weight: [400, 600]
|
||||
style: [normal, italic]
|
||||
```
|
||||
|
||||
Same syntax as Google Fonts.
|
||||
|
||||
### Typographic Elements
|
||||
|
||||
All elements support these fields:
|
||||
- `family`: Font family name (must match a defined font)
|
||||
- `weight`: `100`-`900` or `thin`, `normal`, `bold`, etc.
|
||||
- `style`: `normal` or `italic`
|
||||
- `size`: CSS units (`16px`, `1rem`, `0.9em`)
|
||||
- `line-height`: Number or CSS unit
|
||||
- `color`: Hex value or reference to color name
|
||||
- `background-color`: Hex value or reference to color name
|
||||
|
||||
#### Simple Format (String)
|
||||
|
||||
```yaml
|
||||
typography:
|
||||
base: Open Sans
|
||||
headings: Roboto
|
||||
monospace: Fira Code
|
||||
```
|
||||
|
||||
#### Extended Format (Object)
|
||||
|
||||
```yaml
|
||||
typography:
|
||||
base:
|
||||
family: Open Sans
|
||||
weight: 400
|
||||
size: 16px
|
||||
line-height: 1.5
|
||||
headings:
|
||||
family: Roboto
|
||||
weight: 600
|
||||
style: normal
|
||||
line-height: 1.2
|
||||
color: "#333333"
|
||||
monospace:
|
||||
family: Fira Code
|
||||
weight: 400
|
||||
size: 0.9em
|
||||
monospace-inline:
|
||||
color: "#7d12ba"
|
||||
background-color: "#f8f9fa"
|
||||
monospace-block:
|
||||
color: foreground
|
||||
background-color: background
|
||||
line-height: 1.4
|
||||
link:
|
||||
weight: 600
|
||||
color: primary
|
||||
decoration: underline
|
||||
```
|
||||
|
||||
**Note**: Base text color uses `color.foreground` by default. Do not specify color in base unless overriding.
|
||||
|
||||
### Complete Example
|
||||
|
||||
```yaml
|
||||
typography:
|
||||
fonts:
|
||||
- family: Open Sans
|
||||
source: google
|
||||
weight: [400, 600, 700]
|
||||
style: [normal, italic]
|
||||
- family: Roboto Slab
|
||||
source: google
|
||||
weight: [600, 900]
|
||||
- family: Fira Code
|
||||
source: bunny
|
||||
weight: [400, 500]
|
||||
base:
|
||||
family: Open Sans
|
||||
size: 16px
|
||||
line-height: 1.5
|
||||
headings:
|
||||
family: Roboto Slab
|
||||
weight: 600
|
||||
monospace: Fira Code
|
||||
link:
|
||||
color: primary
|
||||
weight: 600
|
||||
```
|
||||
|
||||
## Defaults Section
|
||||
|
||||
Framework-specific customizations. Use sparingly - only when brand requirements cannot be met through the standard sections above.
|
||||
|
||||
### Structure
|
||||
|
||||
```yaml
|
||||
defaults:
|
||||
bootstrap: # Bootstrap/bslib customizations
|
||||
functions: # SCSS function declarations (string)
|
||||
defaults: # Bootstrap variable overrides (mapping)
|
||||
mixins: # SCSS mixins (string)
|
||||
rules: # Additional SCSS rules (string)
|
||||
quarto: # Quarto-specific settings
|
||||
format: # Format-specific options
|
||||
shiny: # Shiny-specific settings
|
||||
theme:
|
||||
defaults: # Bootstrap variables
|
||||
rules: # Additional SCSS rules
|
||||
```
|
||||
|
||||
### Example
|
||||
|
||||
```yaml
|
||||
defaults:
|
||||
bootstrap:
|
||||
defaults:
|
||||
navbar-bg: $brand-orange
|
||||
rules: |
|
||||
.btn-primary {
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
shiny:
|
||||
theme:
|
||||
defaults:
|
||||
navbar-padding-y: 1rem
|
||||
```
|
||||
|
||||
**Note**: Colors from `color.palette` are available as Sass variables: `$brand-{color_name}`
|
||||
|
||||
## Validation Rules
|
||||
|
||||
When creating `_brand.yml` files:
|
||||
|
||||
1. **All fields are optional** - only include what's needed
|
||||
2. **Prefer hex colors** - use `"#447099"` format
|
||||
3. **Prefer simple syntax** - use strings instead of objects when possible
|
||||
4. **Follow Sass naming** - color/font names use lowercase and hyphens
|
||||
5. **Include URLs with protocol** - always use `https://`
|
||||
6. **Reference before use** - define colors/fonts before referencing them
|
||||
7. **Keep it concise** - simpler is better
|
||||
|
||||
## Complete Minimal Example
|
||||
|
||||
```yaml
|
||||
color:
|
||||
palette:
|
||||
blue: "#0066cc"
|
||||
gray: "#666666"
|
||||
primary: blue
|
||||
foreground: gray
|
||||
background: "#ffffff"
|
||||
|
||||
typography:
|
||||
fonts:
|
||||
- family: Inter
|
||||
source: google
|
||||
weight: [400, 600]
|
||||
base: Inter
|
||||
headings:
|
||||
weight: 600
|
||||
```
|
||||
|
||||
## Complete Comprehensive Example
|
||||
|
||||
See the example in the document provided to you (brand-yml.prompt.txt) for a full-featured _brand.yml with all options demonstrated.
|
||||
504
skills/brand-yml/references/quarto.md
Normal file
504
skills/brand-yml/references/quarto.md
Normal file
@@ -0,0 +1,504 @@
|
||||
# Using brand.yml with Quarto
|
||||
|
||||
Guide for applying brand.yml styling to Quarto documents, presentations, websites, and PDFs.
|
||||
|
||||
## Overview
|
||||
|
||||
Quarto automatically integrates `_brand.yml` to provide unified visual styling across multiple output formats including HTML, dashboards, RevealJS presentations, and Typst PDFs.
|
||||
|
||||
## Quick Start
|
||||
|
||||
Place `_brand.yml` at your project root:
|
||||
|
||||
```
|
||||
my-project/
|
||||
├── _quarto.yml
|
||||
├── _brand.yml
|
||||
├── index.qmd
|
||||
└── ...
|
||||
```
|
||||
|
||||
Quarto automatically discovers and applies `_brand.yml` - no configuration needed.
|
||||
|
||||
## Supported Formats
|
||||
|
||||
Brand styling automatically applies to:
|
||||
|
||||
- **HTML documents** - Web pages, reports
|
||||
- **HTML dashboards** - Interactive dashboards
|
||||
- **RevealJS presentations** - Slide decks
|
||||
- **Typst PDFs** - PDF documents via Typst
|
||||
- **Websites** - Multi-page Quarto websites
|
||||
|
||||
## Document-Level Usage
|
||||
|
||||
Specify brand in document frontmatter:
|
||||
|
||||
```yaml
|
||||
---
|
||||
title: "My Document"
|
||||
format:
|
||||
html:
|
||||
brand: _brand.yml
|
||||
---
|
||||
```
|
||||
|
||||
Or use default discovery:
|
||||
|
||||
```yaml
|
||||
---
|
||||
title: "My Document"
|
||||
format: html
|
||||
---
|
||||
```
|
||||
|
||||
If `_brand.yml` exists at project root, it's automatically applied.
|
||||
|
||||
## Project-Level Usage
|
||||
|
||||
Configure in `_quarto.yml`:
|
||||
|
||||
```yaml
|
||||
project:
|
||||
type: website
|
||||
brand: _brand.yml
|
||||
|
||||
format:
|
||||
html:
|
||||
theme: default
|
||||
```
|
||||
|
||||
## Custom Brand File Location
|
||||
|
||||
Specify a non-standard path:
|
||||
|
||||
```yaml
|
||||
---
|
||||
title: "My Document"
|
||||
format:
|
||||
html:
|
||||
brand: branding/company-brand.yml
|
||||
---
|
||||
```
|
||||
|
||||
Or in project config:
|
||||
|
||||
```yaml
|
||||
project:
|
||||
brand: path/to/brand.yml
|
||||
```
|
||||
|
||||
## Light/Dark Mode
|
||||
|
||||
Specify color variants for light and dark modes:
|
||||
|
||||
```yaml
|
||||
color:
|
||||
palette:
|
||||
blue: "#0066cc"
|
||||
primary:
|
||||
light: "#0066cc"
|
||||
dark: "#3399ff"
|
||||
background:
|
||||
light: "#ffffff"
|
||||
dark: "#1a1a1a"
|
||||
foreground:
|
||||
light: "#333333"
|
||||
dark: "#e0e0e0"
|
||||
```
|
||||
|
||||
Any color in `color` or `typography` can have light/dark variants.
|
||||
|
||||
## Theme Layering
|
||||
|
||||
Control precedence with the `"brand"` keyword:
|
||||
|
||||
### Default (Brand Lowest Priority)
|
||||
|
||||
```yaml
|
||||
format:
|
||||
revealjs:
|
||||
theme:
|
||||
- custom.scss
|
||||
- cosmo
|
||||
```
|
||||
|
||||
Priority: `cosmo` > `custom.scss` > `_brand.yml`
|
||||
|
||||
### Brand Highest Priority
|
||||
|
||||
```yaml
|
||||
format:
|
||||
revealjs:
|
||||
theme:
|
||||
- cosmo
|
||||
- custom.scss
|
||||
- brand
|
||||
```
|
||||
|
||||
Priority: `_brand.yml` > `custom.scss` > `cosmo`
|
||||
|
||||
### Brand in Middle
|
||||
|
||||
```yaml
|
||||
format:
|
||||
html:
|
||||
theme:
|
||||
- cosmo
|
||||
- brand
|
||||
- custom.scss
|
||||
```
|
||||
|
||||
Priority: `custom.scss` > `_brand.yml` > `cosmo`
|
||||
|
||||
## Accessing Brand Data in Documents
|
||||
|
||||
### Shortcodes
|
||||
|
||||
Use shortcodes to access brand values (requires Quarto extensions):
|
||||
|
||||
```markdown
|
||||
<!-- Access colors -->
|
||||
Our primary color is {{{< brand-color primary >}}}.
|
||||
|
||||
<!-- Access meta information -->
|
||||
Welcome to {{{< brand-meta name >}}}.
|
||||
```
|
||||
|
||||
### SCSS Variables
|
||||
|
||||
Access brand colors in custom SCSS:
|
||||
|
||||
```scss
|
||||
// Custom SCSS file
|
||||
.branded-element {
|
||||
color: $brand-primary;
|
||||
background: $brand-background;
|
||||
border-color: $brand-secondary;
|
||||
}
|
||||
```
|
||||
|
||||
Brand colors are automatically available as Sass variables: `$brand-{color-name}`.
|
||||
|
||||
## Typst PDF Support
|
||||
|
||||
Brand styling works with Typst PDF output:
|
||||
|
||||
```yaml
|
||||
---
|
||||
title: "My Document"
|
||||
format:
|
||||
typst:
|
||||
brand: _brand.yml
|
||||
---
|
||||
```
|
||||
|
||||
### Typst Color Variables
|
||||
|
||||
Access colors in Typst templates:
|
||||
|
||||
- `brand-color.{name}` - Palette colors (e.g., `brand-color.blue`, `brand-color.primary`)
|
||||
- `brand-background-color.{name}` - Lighter background variants
|
||||
|
||||
### Typst Typography Support
|
||||
|
||||
| Element | family | weight | color | background-color | line-height |
|
||||
|---------|--------|--------|-------|------------------|-------------|
|
||||
| base | ✓ | ✓ | ✓ | - | ✓ |
|
||||
| headings | ✓ | ✓ | ✓ | - | ✓ |
|
||||
| title | ✓ | ✓ | ✓ | - | ✓ |
|
||||
| monospace-inline | ✓ | ✓ | ✓ | ✓ | - |
|
||||
| monospace-block | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| link | - | ✓ | ✓ | ✓ | - |
|
||||
|
||||
### Typst Font Handling
|
||||
|
||||
Quarto automatically downloads Google Fonts and caches them for Typst. Check fonts:
|
||||
|
||||
```bash
|
||||
quarto typst fonts --ignore-system-fonts --font-path .quarto/typst-font-cache/
|
||||
```
|
||||
|
||||
Disable font fallback in Typst:
|
||||
|
||||
```typst
|
||||
#set text(fallback: false)
|
||||
```
|
||||
|
||||
## Complete Examples
|
||||
|
||||
### Simple HTML Document
|
||||
|
||||
```yaml
|
||||
---
|
||||
title: "Quarterly Report"
|
||||
format:
|
||||
html:
|
||||
toc: true
|
||||
---
|
||||
|
||||
# Executive Summary
|
||||
|
||||
Content here uses brand colors and typography automatically.
|
||||
```
|
||||
|
||||
With `_brand.yml` at project root:
|
||||
|
||||
```yaml
|
||||
color:
|
||||
palette:
|
||||
blue: "#0066cc"
|
||||
primary: blue
|
||||
background: "#ffffff"
|
||||
|
||||
typography:
|
||||
fonts:
|
||||
- family: Inter
|
||||
source: google
|
||||
weight: [400, 600]
|
||||
base:
|
||||
family: Inter
|
||||
size: 16px
|
||||
headings:
|
||||
family: Inter
|
||||
weight: 600
|
||||
```
|
||||
|
||||
### RevealJS Presentation
|
||||
|
||||
```yaml
|
||||
---
|
||||
title: "Company Overview"
|
||||
format:
|
||||
revealjs:
|
||||
theme:
|
||||
- default
|
||||
- brand
|
||||
logo: logo.png
|
||||
---
|
||||
|
||||
# Introduction
|
||||
|
||||
Slides automatically use brand colors and fonts.
|
||||
```
|
||||
|
||||
### Website with Brand
|
||||
|
||||
`_quarto.yml`:
|
||||
|
||||
```yaml
|
||||
project:
|
||||
type: website
|
||||
brand: _brand.yml
|
||||
|
||||
website:
|
||||
title: "My Company"
|
||||
navbar:
|
||||
left:
|
||||
- href: index.qmd
|
||||
text: Home
|
||||
- about.qmd
|
||||
|
||||
format:
|
||||
html:
|
||||
theme: cosmo
|
||||
css: styles.css
|
||||
```
|
||||
|
||||
Brand colors and typography apply across all pages.
|
||||
|
||||
### Dashboard
|
||||
|
||||
```yaml
|
||||
---
|
||||
title: "Sales Dashboard"
|
||||
format:
|
||||
dashboard:
|
||||
brand: _brand.yml
|
||||
theme: default
|
||||
---
|
||||
|
||||
## Row
|
||||
|
||||
```{python}
|
||||
# Dashboard content
|
||||
```
|
||||
```
|
||||
|
||||
### Typst PDF
|
||||
|
||||
```yaml
|
||||
---
|
||||
title: "Technical Report"
|
||||
format:
|
||||
typst:
|
||||
brand: _brand.yml
|
||||
margin:
|
||||
x: 2cm
|
||||
y: 2cm
|
||||
---
|
||||
|
||||
# Overview
|
||||
|
||||
PDF uses brand colors and fonts via Typst.
|
||||
```
|
||||
|
||||
## Brand Extensions
|
||||
|
||||
Create reusable brand packages:
|
||||
|
||||
```bash
|
||||
quarto create extension brand
|
||||
```
|
||||
|
||||
Structure:
|
||||
|
||||
```
|
||||
my-brand-extension/
|
||||
├── _extension.yml
|
||||
├── brand.yml
|
||||
├── logo.png
|
||||
└── fonts/
|
||||
└── ...
|
||||
```
|
||||
|
||||
`_extension.yml`:
|
||||
|
||||
```yaml
|
||||
title: Company Brand
|
||||
author: Your Name
|
||||
version: 1.0.0
|
||||
contributes:
|
||||
brand: brand.yml
|
||||
```
|
||||
|
||||
Install extension in projects:
|
||||
|
||||
```bash
|
||||
quarto add username/my-brand-extension
|
||||
```
|
||||
|
||||
**Requirement**: Brand extensions need `_quarto.yml` project file.
|
||||
|
||||
## Sample _brand.yml for Quarto
|
||||
|
||||
Minimal example:
|
||||
|
||||
```yaml
|
||||
color:
|
||||
palette:
|
||||
brand-blue: "#0066cc"
|
||||
brand-gray: "#666666"
|
||||
primary: brand-blue
|
||||
foreground: brand-gray
|
||||
background: "#ffffff"
|
||||
|
||||
typography:
|
||||
fonts:
|
||||
- family: Inter
|
||||
source: google
|
||||
weight: [400, 600]
|
||||
base:
|
||||
family: Inter
|
||||
size: 1rem
|
||||
line-height: 1.6
|
||||
headings:
|
||||
family: Inter
|
||||
weight: 600
|
||||
line-height: 1.2
|
||||
```
|
||||
|
||||
Complete example with light/dark mode:
|
||||
|
||||
```yaml
|
||||
meta:
|
||||
name: My Company
|
||||
link: https://mycompany.com
|
||||
|
||||
logo:
|
||||
small: logo-icon.png
|
||||
medium:
|
||||
light: logo-dark.svg
|
||||
dark: logo-white.svg
|
||||
|
||||
color:
|
||||
palette:
|
||||
blue: "#0066cc"
|
||||
navy: "#003366"
|
||||
gray: "#666666"
|
||||
light-gray: "#f5f5f5"
|
||||
primary: blue
|
||||
secondary: gray
|
||||
success: "#28a745"
|
||||
info: blue
|
||||
warning: "#ffc107"
|
||||
danger: "#dc3545"
|
||||
foreground:
|
||||
light: navy
|
||||
dark: "#e0e0e0"
|
||||
background:
|
||||
light: "#ffffff"
|
||||
dark: "#1a1a1a"
|
||||
|
||||
typography:
|
||||
fonts:
|
||||
- family: Inter
|
||||
source: google
|
||||
weight: [400, 500, 600, 700]
|
||||
style: [normal, italic]
|
||||
- family: Fira Code
|
||||
source: google
|
||||
weight: [400, 500]
|
||||
base:
|
||||
family: Inter
|
||||
size: 1rem
|
||||
line-height: 1.6
|
||||
headings:
|
||||
family: Inter
|
||||
weight: 600
|
||||
line-height: 1.2
|
||||
monospace:
|
||||
family: Fira Code
|
||||
size: 0.9em
|
||||
link:
|
||||
color: primary
|
||||
weight: 500
|
||||
```
|
||||
|
||||
## Tips
|
||||
|
||||
- **Automatic discovery**: Place `_brand.yml` at project root for automatic application
|
||||
- **Light/dark variants**: Use for websites with theme toggles
|
||||
- **Layer strategically**: Use `brand` keyword to control theme precedence
|
||||
- **Test across formats**: Verify brand applies correctly to HTML, PDF, and presentations
|
||||
- **Extension for reuse**: Create brand extensions for multi-project consistency
|
||||
- **Version control**: Include `_brand.yml` in git repository
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Brand not applying?**
|
||||
- Verify file is named `_brand.yml` (with underscore)
|
||||
- Check file is at project root or specified in `brand:` field
|
||||
- Ensure `_quarto.yml` exists for project-level branding
|
||||
- Try explicit path in frontmatter
|
||||
|
||||
**Colors not matching?**
|
||||
- Ensure hex colors have quotes: `"#0066cc"`
|
||||
- Check color references match palette definitions
|
||||
- Verify theme layering order
|
||||
|
||||
**Fonts not loading?**
|
||||
- Verify Google Fonts spelling
|
||||
- Check internet connection (required for Google Fonts)
|
||||
- For Typst, check font cache: `quarto typst fonts`
|
||||
- Ensure `source: google` is specified correctly
|
||||
|
||||
**Typst-specific issues?**
|
||||
- Check font cache path: `.quarto/typst-font-cache/`
|
||||
- Add `#set text(fallback: false)` to debug font issues
|
||||
- Verify typography properties are supported (see table above)
|
||||
|
||||
**Brand extension not working?**
|
||||
- Ensure `_quarto.yml` exists in project
|
||||
- Verify extension is installed: `quarto list extensions`
|
||||
- Check extension contributes brand: look for `contributes.brand` in `_extension.yml`
|
||||
395
skills/brand-yml/references/shiny-python.md
Normal file
395
skills/brand-yml/references/shiny-python.md
Normal file
@@ -0,0 +1,395 @@
|
||||
# Using brand.yml with Shiny for Python
|
||||
|
||||
Guide for applying brand.yml styling to Shiny for Python applications using ui.Theme.
|
||||
|
||||
## Overview
|
||||
|
||||
Shiny for Python integrates brand.yml through the `ui.Theme.from_brand()` method, which creates custom themes from `_brand.yml` files. This enables consistent branding across Shiny apps with minimal configuration.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
# Install Shiny with theme support
|
||||
pip install "shiny[theme]"
|
||||
|
||||
# Or install separately
|
||||
pip install shiny libsass
|
||||
|
||||
# Optional: Install brand_yml for programmatic access
|
||||
pip install brand_yml
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Automatic Discovery
|
||||
|
||||
Place `_brand.yml` at your app directory root:
|
||||
|
||||
```
|
||||
my-app/
|
||||
├── _brand.yml
|
||||
├── app.py
|
||||
└── ...
|
||||
```
|
||||
|
||||
Then use `ui.Theme.from_brand()`:
|
||||
|
||||
**Shiny Express:**
|
||||
|
||||
```python
|
||||
from shiny.express import ui
|
||||
|
||||
ui.page_opts(theme=ui.Theme.from_brand(__file__))
|
||||
|
||||
# ... rest of app
|
||||
```
|
||||
|
||||
**Shiny Core:**
|
||||
|
||||
```python
|
||||
from shiny import App, ui
|
||||
|
||||
app_ui = ui.page_fluid(
|
||||
ui.Theme.from_brand(__file__),
|
||||
ui.h2("My App"),
|
||||
# ... rest of UI
|
||||
)
|
||||
|
||||
def server(input, output, session):
|
||||
pass
|
||||
|
||||
app = App(app_ui, server)
|
||||
```
|
||||
|
||||
## ui.Theme.from_brand() Parameters
|
||||
|
||||
```python
|
||||
ui.Theme.from_brand(brand)
|
||||
```
|
||||
|
||||
The `brand` parameter accepts:
|
||||
|
||||
### File Path (Most Common)
|
||||
|
||||
```python
|
||||
# Use __file__ for app directory
|
||||
ui.Theme.from_brand(__file__)
|
||||
|
||||
# Explicit file path
|
||||
ui.Theme.from_brand("path/to/_brand.yml")
|
||||
|
||||
# Explicit directory (auto-finds _brand.yml)
|
||||
ui.Theme.from_brand("branding/")
|
||||
```
|
||||
|
||||
### Brand Object
|
||||
|
||||
```python
|
||||
from brand_yml import Brand
|
||||
|
||||
brand = Brand.from_yaml("_brand.yml")
|
||||
ui.Theme.from_brand(brand)
|
||||
```
|
||||
|
||||
## Search Behavior
|
||||
|
||||
When given `__file__` or a directory path, the method searches for `_brand.yml`:
|
||||
|
||||
1. In the specified directory
|
||||
2. In `_brand/` subdirectory
|
||||
3. In `brand/` subdirectory
|
||||
4. In parent directories (recursive)
|
||||
|
||||
## Complete Examples
|
||||
|
||||
### Shiny Express App
|
||||
|
||||
```python
|
||||
from shiny.express import input, render, ui
|
||||
|
||||
ui.page_opts(
|
||||
title="My Dashboard",
|
||||
theme=ui.Theme.from_brand(__file__)
|
||||
)
|
||||
|
||||
with ui.sidebar():
|
||||
ui.input_slider("n", "Number of observations", 1, 100, 50)
|
||||
|
||||
@render.plot
|
||||
def histogram():
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
|
||||
data = np.random.randn(input.n())
|
||||
plt.hist(data, bins=20)
|
||||
plt.xlabel("Value")
|
||||
plt.ylabel("Frequency")
|
||||
```
|
||||
|
||||
### Shiny Core App
|
||||
|
||||
```python
|
||||
from shiny import App, render, ui
|
||||
|
||||
app_ui = ui.page_sidebar(
|
||||
ui.sidebar(
|
||||
ui.input_slider("n", "Number of observations", 1, 100, 50),
|
||||
),
|
||||
ui.output_plot("histogram"),
|
||||
title="My Dashboard",
|
||||
theme=ui.Theme.from_brand(__file__)
|
||||
)
|
||||
|
||||
def server(input, output, session):
|
||||
@render.plot
|
||||
def histogram():
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
|
||||
data = np.random.randn(input.n())
|
||||
plt.hist(data, bins=20)
|
||||
plt.xlabel("Value")
|
||||
plt.ylabel("Frequency")
|
||||
|
||||
app = App(app_ui, server)
|
||||
```
|
||||
|
||||
### With Custom Path
|
||||
|
||||
```python
|
||||
from shiny.express import ui
|
||||
|
||||
# Shared brand file
|
||||
ui.page_opts(theme=ui.Theme.from_brand("../shared-branding/_brand.yml"))
|
||||
|
||||
# Named brand file
|
||||
ui.page_opts(theme=ui.Theme.from_brand("company-brand.yml"))
|
||||
|
||||
# Directory with _brand.yml inside
|
||||
ui.page_opts(theme=ui.Theme.from_brand("branding/"))
|
||||
```
|
||||
|
||||
### Multiple Page Types
|
||||
|
||||
```python
|
||||
from shiny import App, ui
|
||||
|
||||
# page_fluid
|
||||
app_ui = ui.page_fluid(
|
||||
theme=ui.Theme.from_brand(__file__),
|
||||
# ... content
|
||||
)
|
||||
|
||||
# page_sidebar
|
||||
app_ui = ui.page_sidebar(
|
||||
theme=ui.Theme.from_brand(__file__),
|
||||
ui.sidebar(
|
||||
# ... sidebar content
|
||||
),
|
||||
# ... main content
|
||||
)
|
||||
|
||||
# page_navbar
|
||||
app_ui = ui.page_navbar(
|
||||
ui.nav_panel("Tab 1", # ...),
|
||||
ui.nav_panel("Tab 2", # ...),
|
||||
title="My App",
|
||||
theme=ui.Theme.from_brand(__file__)
|
||||
)
|
||||
|
||||
# page_fillable
|
||||
app_ui = ui.page_fillable(
|
||||
theme=ui.Theme.from_brand(__file__),
|
||||
# ... content
|
||||
)
|
||||
```
|
||||
|
||||
## Combining with Custom Theme Rules
|
||||
|
||||
Extend brand.yml themes with custom Sass:
|
||||
|
||||
```python
|
||||
from shiny.express import ui
|
||||
|
||||
theme = (
|
||||
ui.Theme.from_brand(__file__)
|
||||
.add_rules("""
|
||||
.custom-card {
|
||||
border-radius: 0.5rem;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
}
|
||||
""")
|
||||
)
|
||||
|
||||
ui.page_opts(theme=theme)
|
||||
```
|
||||
|
||||
Available theme methods (chainable):
|
||||
- `.add_defaults()` - Override Bootstrap variables
|
||||
- `.add_functions()` - Add Sass functions
|
||||
- `.add_mixins()` - Add Sass mixins
|
||||
- `.add_rules()` - Add CSS rules
|
||||
- `.add_uses()` - Add Sass declarations
|
||||
|
||||
## Programmatic Access with brand_yml
|
||||
|
||||
For advanced use cases, access brand data programmatically:
|
||||
|
||||
```python
|
||||
from brand_yml import Brand
|
||||
|
||||
# Read brand file
|
||||
brand = Brand.from_yaml("_brand.yml")
|
||||
|
||||
# Or from string
|
||||
yaml_content = """
|
||||
color:
|
||||
palette:
|
||||
blue: "#0066cc"
|
||||
primary: blue
|
||||
"""
|
||||
brand = Brand.from_yaml_str(yaml_content)
|
||||
|
||||
# Access brand elements
|
||||
brand.meta.name # Organization name
|
||||
brand.color.palette.blue # "#0066cc"
|
||||
brand.color.primary # "blue"
|
||||
brand.typography.base.family # Font family name
|
||||
|
||||
# Use in UI
|
||||
from shiny import ui
|
||||
|
||||
app_ui = ui.page_fluid(
|
||||
theme=ui.Theme.from_brand(brand),
|
||||
ui.h2(brand.meta.name),
|
||||
# ... more content
|
||||
)
|
||||
```
|
||||
|
||||
## Sample _brand.yml for Shiny
|
||||
|
||||
Minimal example:
|
||||
|
||||
```yaml
|
||||
color:
|
||||
palette:
|
||||
brand-blue: "#0066cc"
|
||||
brand-gray: "#666666"
|
||||
primary: brand-blue
|
||||
foreground: brand-gray
|
||||
background: "#ffffff"
|
||||
|
||||
typography:
|
||||
fonts:
|
||||
- family: Inter
|
||||
source: google
|
||||
weight: [400, 600]
|
||||
base:
|
||||
family: Inter
|
||||
size: 16px
|
||||
headings:
|
||||
family: Inter
|
||||
weight: 600
|
||||
```
|
||||
|
||||
More complete example:
|
||||
|
||||
```yaml
|
||||
meta:
|
||||
name: My Company
|
||||
link: https://mycompany.com
|
||||
|
||||
color:
|
||||
palette:
|
||||
blue: "#0066cc"
|
||||
navy: "#003366"
|
||||
gray: "#666666"
|
||||
light-gray: "#f5f5f5"
|
||||
primary: blue
|
||||
secondary: gray
|
||||
success: "#28a745"
|
||||
info: blue
|
||||
warning: "#ffc107"
|
||||
danger: "#dc3545"
|
||||
foreground: navy
|
||||
background: "#ffffff"
|
||||
|
||||
typography:
|
||||
fonts:
|
||||
- family: Inter
|
||||
source: google
|
||||
weight: [400, 500, 600, 700]
|
||||
style: [normal, italic]
|
||||
- family: Fira Code
|
||||
source: google
|
||||
weight: [400, 500]
|
||||
base:
|
||||
family: Inter
|
||||
size: 16px
|
||||
line-height: 1.5
|
||||
headings:
|
||||
family: Inter
|
||||
weight: 600
|
||||
line-height: 1.2
|
||||
monospace:
|
||||
family: Fira Code
|
||||
size: 14px
|
||||
```
|
||||
|
||||
## Tips
|
||||
|
||||
- **Use __file__**: Most reliable way to locate `_brand.yml` in app directory
|
||||
- **Start simple**: Begin with colors and one font
|
||||
- **Test paths**: If brand doesn't apply, try explicit paths
|
||||
- **Version control**: Include `_brand.yml` in git repository
|
||||
- **Precompile for production**: Use `.to_css()` to avoid runtime Sass compilation
|
||||
|
||||
```python
|
||||
# Development
|
||||
theme = ui.Theme.from_brand(__file__)
|
||||
|
||||
# Production (precompile)
|
||||
theme_css = ui.Theme.from_brand(__file__).to_css()
|
||||
# Save to static/theme.css, then reference in production
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Theme not applying?**
|
||||
- Check file is named `_brand.yml` (with underscore)
|
||||
- Verify `libsass` is installed: `pip install libsass`
|
||||
- Try explicit path: `ui.Theme.from_brand("path/to/_brand.yml")`
|
||||
- Check for YAML syntax errors
|
||||
|
||||
**Colors not matching?**
|
||||
- Ensure hex colors have quotes: `"#0066cc"`
|
||||
- Verify color names match palette definitions
|
||||
- Check semantic colors reference valid palette names
|
||||
|
||||
**Fonts not loading?**
|
||||
- Verify Google Fonts spelling and availability
|
||||
- Ensure `source: google` is specified
|
||||
- Check font family names match exactly
|
||||
- Internet connection required for Google Fonts
|
||||
|
||||
**Import errors?**
|
||||
- Install theme support: `pip install "shiny[theme]"`
|
||||
- Or install libsass separately: `pip install libsass`
|
||||
|
||||
## Performance Considerations
|
||||
|
||||
For production apps with many instances, precompile the theme:
|
||||
|
||||
```python
|
||||
# build_theme.py
|
||||
from shiny import ui
|
||||
|
||||
theme = ui.Theme.from_brand("_brand.yml")
|
||||
css = theme.to_css()
|
||||
|
||||
with open("static/brand-theme.css", "w") as f:
|
||||
f.write(css)
|
||||
|
||||
# Then in app.py, reference the CSS file directly
|
||||
# This avoids runtime Sass compilation overhead
|
||||
```
|
||||
378
skills/brand-yml/references/shiny-r.md
Normal file
378
skills/brand-yml/references/shiny-r.md
Normal file
@@ -0,0 +1,378 @@
|
||||
# Using brand.yml with Shiny for R
|
||||
|
||||
Guide for applying brand.yml styling to Shiny applications using the bslib package.
|
||||
|
||||
## Overview
|
||||
|
||||
The bslib package integrates brand.yml to provide unified visual theming across Shiny applications. Define colors, fonts, and logos once in `_brand.yml`, and bslib automatically applies them to your Shiny app UI.
|
||||
|
||||
## Installation
|
||||
|
||||
```r
|
||||
# Install bslib (includes brand.yml support)
|
||||
install.packages("bslib")
|
||||
|
||||
# Optional: Install brand.yml package for theming plots/tables
|
||||
install.packages("brand.yml")
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Automatic Discovery
|
||||
|
||||
Place `_brand.yml` at your app directory root:
|
||||
|
||||
```
|
||||
my-app/
|
||||
├── _brand.yml
|
||||
├── app.R
|
||||
└── ...
|
||||
```
|
||||
|
||||
Then use `bs_theme()` in your app:
|
||||
|
||||
```r
|
||||
library(shiny)
|
||||
library(bslib)
|
||||
|
||||
ui <- page_fluid(
|
||||
theme = bs_theme(), # Automatically finds _brand.yml
|
||||
titlePanel("My App"),
|
||||
# ... rest of UI
|
||||
)
|
||||
|
||||
server <- function(input, output, session) {
|
||||
# ...
|
||||
}
|
||||
|
||||
shinyApp(ui, server)
|
||||
```
|
||||
|
||||
### Search Paths
|
||||
|
||||
bslib automatically searches for `_brand.yml` in this order:
|
||||
|
||||
1. Current app directory
|
||||
2. `_brand/` subdirectory
|
||||
3. `brand/` subdirectory
|
||||
4. Parent directories (recursive)
|
||||
|
||||
## bs_theme() Brand Parameter
|
||||
|
||||
The `brand` parameter controls how branding is applied:
|
||||
|
||||
### Automatic (Default)
|
||||
|
||||
```r
|
||||
theme = bs_theme()
|
||||
```
|
||||
|
||||
Searches for `_brand.yml` and applies it if found. No error if file doesn't exist.
|
||||
|
||||
### Required Brand
|
||||
|
||||
```r
|
||||
theme = bs_theme(brand = TRUE)
|
||||
```
|
||||
|
||||
Requires `_brand.yml` to exist. Throws error if not found.
|
||||
|
||||
### Explicit Path
|
||||
|
||||
```r
|
||||
theme = bs_theme(brand = "path/to/my-brand.yml")
|
||||
```
|
||||
|
||||
Uses specific brand file. Path can be:
|
||||
- Relative to app directory: `"branding/company-brand.yml"`
|
||||
- Absolute: `"/Users/name/brands/company.yml"`
|
||||
- Directory (auto-finds `_brand.yml`): `"branding/"`
|
||||
|
||||
### Inline Brand Definition
|
||||
|
||||
```r
|
||||
theme = bs_theme(
|
||||
brand = list(
|
||||
color = list(
|
||||
palette = list(
|
||||
blue = "#0066cc",
|
||||
gray = "#666666"
|
||||
),
|
||||
primary = "blue",
|
||||
foreground = "gray"
|
||||
),
|
||||
typography = list(
|
||||
fonts = list(
|
||||
list(family = "Inter", source = "google", weight = c(400, 600))
|
||||
),
|
||||
base = "Inter"
|
||||
)
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
### Disable Branding
|
||||
|
||||
```r
|
||||
theme = bs_theme(brand = FALSE)
|
||||
```
|
||||
|
||||
Ignores `_brand.yml` even if it exists.
|
||||
|
||||
## Using with page_*() Functions
|
||||
|
||||
All bslib page functions support automatic brand discovery:
|
||||
|
||||
```r
|
||||
# page_fluid
|
||||
ui <- page_fluid(
|
||||
theme = bs_theme(),
|
||||
# ... content
|
||||
)
|
||||
|
||||
# page_sidebar
|
||||
ui <- page_sidebar(
|
||||
theme = bs_theme(),
|
||||
sidebar = sidebar(
|
||||
# ... sidebar content
|
||||
),
|
||||
# ... main content
|
||||
)
|
||||
|
||||
# page_navbar
|
||||
ui <- page_navbar(
|
||||
theme = bs_theme(),
|
||||
nav_panel("Tab 1", # ...),
|
||||
nav_panel("Tab 2", # ...)
|
||||
)
|
||||
|
||||
# page_fillable
|
||||
ui <- page_fillable(
|
||||
theme = bs_theme(),
|
||||
# ... content
|
||||
)
|
||||
```
|
||||
|
||||
## Branded Plots and Tables in Shiny
|
||||
|
||||
Use theming functions from the brand.yml package to style plots and tables within Shiny apps. See `brand-yml-in-r.md` for complete documentation of theming functions.
|
||||
|
||||
### Basic Example
|
||||
|
||||
```r
|
||||
library(shiny)
|
||||
library(bslib)
|
||||
library(ggplot2)
|
||||
library(gt)
|
||||
library(brand.yml)
|
||||
|
||||
ui <- page_sidebar(
|
||||
theme = bs_theme(brand = TRUE),
|
||||
|
||||
sidebar = sidebar(
|
||||
selectInput("dataset", "Dataset:", c("mtcars", "iris"))
|
||||
),
|
||||
|
||||
card(
|
||||
card_header("Branded Plot"),
|
||||
plotOutput("plot")
|
||||
),
|
||||
card(
|
||||
card_header("Branded Table"),
|
||||
gt_output("table")
|
||||
)
|
||||
)
|
||||
|
||||
server <- function(input, output, session) {
|
||||
output$plot <- renderPlot({
|
||||
ggplot(mtcars, aes(mpg, hp)) +
|
||||
geom_point() +
|
||||
theme_brand_ggplot2()
|
||||
})
|
||||
|
||||
output$table <- render_gt({
|
||||
head(mtcars) |>
|
||||
gt() |>
|
||||
theme_brand_gt()
|
||||
})
|
||||
}
|
||||
|
||||
shinyApp(ui, server)
|
||||
```
|
||||
|
||||
**Benefits:**
|
||||
- Consistent styling across UI, plots, and tables
|
||||
- Automatic brand detection from `_brand.yml`
|
||||
- Works with ggplot2, gt, flextable, plotly, and base R graphics
|
||||
|
||||
For detailed theming function documentation, see `brand-yml-in-r.md`.
|
||||
|
||||
## Complete Shiny Example
|
||||
|
||||
```r
|
||||
library(shiny)
|
||||
library(bslib)
|
||||
|
||||
ui <- page_sidebar(
|
||||
theme = bs_theme(brand = TRUE), # Require _brand.yml
|
||||
|
||||
sidebar = sidebar(
|
||||
title = "Controls",
|
||||
selectInput("dataset", "Dataset:",
|
||||
choices = c("iris", "mtcars")),
|
||||
numericInput("n", "Number of rows:", 10, min = 1, max = 50)
|
||||
),
|
||||
|
||||
card(
|
||||
card_header("Data Summary"),
|
||||
tableOutput("summary")
|
||||
),
|
||||
|
||||
card(
|
||||
card_header("Data Details"),
|
||||
verbatimTextOutput("details")
|
||||
)
|
||||
)
|
||||
|
||||
server <- function(input, output, session) {
|
||||
dataset <- reactive({
|
||||
get(input$dataset)
|
||||
})
|
||||
|
||||
output$summary <- renderTable({
|
||||
head(dataset(), input$n)
|
||||
})
|
||||
|
||||
output$details <- renderPrint({
|
||||
summary(dataset())
|
||||
})
|
||||
}
|
||||
|
||||
shinyApp(ui, server)
|
||||
```
|
||||
|
||||
With `_brand.yml`:
|
||||
|
||||
```yaml
|
||||
color:
|
||||
palette:
|
||||
brand-blue: "#0066cc"
|
||||
brand-gray: "#666666"
|
||||
primary: brand-blue
|
||||
foreground: brand-gray
|
||||
background: "#ffffff"
|
||||
|
||||
typography:
|
||||
fonts:
|
||||
- family: Inter
|
||||
source: google
|
||||
weight: [400, 600]
|
||||
base:
|
||||
family: Inter
|
||||
size: 16px
|
||||
headings:
|
||||
family: Inter
|
||||
weight: 600
|
||||
```
|
||||
|
||||
## R Markdown Shiny Documents
|
||||
|
||||
Use brand.yml in R Markdown documents with Shiny runtime:
|
||||
|
||||
```yaml
|
||||
---
|
||||
title: "Interactive Dashboard"
|
||||
output:
|
||||
html_document:
|
||||
theme:
|
||||
version: 5 # Required for brand.yml
|
||||
brand: true # Auto-discover _brand.yml
|
||||
runtime: shiny
|
||||
---
|
||||
```
|
||||
|
||||
Or specify a path:
|
||||
|
||||
```yaml
|
||||
---
|
||||
title: "Interactive Dashboard"
|
||||
output:
|
||||
html_document:
|
||||
theme:
|
||||
version: 5
|
||||
brand: "path/to/brand.yml"
|
||||
runtime: shiny
|
||||
---
|
||||
```
|
||||
|
||||
**Important**: Set `version: 5` to use Bootstrap 5, which has the best brand.yml support.
|
||||
|
||||
**Note**: For R Markdown documents without `runtime: shiny`, see `brand-yml-in-r.md`.
|
||||
|
||||
## Programmatic Brand Access
|
||||
|
||||
For advanced use cases, access brand data programmatically within Shiny:
|
||||
|
||||
```r
|
||||
library(brand.yml)
|
||||
|
||||
server <- function(input, output, session) {
|
||||
# Read brand data
|
||||
brand <- read_brand_yml()
|
||||
|
||||
# Use in custom UI elements
|
||||
output$brand_info <- renderUI({
|
||||
div(
|
||||
style = paste0("color: ", brand$color$primary, ";"),
|
||||
h3(brand$meta$name),
|
||||
p("Welcome to our branded app!")
|
||||
)
|
||||
})
|
||||
|
||||
# Use in plots with custom styling
|
||||
output$custom_plot <- renderPlot({
|
||||
plot(mtcars$mpg, mtcars$hp,
|
||||
col = brand$color$primary,
|
||||
pch = 19)
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
For complete documentation on programmatic access and theming functions, see `brand-yml-in-r.md`.
|
||||
|
||||
## Tips
|
||||
|
||||
- **Start simple**: Begin with colors and one font family
|
||||
- **Test automatically**: Automatic discovery works well for most cases
|
||||
- **Use explicit paths**: For shared brand files across multiple apps
|
||||
- **Version control**: Include `_brand.yml` in your git repository
|
||||
- **Validate early**: Use `brand = TRUE` during development to catch missing files
|
||||
- **Combine with theming functions**: Style plots and tables consistently (see `brand-yml-in-r.md`)
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Brand not applying to Shiny UI?**
|
||||
- Check file is named `_brand.yml` (with underscore)
|
||||
- Verify file is in app directory or parent directories
|
||||
- Try explicit path: `bs_theme(brand = "path/to/_brand.yml")`
|
||||
- Check for YAML syntax errors
|
||||
|
||||
**Colors not matching?**
|
||||
- Verify hex colors have quotes: `"#0066cc"`
|
||||
- Check color names match palette definitions
|
||||
- Ensure primary/secondary colors reference valid palette names
|
||||
|
||||
**Fonts not loading?**
|
||||
- Verify Google Fonts spelling and availability
|
||||
- Check `source: google` is specified correctly
|
||||
- Ensure font family names match exactly in typography elements
|
||||
|
||||
**Plots/tables not branded?**
|
||||
- Ensure brand.yml package is installed: `install.packages("brand.yml")`
|
||||
- Use theming functions: `theme_brand_ggplot2()`, `theme_brand_gt()`, etc.
|
||||
- See `brand-yml-in-r.md` for complete theming documentation
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- **[brand-yml-in-r.md](brand-yml-in-r.md)**: General R usage, R Markdown integration, theming functions, and programmatic access
|
||||
- **[brand-yml-spec.md](brand-yml-spec.md)**: Complete brand.yml file specification
|
||||
Reference in New Issue
Block a user