Skip to content

Commit 028a3ca

Browse files
committed
docs(gravityview): split the token JSON guide off the theming page
The theming page is for someone restyling a View with CSS. Wiring the token file into Style Dictionary or Figma is a different job for a different reader, and it had grown into 119 lines in the middle of that page. Moves it to /gravityview/design-tokens/ and leaves a two-sentence pointer behind. The new page opens by saying who it is not for. Trimmed on the way across: a statistic about how few token paths match their CSS variable name (the one example makes the point), a paragraph on what survives each tool's internal model, and the named `$extensions` sub-keys. The Style Dictionary duration workaround comes back, since a page about build pipelines is where it belongs. Claude-Session: https://claude.ai/code/session_01QMQRQzykRFy5uhbadgm4gw
1 parent 7705584 commit 028a3ca

4 files changed

Lines changed: 178 additions & 99 deletions

File tree

docusaurus.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ const gravityview_nav = {
100100
items: [
101101
{ label: 'GravityView', href: '/docs/gravityview/' },
102102
{ label: 'Theming', href: '/gravityview/css-tokens/' },
103+
{ label: 'Design Tokens (JSON)', href: '/gravityview/design-tokens/' },
103104
{
104105
type: 'html',
105106
value: '<hr class="dropdown-separator">',

sidebars-gravityview.js

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
/**
44
* GravityView-specific sidebar.
55
*
6-
* Same autogenerated tree as the shared sidebars.js, plus a manual link to the
7-
* CSS Design Tokens (theming) page. That page lives at /gravityview/css-tokens/
8-
* as a src/pages React route — it is NOT a doc under docs/gravityview/, so the
9-
* autogenerated sidebar can't pick it up on its own.
6+
* Same autogenerated tree as the shared sidebars.js, plus manual links to the
7+
* theming and design-token pages. Both live under src/pages as React routes —
8+
* they are NOT docs under docs/gravityview/, so the autogenerated sidebar
9+
* can't pick them up on its own.
1010
*/
1111

1212
/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */
@@ -18,6 +18,11 @@ const sidebars = {
1818
label: 'Theming',
1919
href: '/gravityview/css-tokens/',
2020
},
21+
{
22+
type: 'link',
23+
label: 'Design Tokens (JSON)',
24+
href: '/gravityview/design-tokens/',
25+
},
2126
],
2227
};
2328

src/pages/gravityview/css-tokens.jsx

Lines changed: 38 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -208,123 +208,66 @@ body .gv-container { --gv-color-primary: #7a1f1f; }
208208
:root { --gv-color-primary: #7a1f1f; }`}</code>
209209
</pre>
210210

211-
<h2>Machine-readable token files</h2>
211+
<h2>Target a View with placeholders</h2>
212212
<p>
213-
Two generated files publish this reference as data. Both rebuild from GravityView's token registry on every
214-
deploy, so anything you write into them is overwritten.
213+
When you enter rules in GravityView's <strong>Custom CSS</strong> field (View Settings &rarr;{' '}
214+
<strong>Custom Code</strong>), GravityView swaps three placeholders for that View's own values as the page
215+
loads, so you can target a single View without hardcoding its container ID:
215216
</p>
216217
<table>
217218
<thead>
218219
<tr>
219-
<th>File</th>
220-
<th>Format</th>
221-
<th>Use it for</th>
220+
<th>Placeholder</th>
221+
<th>Replaced with</th>
222+
<th>Example output</th>
222223
</tr>
223224
</thead>
224225
<tbody>
225226
<tr>
226-
<td>
227-
<a href="/api/css-tokens.tokens.json">
228-
<code>/api/css-tokens.tokens.json</code>
229-
</a>
230-
</td>
231-
<td>
232-
<a href="https://www.designtokens.org/TR/2025.10/format/">Design Tokens Format Module 2025.10</a>
233-
</td>
234-
<td>Design-tool interop: Style Dictionary, Terrazzo, Tokens Studio, Figma</td>
227+
<td><code>VIEW_SELECTOR</code></td>
228+
<td>A high-specificity CSS selector targeting only this View</td>
229+
<td><code>.gv-container.gv-container-123</code></td>
235230
</tr>
236231
<tr>
237-
<td>
238-
<a href="/api/css-tokens.json">
239-
<code>/api/css-tokens.json</code>
240-
</a>
241-
</td>
242-
<td>Flat GravityKit-specific JSON</td>
243-
<td>The lossless record: every token, every field, no exceptions</td>
232+
<td><code>VIEW_ID</code></td>
233+
<td>The View's ID number</td>
234+
<td><code>123</code></td>
235+
</tr>
236+
<tr>
237+
<td><code>GF_FORM_ID</code></td>
238+
<td>The connected Gravity Forms form ID</td>
239+
<td><code>5</code></td>
244240
</tr>
245241
</tbody>
246242
</table>
247243
<p>
248-
The DTCG file validates against the{' '}
249-
<a href="https://www.designtokens.org/schemas/2025.10/format.json">
250-
Design Tokens Community Group's published JSON Schema
251-
</a>
252-
, which the build enforces. Read <code>$extensions["com.gravitykit.tokens"].counts</code> for how many tokens
253-
it carries.
254-
</p>
255-
256-
<h3>Token paths are not CSS variable names</h3>
257-
<p>
258-
A token at <code>gravityview.border.entry_color</code> is the CSS variable{' '}
259-
<code>--gv-entry-border-color</code>. The registry reorders and rewrites segments, so only about a fifth of
260-
tokens match a naive path-to-name transform. Drive your name transform from{' '}
261-
<code>$extensions["com.gravitykit.tokens"].cssVar</code>, or you will generate variables GravityView never
262-
reads.
244+
Prefer <code>VIEW_SELECTOR</code> for token overrides: its double-class selector
245+
(<code>.gv-container.gv-container-123</code>) outranks the layered defaults, so your values win without{' '}
246+
<code>!important</code> and without pinning the View ID by hand.
263247
</p>
264248
<pre>
265-
<code>{`import SD from 'style-dictionary';
266-
267-
const EXT = 'com.gravitykit.tokens';
268-
269-
// Use the shipped CSS variable name, not the token path.
270-
SD.registerTransform({
271-
name: 'name/gv-cssvar',
272-
type: 'name',
273-
transform: (t) => t.$extensions[EXT].cssVar.replace(/^--/, ''),
274-
});
275-
276-
// Style Dictionary 5.x renders DTCG duration objects as "[object Object]".
277-
SD.registerTransform({
278-
name: 'duration/css-dtcg',
279-
type: 'value',
280-
transitive: true,
281-
filter: (t) => t.$type === 'duration' && typeof t.$value === 'object',
282-
transform: (t) => \`\${t.$value.value}\${t.$value.unit}\`,
283-
});
284-
285-
const sd = new SD({
286-
source: ['css-tokens.tokens.json'],
287-
platforms: {
288-
css: {
289-
prefix: '',
290-
transforms: SD.hooks.transformGroups.css
291-
.map((t) => (t === 'name/kebab' ? 'name/gv-cssvar' : t))
292-
.concat('duration/css-dtcg'),
293-
files: [{ destination: 'gravityview-tokens.css', format: 'css/variables' }],
294-
},
295-
},
296-
});
297-
await sd.buildAllPlatforms();`}</code>
249+
<code>{`/* In GravityView's Custom CSS field. VIEW_SELECTOR resolves to this View. */
250+
VIEW_SELECTOR { --gv-color-primary: #7a1f1f; }`}</code>
298251
</pre>
299252
<p>
300-
Terrazzo reads the file without configuration. Its <code>core/consistent-naming</code> rule defaults to
301-
kebab-case and will warn on GravityView's snake_case leaf names; set{' '}
302-
<code>{'{ format: "snake_case" }'}</code> on that rule to silence it.
303-
</p>
304-
<p>
305-
<strong>File-level metadata does not survive either tool.</strong> Style Dictionary drops the root{' '}
306-
<code>$description</code>, the root <code>$extensions</code> manifest and every group that has no{' '}
307-
<code>$value</code>; Terrazzo keeps them only on the raw parsed document, not in its token model. Per-token{' '}
308-
<code>$extensions</code> (including <code>cssVar</code>) do survive both. If you need the counts, the derived
309-
list or the unrepresentable list, read them from the JSON directly rather than from a tool's output.
253+
Placeholders resolve only inside a View's Custom CSS/JavaScript field, not in your theme's stylesheet.
254+
Developers can add or change them with the{' '}
255+
<a href="/gravityview/filters/gk-gravityview-custom-code-placeholders">
256+
<code>gk/gravityview/custom-code/placeholders</code>
257+
</a>{' '}
258+
filter. See{' '}
259+
<a href="https://www.gravitykit.com/docs/gravityview/customizing-your-views/adding-custom-css-to-your-website/#available-placeholders">
260+
Adding Custom CSS to Your Website
261+
</a>{' '}
262+
for the full walkthrough.
310263
</p>
311264

312-
<h3>Tokens with no DTCG equivalent</h3>
313-
<p>
314-
DTCG has no way to express a few CSS values GravityView ships: percentage widths, <code>em</code> lengths,{' '}
315-
<code>clamp()</code> and <code>min()</code>, <code>color-mix()</code>, and keywords like{' '}
316-
<code>inherit</code> or <code>stretch</code>. Rather than drop them or invent a type, each appears at its
317-
normal path as a group with no <code>$value</code>, carrying its description and raw CSS under{' '}
318-
<code>$extensions</code>. Token-consuming tools skip these; nothing disappears silently. They are also listed
319-
together under <code>$extensions["com.gravitykit.tokens"].metadataOnly</code>.
320-
</p>
265+
<h2>Using the tokens as data</h2>
321266
<p>
322-
A second group of tokens is expressible but <em>resolved</em>. <code>--gv-font-size-xs</code> ships as{' '}
323-
<code>calc(var(--gv-font-size-base) * 0.75)</code>, which DTCG cannot represent, so the file carries{' '}
324-
<code>0.75rem</code>, its value at GravityView's defaults. Change the base font size and the browser computes
325-
something different from what a Figma library synced from this file shows. Every such token says so in its{' '}
326-
<code>$description</code> and is listed under{' '}
327-
<code>$extensions["com.gravitykit.tokens"].derivedTokens</code>.
267+
The same tokens are published as JSON, in the{' '}
268+
<a href="https://www.designtokens.org/TR/2025.10/format/">Design Tokens (DTCG)</a> format, if you want to pull
269+
them into Style Dictionary, Terrazzo, Tokens Studio or Figma. See{' '}
270+
<a href="/gravityview/design-tokens/">Design Tokens (JSON)</a>.
328271
</p>
329272

330273
<h2>Token reference</h2>
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
import Layout from '@theme/Layout';
2+
3+
export default function DesignTokensPage() {
4+
return (
5+
<Layout
6+
title="GravityView Design Tokens (JSON)"
7+
description="GravityView's design tokens as data, in the Design Tokens Community Group format, for Style Dictionary, Terrazzo, Tokens Studio and Figma."
8+
>
9+
<main className="container margin-vert--lg">
10+
<h1>Design Tokens (JSON)</h1>
11+
<p>
12+
GravityView's theme tokens are published as data on every deploy, so you can pull them into a design system
13+
pipeline instead of copying values by hand. If you only want to restyle a View with CSS, see{' '}
14+
<a href="/gravityview/css-tokens/">Theming</a> instead.
15+
</p>
16+
17+
<table>
18+
<thead>
19+
<tr>
20+
<th>File</th>
21+
<th>Format</th>
22+
</tr>
23+
</thead>
24+
<tbody>
25+
<tr>
26+
<td>
27+
<a href="/api/css-tokens.tokens.json">
28+
<code>css-tokens.tokens.json</code>
29+
</a>
30+
</td>
31+
<td>
32+
<a href="https://www.designtokens.org/TR/2025.10/format/">Design Tokens (DTCG) 2025.10</a>, for Style
33+
Dictionary, Terrazzo, Tokens Studio and Figma
34+
</td>
35+
</tr>
36+
<tr>
37+
<td>
38+
<a href="/api/css-tokens.json">
39+
<code>css-tokens.json</code>
40+
</a>
41+
</td>
42+
<td>Flat JSON with every registry field, including the ones DTCG has no place for</td>
43+
</tr>
44+
</tbody>
45+
</table>
46+
47+
<p>
48+
The DTCG file declares its own <code>$schema</code>, so editors validate it as you work, and it is checked
49+
against the{' '}
50+
<a href="https://www.designtokens.org/schemas/2025.10/format.json">
51+
Design Tokens Community Group's published schema
52+
</a>{' '}
53+
before it is published.
54+
</p>
55+
56+
<h2>Use <code>cssVar</code>, not the token path</h2>
57+
<p>
58+
A token's path and its CSS variable are not the same string. <code>gravityview.border.entry_color</code> is{' '}
59+
<code>--gv-entry-border-color</code>. Read the variable name from{' '}
60+
<code>$extensions["com.gravitykit.tokens"].cssVar</code> so the CSS you generate matches what GravityView
61+
actually reads.
62+
</p>
63+
64+
<h2>Style Dictionary</h2>
65+
<p>One custom transform points the names at the shipped CSS variables:</p>
66+
<pre>
67+
<code>{`import SD from 'style-dictionary';
68+
69+
const EXT = 'com.gravitykit.tokens';
70+
71+
SD.registerTransform({
72+
name: 'name/gv-cssvar',
73+
type: 'name',
74+
transform: (t) => t.$extensions[EXT].cssVar.replace(/^--/, ''),
75+
});
76+
77+
const sd = new SD({
78+
source: ['css-tokens.tokens.json'],
79+
platforms: {
80+
css: {
81+
prefix: '',
82+
transforms: SD.hooks.transformGroups.css.map((t) =>
83+
t === 'name/kebab' ? 'name/gv-cssvar' : t,
84+
),
85+
files: [{ destination: 'gravityview-tokens.css', format: 'css/variables' }],
86+
},
87+
},
88+
});
89+
90+
await sd.buildAllPlatforms();`}</code>
91+
</pre>
92+
<p>
93+
Style Dictionary 5.x renders DTCG <code>duration</code> values as <code>[object Object]</code>, which affects
94+
GravityView's transition tokens. Add this transform alongside the one above and include it in the list:
95+
</p>
96+
<pre>
97+
<code>{`SD.registerTransform({
98+
name: 'duration/css-dtcg',
99+
type: 'value',
100+
transitive: true,
101+
filter: (t) => t.$type === 'duration' && typeof t.$value === 'object',
102+
transform: (t) => \`\${t.$value.value}\${t.$value.unit}\`,
103+
});`}</code>
104+
</pre>
105+
106+
<h2>Terrazzo</h2>
107+
<p>
108+
Terrazzo reads the file without configuration. Its <code>core/consistent-naming</code> rule warns on
109+
GravityView's snake_case names until you set it to <code>{'{ format: "snake_case" }'}</code>.
110+
</p>
111+
112+
<h2>What the DTCG file leaves out</h2>
113+
<p>
114+
DTCG has no way to express a handful of values GravityView ships, such as percentage widths,{' '}
115+
<code>clamp()</code>, and keywords like <code>inherit</code>. Those tokens still appear at their usual path
116+
with their description and raw CSS attached, but without a value, so design tools skip them.
117+
</p>
118+
<p>
119+
A few others, like <code>--gv-font-size-xs</code>, are calculated from another token. The file carries the
120+
value at GravityView's defaults and says so in the token's description, so a library synced from it can drift
121+
if you change the token it derives from.
122+
</p>
123+
<p>
124+
Both groups are listed under <code>$extensions["com.gravitykit.tokens"]</code> if you want to check them
125+
programmatically, and the flat file always has the exact CSS.
126+
</p>
127+
</main>
128+
</Layout>
129+
);
130+
}

0 commit comments

Comments
 (0)