Vaulthalla Logo

Directive Themes

Register named directive themes, override built-ins, and use stable hook classes.

Directive Themes

Directive themes let authors select named visual treatments without putting raw Tailwind classes into CMS-authored Markdown.

The recommended model:

  • define theme class strings in source/config
  • let Tailwind scan those class strings
  • select a named theme in Markdown with theme="..."
  • use stable emitted vl-md-* classes for additional CSS overrides

Register Themes

1payloadMarkdown({2  themes: {3    card: {4      extendDefaults: true,5      items: [6        {7          name: 'forge',8          classes: 'rounded-2xl border border-white/10 bg-cyan-950/30 p-5 shadow-sm',9        },10      ],11    },12  },13})

Theme objects use classes, not className.

Defaults And Overrides

extendDefaults defaults to true:

1payloadMarkdown({2  themes: {3    card: {4      items: [5        {6          name: 'forge',7          classes: 'rounded-2xl border border-white/10 bg-cyan-950/30 p-5',8        },9      ],10    },11  },12})

If a custom theme has the same name as a built-in theme, it overrides the built-in theme.

For total control:

1payloadMarkdown({2  themes: {3    card: {4      extendDefaults: false,5      items: [6        {7          name: 'default',8          classes: 'rounded-xl border border-white/10 bg-[#18191c] p-4',9        },10      ],11    },12  },13})

Collection-Scoped Themes

1payloadMarkdown({2  collections: {3    posts: {4      themes: {5        card: {6          items: [7            {8              name: 'postHeroCard',9              classes: 'rounded-2xl border border-white/10 bg-cyan-950/30 p-5',10            },11          ],12        },13      },14    },15  },16})

Collection themes merge after plugin-level themes. If a collection theme has the same name as a plugin-level theme, the collection theme wins for that collection.

Themeable Directive Groups

  • callout
  • card
  • cards
  • cell
  • columns
  • details
  • section
  • steps
  • tab
  • tabs
  • toc

Parent-Child Defaults

Cards can set a default child card theme:

1:::cards{2  columns="3"3  cardTheme="glass"4}5 6:::card[Inherits Glass]7Content.8:::9 10:::card[Overrides Parent]{theme="cyan"}11Content.12:::13 14:::

Steps can set a default card theme for individual step cards:

1:::steps{2  variant="cards"3  stepTheme="cyan"4}5 6### Install7 8Content.9 10:::

Tabs can set a default child panel theme:

1:::tabs{2  default="pnpm"3  tabTheme="glass"4}5 6:::tab[pnpm]{value="pnpm"}7Content.8:::9 10:::

Stable Output Hooks

The renderer emits stable hooks:

1<article2  class="vl-md-card vl-md-card--theme-cyan ..."3  data-directive="card"4  data-theme="cyan"5>6  ...7</article>

Custom theme names are slugged for modifier classes:

1class="vl-md-card vl-md-card--theme-post-hero-card ..."

Default Theme Exports

1import {2  DEFAULT_CALLOUT_THEMES,3  DEFAULT_CARD_THEMES,4  DEFAULT_CARDS_THEMES,5  DEFAULT_CELL_THEMES,6  DEFAULT_COLUMNS_THEMES,7  DEFAULT_DETAILS_THEMES,8  DEFAULT_SECTION_THEMES,9  DEFAULT_STEPS_THEMES,10  DEFAULT_TAB_THEMES,11  DEFAULT_TABS_THEMES,12  DEFAULT_TOC_THEMES,13} from '@valkyrianlabs/payload-markdown'

You usually do not need to spread these manually. Built-ins are included automatically unless extendDefaults: false.