Skip to content

feat: add admin GUI for editing SLASHED design tokens - #77

Merged
jackgranatowski merged 10 commits into
mainfrom
feat/bricks-admin-gui
May 24, 2026
Merged

feat: add admin GUI for editing SLASHED design tokens#77
jackgranatowski merged 10 commits into
mainfrom
feat/bricks-admin-gui

Conversation

@kiro-agent

@kiro-agent kiro-agent Bot commented May 23, 2026

Copy link
Copy Markdown

This pull request was created by @kiro-agent on behalf of @jackgranatowski 👻

Comment with /kiro fix to address specific feedback or /kiro all to address everything.
Learn about Kiro autonomous agent


Summary

Adds a full WordPress admin settings page to the Bricks Builder integration plugin for visually editing all user-customizable SLASHED design tokens.

Changes

  • Admin settings page (class-admin-page.php) - Tabbed UI with 7 sections: Colors, Typography, Spacing, Radius, Shadows, Motion, Z-Index
  • Token defaults (class-token-defaults.php) - Factory default values for all editable tokens
  • CSS generator (class-css-generator.php) - Generates @layer slashed.overrides { :root { ... } } override CSS from saved settings
  • Admin assets (assets/admin-page.css, assets/admin-page.js) - Color picker integration, range/number sync, live preview panel, tab persistence
  • jsDelivr default - CSS bundle now loads from jsDelivr CDN by default (no local file setup needed)
  • Override injection - class-enqueue.php injects customized token CSS via wp_add_inline_style after the framework bundle

Features

  • Color pickers for 6 brand colors (light/dark) + 5 status colors
  • Paired min/max inputs for 12 fluid font sizes with clamp() regeneration
  • Font family text inputs for 7 font stacks
  • Range sliders + number inputs for spacing, radius, shadow, motion, and z-index scales
  • Per-section and global reset buttons
  • Live preview panel with real-time updates
  • CSS value sanitization to prevent injection
  • Overrides apply to both frontend and Bricks editor iframe
  • Admin page loads independently of Bricks (configure tokens before activating theme)

Testing

  • PHP syntax validated (php -l) on all new files
  • Internal semantic review passed (v2 approved after addressing 4 issues in fix commit)

Summary by CodeRabbit

  • New Features

    • Added a SLASHED admin settings page with tabbed controls and live preview to customize design tokens (colors, typography, spacing, radius, shadows, motion, z‑index).
    • Token defaults and on-site CSS override generation now enable immediate frontend overrides without extra steps.
    • Plugin can be activated even if the page builder is not present.
  • Documentation

    • Clarified CSS bundle behavior: default CDN path uses a pinned release tag, with local bundle detection overriding the CDN and a filter to select variants or target a specific ref.

Review Change Stack

kiro-agent and others added 5 commits May 23, 2026 20:18
Co-authored-by: Jack Granatowski <contact@codeslash.net>
…zation

- Create class-token-defaults.php with factory defaults for all 7 token sections
- Create class-admin-page.php with WordPress admin menu, tabbed interface, form
  handling, save/load via wp_options, and reset functionality
- Update slashed-bricks.php to bootstrap admin page on plugins_loaded hook
  (independent of Bricks theme activation)
Create Slashed_Bricks_CSS_Generator class that reads saved token
overrides from the slashed_bricks_tokens option and generates CSS
wrapped in @layer slashed.overrides { :root { ... } }.

- Maps all settings keys to CSS custom properties (colors, typography,
  spacing, radius, shadows, motion, z-index)
- Generates fluid type clamp() expressions from min/max rem values
- Outputs shadow-strength with dark mode calc() formula
- Outputs motion durations with motion-scale multiplication
- Only includes non-empty values in the output

Update class-enqueue.php to inject override CSS via wp_add_inline_style
attached to the slashed-framework handle, ensuring overrides load after
the framework in both frontend and Bricks editor contexts.
- Add CSS value sanitization to reject {, }, <, >, @ characters
- Replace empty() with isset/strict checks for numeric token fields
- Wrap admin-only hook in is_admin() to avoid frontend overhead
- Verify has_overrides() nested array path correctly handles '0'
@coderabbitai

coderabbitai Bot commented May 23, 2026

Copy link
Copy Markdown

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: c0e564e0-d14d-4bce-99f9-f75436710a2e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a Bricks integration admin for editing SLASHED design tokens: token defaults, a tabbed settings page with client preview and JS/CSS assets, backend save/reset handling and sanitization, generator for CSS custom-property overrides, frontend injection, and README updates for CDN bundling.

Changes

Design Token Admin & Override System

Layer / File(s) Summary
Design token defaults
integrations/bricks/includes/class-token-defaults.php
Slashed_Bricks_Token_Defaults provides static defaults for colors (oklch), typography (families and min/max sizes), spacing, radius, shadows, motion, and z-index.
CSS override generation
integrations/bricks/includes/class-css-generator.php
Slashed_Bricks_CSS_Generator reads slashed_bricks_tokens, generates per-category CSS custom properties (typography uses clamp()), wraps in @layer slashed.overrides, caches output, and exposes a filter.
Frontend integration & bootstrap
integrations/bricks/includes/class-enqueue.php, integrations/bricks/slashed-bricks.php
Injects generated override CSS inline after the main stylesheet via wp_add_inline_style() when overrides exist; slashed_bricks_get_css_url() now defaults to a pinned jsDelivr release ref with local dist/ precedence; admin initializer registered when is_admin().
Admin page backend & sanitization
integrations/bricks/includes/class-admin-page.php
Slashed_Bricks_Admin_Page registers the admin menu, enqueues/localizes assets, implements secure POST handler (capability + nonce), supports save/reset/reset-section flows, and sanitizes submitted token values.
Admin settings render & tab renderers
integrations/bricks/includes/class-admin-page.php
Renders tabbed UI for Colors, Typography, Spacing, Radius, Shadows, Motion, Z-Index with inputs named under slashed_tokens[...], includes live preview and status notices.
Admin styling and client interactivity
integrations/bricks/assets/admin-page.css, integrations/bricks/assets/admin-page.js
CSS for layout, tabs, form grid, live preview, and dirty-state; JS initializes tab persistence (URL hash), WP color pickers, range/number sync, live preview CSS generation, unsaved-change tracking, and reset confirmations.
Installation and CSS bundle documentation
integrations/bricks/README.md
README updated to document jsDelivr-pinned CSS default, local dist/ or symlink bundle precedence, and expanded slashed_bricks/css_bundle_url filter usage for variant/ref overrides.

Sequence Diagram

sequenceDiagram
  participant AdminUser
  participant AdminForm
  participant AdminScript
  participant Handler
  participant OptionStorage
  participant CSSGen
  participant FrontendEnqueue

  AdminUser->>AdminForm: load settings page
  AdminScript->>AdminForm: init tabs from URL hash and color pickers
  AdminUser->>AdminForm: change token inputs
  AdminScript->>AdminScript: regenerate live preview CSS
  AdminUser->>AdminForm: submit form
  AdminForm->>Handler: POST with tokens and nonce
  Handler->>Handler: verify capability and nonce
  Handler->>Handler: sanitize_section
  Handler->>OptionStorage: update_option slashed_bricks_tokens
  FrontendEnqueue->>CSSGen: request override CSS
  CSSGen->>OptionStorage: load slashed_bricks_tokens
  CSSGen->>CSSGen: generate override declarations
  FrontendEnqueue->>FrontendEnqueue: wp_add_inline_style generated CSS
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely describes the main change: adding an admin GUI for editing SLASHED design tokens, which is the primary objective of this PR.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/bricks-admin-gui

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@integrations/bricks/assets/admin-page.css`:
- Line 79: The CSS file has Stylelint violations around the keyframe name and
modern syntax: rename the `@keyframes` identifier slashedFadeIn to a kebab-case
name (e.g. slashed-fade-in) and update all references (animation,
animation-name) to that new identifier; convert any legacy color formats to the
modern canonical notation required by your linter (e.g. full hex `#rrggbb` or
functional rgb()/rgba()/hsl()/hsla() as configured) and replace any media
feature ranges using comparison operators with the canonical range syntax (use
min-width/max-width or media queries like (min-width: 600px) instead of
deprecated range operators). Apply the same fixes to the other occurrences
mentioned (lines around the other keyframe definitions and media queries) so
naming and syntax are consistent across the file.

In `@integrations/bricks/includes/class-admin-page.php`:
- Around line 247-249: The reset buttons in class-admin-page.php are missing the
JS hook classes expected by admin-page.js so the handlers never run; update the
submit buttons (the one with page-title-action and the other occurrence around
the 283-286 block) to include the CSS classes used by the script (add
slashed-reset-all-btn for the global reset button and slashed-reset-btn for
individual reset buttons) while keeping existing classes/attributes (e.g.,
page-title-action) intact so admin-page.js can find and bind to them.
- Around line 159-165: Validate incoming section slugs against the allowed tabs
before mutating options: when handling $_POST['reset_section'] and
$_POST['active_tab'] in class-admin-page.php, sanitize the value as you're
already doing, then check it exists in $this->tabs (e.g.
isset($this->tabs[$section]) or in_array($section, array_keys($this->tabs)))
before calling get_settings(), unset($settings[$section]) and
update_option(self::OPTION_NAME, $settings) or before using it to build the
redirect; if the slug is not a known tab, skip the mutation/redirect (or return
an error) to prevent creating/removing arbitrary top-level keys in the
slashed_bricks_tokens option.
- Around line 240-263: The admin template is missing the wrapper elements
targeted by admin-page.css; wrap the header block (the <h1> with the Reset All
form and the call to $this->render_notices( $message )) in a container with
class "slashed-admin-header" and wrap the nav block that iterates $this->tabs
(uses $this->tabs and $active_tab) in a container with class
"slashed-admin-tabs" so the stylesheet rules apply; ensure you add those classes
to the correct surrounding elements and keep existing markup/nonce/form handlers
intact.

In `@integrations/bricks/README.md`:
- Line 140: Update the README's default CDN URL that currently uses the mutable
ref
'https://cdn.jsdelivr.net/gh/codeslash-dev/SLASHED@main/dist/slashed.optimal.css'
to reference an immutable release tag or commit SHA (for example replace '`@main`'
with a version tag like '`@v1.2.3`' or a specific commit SHA) and update any
examples mentioning 'dist/slashed.optimal.css' to recommend pinning to a tagged
release or SHA for reproducibility and supply-chain safety.

In `@integrations/bricks/slashed-bricks.php`:
- Around line 92-100: The code currently registers slashed_bricks_admin_init for
admin pages but a separate deactivation branch still force-deactivates the
plugin when Bricks is inactive, which blocks the preconfiguration path; modify
the deactivation logic so it does not auto-deactivate in admin contexts: instead
of calling deactivate_plugins(...) when Bricks is missing, only show an admin
notice (or restrict deactivation to non-admin/front-end requests or the actual
plugin activation hook), and ensure the new slashed_bricks_admin_init +
add_action('plugins_loaded', 'slashed_bricks_admin_init') path remains usable
before Bricks is active.
- Around line 39-40: The default CDN URL ($default_url) currently points to the
moving ref '`@main`'—replace it with an immutable identifier (a commit SHA or
immutable release tag) so the CSS is pinned; update the assignment for
$default_url to reference a specific commit hash or a guaranteed immutable tag
and, if appropriate, map SLASHED_BRICKS_VERSION to that immutable CDN ref (use
SLASHED_BRICKS_VERSION only for WP enqueue version/caching and not as the CDN
pointer).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 8d5517a2-38b4-46b6-94b2-c977ab10e857

📥 Commits

Reviewing files that changed from the base of the PR and between 23c421c and 143b514.

📒 Files selected for processing (8)
  • integrations/bricks/README.md
  • integrations/bricks/assets/admin-page.css
  • integrations/bricks/assets/admin-page.js
  • integrations/bricks/includes/class-admin-page.php
  • integrations/bricks/includes/class-css-generator.php
  • integrations/bricks/includes/class-enqueue.php
  • integrations/bricks/includes/class-token-defaults.php
  • integrations/bricks/slashed-bricks.php

Comment thread integrations/bricks/assets/admin-page.css Outdated
Comment thread integrations/bricks/includes/class-admin-page.php
Comment thread integrations/bricks/includes/class-admin-page.php Outdated
Comment thread integrations/bricks/includes/class-admin-page.php Outdated
Comment thread integrations/bricks/README.md Outdated
Comment thread integrations/bricks/slashed-bricks.php Outdated
Comment thread integrations/bricks/slashed-bricks.php
@jackgranatowski

Copy link
Copy Markdown
Contributor

@coderabbitai review

@coderabbitai

coderabbitai Bot commented May 24, 2026

Copy link
Copy Markdown
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

kiro-agent and others added 2 commits May 24, 2026 13:56
Replaces the mutable @main ref with an immutable release tag (v0.2.12)
via a new SLASHED_BRICKS_CSS_REF constant. jsDelivr treats branch refs
as moving (12h cache) while commit/tag refs are effectively immutable,
which is required for reproducibility and supply-chain safety.

The pinned ref is overridable per-site via the slashed_bricks/css_bundle_url
filter and is bumped explicitly with each plugin release.

Addresses CodeRabbit review feedback on PR #77.

Co-authored-by: Jack Granatowski <contact@codeslash.net>
@jackgranatowski

Copy link
Copy Markdown
Contributor

@coderabbitai review

@coderabbitai

coderabbitai Bot commented May 24, 2026

Copy link
Copy Markdown
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
integrations/bricks/includes/class-admin-page.php (1)

226-228: 💤 Low value

Consider adding semicolon to the sanitization blocklist.

The current sanitization prevents escaping the CSS block context, but semicolons could allow injecting additional CSS declarations within :root. While the blast radius is limited (admins already have full control), stripping ; would provide defense-in-depth.

 private function sanitize_css_value( $value ) {
-    return str_replace( array( '{', '}', '<', '>', '@' ), '', $value );
+    return str_replace( array( '{', '}', '<', '>', '@', ';' ), '', $value );
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@integrations/bricks/includes/class-admin-page.php` around lines 226 - 228,
The sanitize_css_value function currently strips { } < > @ but not semicolons;
update the sanitizer in sanitize_css_value to also remove ';' from $value so CSS
declarations cannot be chained (i.e., include ';' in the array passed to
str_replace), ensuring the logics in sanitize_css_value continue returning the
cleaned string.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@integrations/bricks/includes/class-admin-page.php`:
- Around line 226-228: The sanitize_css_value function currently strips { } < >
@ but not semicolons; update the sanitizer in sanitize_css_value to also remove
';' from $value so CSS declarations cannot be chained (i.e., include ';' in the
array passed to str_replace), ensuring the logics in sanitize_css_value continue
returning the cleaned string.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e33f3016-ce46-45eb-a536-96669b26e85e

📥 Commits

Reviewing files that changed from the base of the PR and between 143b514 and 22830c0.

📒 Files selected for processing (4)
  • integrations/bricks/README.md
  • integrations/bricks/assets/admin-page.css
  • integrations/bricks/includes/class-admin-page.php
  • integrations/bricks/slashed-bricks.php
✅ Files skipped from review due to trivial changes (1)
  • integrations/bricks/README.md

@jackgranatowski

Copy link
Copy Markdown
Contributor
🧹 Nitpick comments (1)
integrations/bricks/includes/class-admin-page.php (1)

226-228: 💤 Low value

Consider adding semicolon to the sanitization blocklist.

The current sanitization prevents escaping the CSS block context, but semicolons could allow injecting additional CSS declarations within :root. While the blast radius is limited (admins already have full control), stripping ; would provide defense-in-depth.

 private function sanitize_css_value( $value ) {
-    return str_replace( array( '{', '}', '<', '>', '@' ), '', $value );
+    return str_replace( array( '{', '}', '<', '>', '@', ';' ), '', $value );
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@integrations/bricks/includes/class-admin-page.php` around lines 226 - 228,
The sanitize_css_value function currently strips { } < > @ but not semicolons;
update the sanitizer in sanitize_css_value to also remove ';' from $value so CSS
declarations cannot be chained (i.e., include ';' in the array passed to
str_replace), ensuring the logics in sanitize_css_value continue returning the
cleaned string.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@integrations/bricks/includes/class-admin-page.php`:
- Around line 226-228: The sanitize_css_value function currently strips { } < >
@ but not semicolons; update the sanitizer in sanitize_css_value to also remove
';' from $value so CSS declarations cannot be chained (i.e., include ';' in the
array passed to str_replace), ensuring the logics in sanitize_css_value continue
returning the cleaned string.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e33f3016-ce46-45eb-a536-96669b26e85e

📥 Commits

Reviewing files that changed from the base of the PR and between 143b514 and 22830c0.

📒 Files selected for processing (4)
  • integrations/bricks/README.md
  • integrations/bricks/assets/admin-page.css
  • integrations/bricks/includes/class-admin-page.php
  • integrations/bricks/slashed-bricks.php
✅ Files skipped from review due to trivial changes (1)
  • integrations/bricks/README.md

/kiro fix

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