## Theming

### Ricos Theme

#### <span style="font-weight: 700;" class="rounded-lg border-[1px] border-blue-300 font-mono border-none bg-blue-100 px-2 py-1 leading-[18px] tracking-[0.0175em] font-bold text-slate-900">RicosTheme</span>

Theme input for `RicosEditor` and `RicosViewer`. Values flow into CSS variables consumed by every plugin, the toolbars, and the settings panels — prefer this over wrapping Ricos with external CSS, because external CSS only reaches the editable area, not the chrome. Pair `colorPalette` (broad colors) with `customStyles` (per-element overrides) for full control.

<code class="font-mono text-sm"><span class="text-blue-700">interface</span> RicosTheme</code>

<dl class="pl-4 border-l-2 border-slate-200">
<dt><code><strong>colorPalette</strong><span class="text-slate-400">?</span>: <a href="/api-docs/related-types#ricospalette"><span class="font-mono">RicosPalette</span></a></code></dt>
<dd><p>Global color tokens shared across all plugins, toolbars, and settings panels.</p></dd>
</dl>

<div class="pl-4 border-l-2 border-slate-200 mb-4">

```tsx widget
import { fromPlainText, pluginHashtag, RicosEditor } from '@wix/ricos';
import React from 'react';

export default () => {
  // @essential-start
  return (
    <div style={{ background: '#C9C9C9' }}>
      <RicosEditor
        initialContent={fromPlainText('This is a #hashtag, see it has a unique color.')}
        placeholder="Type here!"
        theme={{
          colorPalette: {
            format: 'color',
            bgColor: '#0E092B',
            textColor: '#FFFFFF',
            accent1: '#D6FF00',
          },
        }}
        plugins={[pluginHashtag()]}
      />
    </div>
  );
  // @essential-end
};
```

</div>

<dl class="pl-4 border-l-2 border-slate-200">
<dt><code><strong>typography</strong><span class="text-slate-400">?</span>: <a href="/api-docs/related-types#ricostypography"><span class="font-mono">RicosTypography</span></a></code></dt>
<dd><p>Typography tokens. `fontFamily` cascades to every text node unless a `customStyles.&lt;element&gt;.fontFamily` overrides it.</p></dd>
<dt><code><strong>customStyles</strong><span class="text-slate-400">?</span>: <a href="/api-docs/related-types#ricoscustomstyles"><span class="font-mono">RicosCustomStyles</span></a></code></dt>
<dd><p>Per-element style overrides for headings, paragraphs, quotes, plugin cards, and the editor container itself.</p></dd>
</dl>

<div class="pl-4 border-l-2 border-slate-200 mb-4">

```tsx widget
import { fromPlainText, RicosEditor } from '@wix/ricos';
import React from 'react';

export default () => {
  // @essential-start
  const theme = {
    customStyles: {
      h2: {
        fontFamily: 'Times',
        fontSize: '26px',
        color: 'orange',
        fontStyle: 'italic',
        textDecoration: 'underline',
      },
      h3: {
        fontFamily: 'Tahoma',
        fontSize: '20px',
        color: 'purple',
        textDecoration: 'none',
      },
      quote: {
        lineHeight: '24px',
        fontWeight: 'bold',
        color: 'brown',
      },
    },
  };

  return (
    <RicosEditor
      initialContent={fromPlainText('Apply heading 2 or 3 from the toolbar to see the styles.')}
      placeholder="Type here!"
      theme={theme}
    />
  );
  // @essential-end
};
```

</div>

<dl class="pl-4 border-l-2 border-slate-200">
<dt><code><strong>settingsStyles</strong><span class="text-slate-400">?</span>: <a href="/api-docs/related-types#ricossettingsstyles"><span class="font-mono">RicosSettingsStyles</span></a></code></dt>
<dd><p>Style overrides for settings modals (z-index layering). Most fields are deprecated — only `modals` is supported going forward.</p></dd>
<dt><code><strong>nativeStyle</strong><span class="text-slate-400">?</span>: <a href="/api-docs/related-types#ricosnativestyles"><span class="font-mono">RicosNativeStyles</span></a></code></dt>
<dd><p>React-Native-flavoured style overrides; only consumed when `useNativeStyles` is `true`.</p></dd>
<dt><code><strong>useWixStyles</strong><span class="text-slate-400">?</span>: boolean</code></dt>
<dd><p>When `true`, applies the Wix Studio default theme on top of the supplied values.</p></dd>
<dt><code><strong>useNativeStyles</strong><span class="text-slate-400">?</span>: boolean</code></dt>
<dd><p>When `true`, switches the renderer to consume `nativeStyle` instead of CSS overrides — used by mobile builds.</p></dd>
<dt><code><strong>breakout</strong><span class="text-slate-400">?</span>: {         rule: ({ node }: {             node: <a href="/api-docs/related-types#ricosdocumentnode"><span class="font-mono">RicosDocumentNode</span></a>;         }) =&gt; 'fullWidth' | 'normal';         normalPadding: {             start: CSSProperties['paddingInlineStart'];             end: CSSProperties['paddingInlineEnd'];         };         fullWidthPadding?: {             start: CSSProperties['paddingInlineStart'];             end: CSSProperties['paddingInlineEnd'];         };     }</code></dt>
<dd><p>Breakout layout: lets specific nodes flow beyond the content column to viewport edges. `rule` is called once per node at layout time; return `'fullWidth'` for the chosen nodes (typically images and galleries) and `'normal'` for everything else. `fullWidthPadding` overrides `normalPadding` for the `'fullWidth'` case.</p></dd>
</dl>

### Recipes

#### Choosing between `colorPalette` and `customStyles`

`colorPalette` is the broad brush — a small set of color tokens (`bgColor`, `textColor`, `accent1..4`, `shade1..3`) that flow into every plugin's CSS variables. Set it once and the editor, toolbars, settings panels, and every plugin card pick up the new colors together.

`customStyles` is the per-element scalpel. Reach for it when you need to override font, size, padding, or borders on a specific element (`h1`, `quote`, `editor`, `footerToolbar`, …). When both apply to the same element, `customStyles` wins.

#### Color formats

`RicosPalette.format` controls how Ricos interprets every other value in the palette:

- `'color'` — values are standard CSS color strings (hex, `rgb()`, named colors). This is what most consumers want.
- `'rgbTuple'` — values are bare `R, G, B` triples (e.g. `'132, 84, 252'`). Use this mode when you want Ricos to derive opacity variants downstream (`rgba(R, G, B, 0.5)` etc.) — applying an alpha channel to a hex string isn't possible.

The same key names work in both modes — only the format of the values changes.

```tsx widget
import { fromPlainText, pluginHashtag, RicosEditor } from '@wix/ricos';
import React from 'react';

export default () => (
  <div style={{ background: '#C9C9C9' }}>
    {/* @essential-start */}
    <RicosEditor
      initialContent={fromPlainText('This is a #hashtag, see it has a unique color.')}
      placeholder="Type here!"
      theme={{
        colorPalette: {
          format: 'color',
          bgColor: '#0E092B',
          textColor: '#FFFFFF',
          accent1: '#D6FF00',
        },
      }}
      plugins={[pluginHashtag()]}
    />
    {/* @essential-end */}
  </div>
);
```

#### Per-element `customStyles`

Most consumers only touch `h1..h6`, `p`, `link`, `quote`. The full surface is in the `RicosCustomStyles` table — link to it from the row above. A few less obvious entries worth knowing:

- `editor` — controls the editable container's `minHeight`/`maxHeight`, placeholder color, and the position of the inline plus button.
- `footerToolbar` — controls the inline plus-button bar at the bottom of the editor.
- `card` — the per-plugin selection chrome (selection border, background image, padding).
- `container` — the outermost wrapper's top/bottom padding.

```tsx widget
import { fromPlainText, RicosEditor } from '@wix/ricos';
import React from 'react';

export default () => {
  // @essential-start
  const theme = {
    customStyles: {
      h2: {
        fontFamily: 'Times',
        fontSize: '26px',
        color: 'orange',
        fontStyle: 'italic',
        textDecoration: 'underline',
      },
      h3: {
        fontFamily: 'Tahoma',
        fontSize: '20px',
        color: 'purple',
        textDecoration: 'none',
      },
      quote: {
        lineHeight: '24px',
        fontWeight: 'bold',
        color: 'brown',
      },
    },
  };

  return (
    <RicosEditor
      initialContent={fromPlainText('Apply heading 2 or 3 from the toolbar to see the styles.')}
      placeholder="Type here!"
      theme={theme}
    />
  );
  // @essential-end
};
```

#### Breakout layout

`breakout.rule({ node }) => 'fullWidth' | 'normal'` runs once per node at layout time. Return `'fullWidth'` to let that node flow to the viewport edges; return `'normal'` (or omit the field entirely) to keep it inside the content column. `fullWidthPadding` overrides `normalPadding` for the `'fullWidth'` case, so you can leave a small inset even on edge-to-edge images.

Typical use: media plugins (`image`, `gallery`, `video`) go full-width on large viewports; text stays in the content column.
