Skip to content

Commit b23f16a

Browse files
authored
Merge pull request #5 from imagewize/fix/border-color-raw-slug-rule
Fix/border Color Raw Slug Rule
2 parents 06562c8 + 1fd2297 commit b23f16a

4 files changed

Lines changed: 71 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
44

55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## [2.2.1] - 2026-05-12
8+
9+
### Added
10+
11+
- **`border-color-raw-slug` rule** (`BaseRules`) — detects raw color slugs in `"border"` style objects (e.g. `"color":"border-light"`) that must be `"color":"var:preset|color|{slug}"`. A bare slug causes WordPress to emit `border-color:border-light` instead of the CSS variable, producing a `core/group` block validation mismatch in the site editor.
12+
713
## [2.2.0] - 2026-05-12
814

915
### Added

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# pt-cli — WordPress Block Theme Developer Toolkit
1+
# WordPress Pattern Toolkit
22

33
Scaffolding, compliance checking, and HTML template validation for WordPress FSE block themes.
44

src/Compliance/Rules/BaseRules.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ public function check(string $filePath): array
6363
$violations = array_merge($violations, $this->checkButtonClassNameOrder($content));
6464
$violations = array_merge($violations, $this->checkCoverBlockMinHeight($content));
6565
$violations = array_merge($violations, $this->checkEmptyBorderSideObjects($content));
66+
$violations = array_merge($violations, $this->checkBorderColorRawSlug($content));
6667
$violations = array_merge($violations, $this->checkButtonsWrapper($content));
6768
$violations = array_merge($violations, $this->checkGroupOverflowHidden($content));
6869
$violations = array_merge($violations, $this->checkOpacityInlineStyle($content));
@@ -264,6 +265,17 @@ private function checkEmptyBorderSideObjects(string $content): array
264265
return [];
265266
}
266267

268+
private function checkBorderColorRawSlug(string $content): array
269+
{
270+
// Matches "border":{..."color":"some-slug"...} where the value is not a var:preset reference.
271+
// Raw slugs (e.g. "color":"border-light") cause WordPress to emit border-color:border-light
272+
// instead of border-color:var(--wp--preset--color--border-light), producing a block validation mismatch.
273+
if (preg_match('/"border"\s*:\s*\{[^}]*"color"\s*:\s*"(?!var:preset\|color\|)[a-z][a-z0-9-]*"/', $content, $matches)) {
274+
return [$this->violation('border-color-raw-slug', 'Raw color slug found in "border" object — use "color":"var:preset|color|{slug}" instead of a bare slug (e.g. "color":"border-light" → "color":"var:preset|color|border-light"). A raw slug causes WordPress to emit border-color:{slug} rather than the CSS variable, producing a block validation mismatch.')];
275+
}
276+
return [];
277+
}
278+
267279
private function checkButtonsWrapper(string $content): array
268280
{
269281
$lines = explode("\n", $content);

tests/Compliance/Rules/BaseRulesTest.php

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,4 +314,56 @@ public function testIsAutofixableReturnsTrue(): void
314314
{
315315
$this->assertTrue($this->rules->isAutofixable());
316316
}
317+
318+
// ========================================================================
319+
// Border Color Raw Slug Tests
320+
// ========================================================================
321+
322+
public function testBorderColorRawSlugIsViolation(): void
323+
{
324+
$content = <<<'PHP'
325+
<?php ?>
326+
<!-- wp:group {"className":"elayne-engraving-option","style":{"border":{"width":"1px","color":"border-light","radius":"0"}}} -->
327+
<div class="wp-block-group elayne-engraving-option"></div>
328+
<!-- /wp:group -->
329+
PHP;
330+
331+
$file = $this->createTempFile($content);
332+
$violations = $this->rules->check($file);
333+
334+
$ruleNames = array_column($violations, 'rule');
335+
$this->assertContains('border-color-raw-slug', $ruleNames);
336+
}
337+
338+
public function testBorderColorPresetReferencePassesClean(): void
339+
{
340+
$content = <<<'PHP'
341+
<?php ?>
342+
<!-- wp:group {"className":"elayne-engraving-option","style":{"border":{"width":"1px","color":"var:preset|color|border-light","radius":"0"}}} -->
343+
<div class="wp-block-group elayne-engraving-option"></div>
344+
<!-- /wp:group -->
345+
PHP;
346+
347+
$file = $this->createTempFile($content);
348+
$violations = $this->rules->check($file);
349+
350+
$ruleNames = array_column($violations, 'rule');
351+
$this->assertNotContains('border-color-raw-slug', $ruleNames);
352+
}
353+
354+
public function testBorderColorEmptyObjectPassesClean(): void
355+
{
356+
$content = <<<'PHP'
357+
<?php ?>
358+
<!-- wp:group {"style":{"border":{"width":"1px","radius":"0"}}} -->
359+
<div class="wp-block-group"></div>
360+
<!-- /wp:group -->
361+
PHP;
362+
363+
$file = $this->createTempFile($content);
364+
$violations = $this->rules->check($file);
365+
366+
$ruleNames = array_column($violations, 'rule');
367+
$this->assertNotContains('border-color-raw-slug', $ruleNames);
368+
}
317369
}

0 commit comments

Comments
 (0)