Skip to content

refactor: Rename Builder Variable to Builder Token, add Font tokens - #676

Open
surajshetty3416 wants to merge 24 commits into
frappe:developfrom
surajshetty3416:builder-tokens
Open

refactor: Rename Builder Variable to Builder Token, add Font tokens#676
surajshetty3416 wants to merge 24 commits into
frappe:developfrom
surajshetty3416:builder-tokens

Conversation

@surajshetty3416

@surajshetty3416 surajshetty3416 commented Jul 16, 2026

Copy link
Copy Markdown
Member
  • Renames the Builder Variable doctype to Builder Token (variable_nametoken_name); token doc names are untouched, so existing var(--id) references keep resolving. Pre-model-sync patch migrates existing sites.
  • New Font token type: fontFamily can be var(--token), resolved when fonts load (editor and published pages).
  • Design System manager with Colors/Fonts/Dimensions tabs, token counts, and a copy-handle button per row.
  • Backward compatible: /builder_assets/variables.css keeps serving the token CSS and sync_builder_variables stays callable.

Demo

design-tokens-demo.1.mp4

Screenshots

Design System manager — color tokens with light/dark values, search, per-row copy of the var(--id) handle:

Design System color tokens

Font tokens render as type specimens:

Font tokens tab

Editing one token rethemes every block bound to it (accent flipped green → terracotta):

Token edit rethemes the page

Typography Family lists font tokens first; picking one stores var(--id):

Font token in Typography panel

surajshetty3416 and others added 8 commits July 16, 2026 14:50
"Variable" was confusing for users and LLMs alike; the doctype is the
site's design-token registry, so name it that. Only the DocType and the
label field (variable_name -> token_name) are renamed - token doc names
(the CSS --<id> handles) are untouched, so every existing page's
var(--id) references keep resolving byte-for-byte.

Pre-model-sync patch handles the rename (verified on a virgin site: all
rows migrate, old table dropped). The variables.css route becomes
tokens.css; published HTML is generated live so no stored references
break. The historic refactor_builder_variables patch keeps operating on
the old names it targets (it runs before the rename) with only its
import repointed.

Co-Authored-By: Claude <noreply@anthropic.com>
The css2 API returns 400 for any wght@ request a family does not carry
(Italiana, Young Serif, Caprasimo are 400-only), which surfaced as CORS
noise and dead font loads. On a weighted load failure, retry the family
default; the browser synthesises the bold.

Co-Authored-By: Claude <noreply@anthropic.com>
New token type "Font" (value = family name). Resolution is centralized
where fonts load, so no caller cares whether a style is tokenized:

- setFont() resolves var(--id) through the token registry before
  loading (covers canvas blocks, scraped HTML, Typography panel)
- get_font_family() resolves tokens server-side so published pages
  Google Fonts links include tokenized families (unresolvable tokens
  are skipped, not emitted as bogus families)
- the Typography Family control lists Font tokens first ("Design
  tokens" group) - picking one stores var(--id), so editing the token
  re-fonts every block bound to it; bound values display as
  "Label (Family)"
- the canvas preloads every Font token family on boot

Co-Authored-By: Claude <noreply@anthropic.com>
The variables popup becomes the Design System manager: type tabs filter
the grid, Color keeps the Name/Light/Dark picker grid, Font and
Dimension get a Name/Value layout (font values render as their own
typeface specimen). New rows inherit the active tab's type; CSV
import/export understands a Type column; left-panel tab renamed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Colors/Fonts/Dimensions tabs now show how many tokens each holds. The count
is search-independent (stable while filtering within a tab) and hides when a
type is empty.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…andle

A hover-revealed copy button on every Design System token row writes the
token's CSS handle var(--<id>) to the clipboard, so it can be pasted straight
into a style field. Shows a check tick for ~1.2s on success. Verified live:
copies var(--wander-accent) etc.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Show a Font token as its friendly name in violet (like Text Color shows
'Ink Dark Blue') instead of the raw var(--uuid), with a specimen 'A'
prefix rendered in the resolved family. Add a 'Save as Token' action to
the dropdown so a plain family can be promoted to a Font token in place,
alongside the existing Upload Font action.

New FontInput/FontInputActions mirror ColorInput/NewBuilderToken; the
Family control swaps its inline Autocomplete for FontInput. Autocomplete's
ActionButton label/handler/icon become optional (component-only actions).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
/builder_assets/variables.css serves the same token CSS as tokens.css,
so pages published (or cached) before the rename keep their stylesheet.
builder.utils.sync_builder_variables stays callable as an alias.

Co-Authored-By: Claude <noreply@anthropic.com>
@surajshetty3416 surajshetty3416 changed the title Rename Builder Variable to Builder Token, add Font tokens and Design System manager refactor: Rename Builder Variable to Builder Token, add Font tokens and Design System manager Jul 16, 2026
@greptile-apps

greptile-apps Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Confidence Score: 5/5

Safe to merge; migration is guarded by table-existence checks, compat aliases cover all old call sites, and the CSS token cache busting now covers both routes.

The rename is systematic and complete: the pre-model-sync patch, field rename, CSS compat route, frontend singleton composable, and copy/paste backward-compat shims all work together correctly. No functional regressions were found in the changed paths.

Files Needing Attention: No files require special attention.

Reviews (14): Last reviewed commit: "fix: add a way to cancel the new-token r..." | Re-trigger Greptile

@codecov

codecov Bot commented Jul 16, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 34.84848% with 43 lines in your changes missing coverage. Please review.
✅ Project coverage is 57.36%. Comparing base (f737b23) to head (34fde8b).

Files with missing lines Patch % Lines
builder/utils.py 24.24% 25 Missing ⚠️
...der/builder/doctype/builder_token/builder_token.py 26.66% 11 Missing ⚠️
...ilder/builder/doctype/builder_page/builder_page.py 72.72% 3 Missing ⚠️
builder/install.py 0.00% 2 Missing ⚠️
builder/api.py 50.00% 1 Missing ⚠️
builder/export_import_standard_page.py 0.00% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop     #676      +/-   ##
===========================================
- Coverage    57.59%   57.36%   -0.24%     
===========================================
  Files           35       35              
  Lines         4271     4306      +35     
===========================================
+ Hits          2460     2470      +10     
- Misses        1811     1836      +25     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

The hardcoded type: "Color" sat after the conditional spread of the
parsed type, so every imported row became a Color token regardless of
its Type cell. Parse the type case-insensitively (Color/Font/Dimension,
defaulting to Color) and include typed rows in the sample CSV.

Co-Authored-By: Claude <noreply@anthropic.com>
@surajshetty3416 surajshetty3416 changed the title refactor: Rename Builder Variable to Builder Token, add Font tokens and Design System manager refactor: Rename Builder Variable to Builder Token, add Font tokens Jul 16, 2026
…nager

The type tabs were hand-rolled buttons and the copy affordance a bare
<button>; frappe-ui already ships both. Token counts fold into the tab
labels.

Co-Authored-By: Claude <noreply@anthropic.com>
Comment thread builder/builder/doctype/builder_token/builder_token.py
The compat route is page-cached like tokens.css; without this, sites
published before the rename keep serving stale token CSS until the
cache TTL expires.

Co-Authored-By: Claude <noreply@anthropic.com>
Comment thread frontend/src/utils/colorOptions.ts
surajshetty3416 and others added 11 commits July 16, 2026 17:23
Font and Dimension tokens leaked into every color dropdown with broken
swatches. Legacy rows with a blank or lowercase type still count as
colors.

Co-Authored-By: Claude <noreply@anthropic.com>
Template fixture exports made before the rename still declare
doctype Builder Variable, so make_records failed on every group
shipped by builder_hub. Route fixture imports through a rename
map when the old doctype no longer exists on the site.

Co-Authored-By: Claude <noreply@anthropic.com>
The rename patch is in pre_model_sync, so by the time
refactor_builder_variables runs the Builder Variable table is gone and
has_column raises TableMissingError, failing migrate on any site that
had not already applied the refactor.
A hub or clipboard that predates the Builder Token rename still sends
Builder Variable docs with variable_name, which is mandatory-field or
missing-doctype death on an upgraded site. Normalize renamed docs in one
place and use it for hub bundles, disk fixtures and pasted clipboards.

Cross-site paste also mapped block refs to an id the server never
assigns (autoname clears an incoming name outside imports), so pasted
tokens never resolved. Reuse an equivalent token when one exists, else
map to the id the insert returns.
Leftovers from the rename: the doctype field label and the New/Edit
dialog still said Variable, and the manager's toasts, empty state and
sample CSV counted variables.

Also normalize a token's type in one place (tokenType) so a legacy blank
or lower-cased type lands in the same tab it shows up in the color
picker, and resolve font tokens from the cached token map instead of a
query per tokenized font.
The new-row value input scheduled a 300ms debounced save on every
keystroke. A short pause while typing (e.g. between "24" and "px")
fired the save, created the token from a partial value, and unmounted
the row's inputs mid-edit. Row creation now commits only on Enter or
when focus leaves the row, as handleNewRowFocusOut already intended.

The row's copy-handle button also used hidden/block on hover, which
changed row height when the button was taller than the row's text.
Switched to invisible/visible so the button always reserves its
layout space.

Renamed updateColor to updateRowValue: it sets row.value for every
token type, not only colors.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LJHQRHG8UXfdpGWaz5U3Jj
handleBlur re-resolved the input by matching option labels, so
selecting one of two tokens that share a display name would get
overwritten by the other on blur.
Right-clicking the not-yet-created row now shows a "Remove" option
in the context menu, same as Esc.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants