rebly-sections 1.2.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,25 +5,36 @@ import re
5
5
 
6
6
 
7
7
  def check_has_color_scheme(content, schema_json):
8
- """Check if section schema includes color_scheme setting."""
8
+ """Check if color_scheme setting exists AND has a non-blank default."""
9
9
  if not schema_json:
10
10
  return ("WARN", "No schema to check for color_scheme")
11
11
  settings = schema_json.get("settings", [])
12
- has_cs = any(s.get("type") == "color_scheme" for s in settings)
13
- if has_cs:
14
- return ("PASS", "color_scheme setting present")
15
- return ("WARN", "Missing color_scheme setting recommended for theme consistency")
12
+ cs_settings = [s for s in settings if s.get("type") == "color_scheme"]
13
+ if not cs_settings:
14
+ return ("WARN", "Missing color_scheme setting — recommended for theme consistency")
15
+ # Verify default is non-blank (Shopify rejects blank default)
16
+ for cs in cs_settings:
17
+ default = cs.get("default", "")
18
+ if not default or str(default).strip() == "":
19
+ return ("WARN", "color_scheme has blank/missing default — Shopify will reject upload. Set default: \"scheme-1\"")
20
+ return ("PASS", "color_scheme setting present with valid default")
16
21
 
17
22
 
18
23
  def check_has_font_picker(content, schema_json):
19
- """Check if section schema includes at least one font_picker."""
24
+ """Check if font_picker exists AND is wired via font_face filter in Liquid."""
20
25
  if not schema_json:
21
26
  return ("WARN", "No schema to check for font_picker")
22
27
  settings = schema_json.get("settings", [])
23
- has_fp = any(s.get("type") == "font_picker" for s in settings)
24
- if has_fp:
25
- return ("PASS", "font_picker setting present")
26
- return ("WARN", "Missing font_picker sections with headings should include typography control")
28
+ fp_settings = [s for s in settings if s.get("type") == "font_picker"]
29
+ if not fp_settings:
30
+ return ("WARN", "Missing font_picker sections with headings should include typography control")
31
+ # Verify font_face filter usage (required to actually load the font)
32
+ if "font_face" not in content:
33
+ return ("WARN", "font_picker exists but font_face filter not used — font won't load. Add: {{ font_var | font_face: font_display: 'swap' }}")
34
+ # Verify CSS variable references the font family
35
+ if ".family" not in content and "font-family" not in content:
36
+ return ("WARN", "font_picker exists but font family not applied in CSS")
37
+ return ("PASS", "font_picker present and wired via font_face")
27
38
 
28
39
 
29
40
  def check_has_heading_tag(content, schema_json):
@@ -53,3 +64,20 @@ def check_no_hardcoded_colors(content, schema_json):
53
64
  if hex_colors:
54
65
  return ("WARN", f"Hardcoded colors in CSS: {', '.join(hex_colors[:5])} — use CSS variables instead")
55
66
  return ("PASS", "No hardcoded colors in CSS")
67
+
68
+
69
+ def check_has_font_size_controls(content, schema_json):
70
+ """Check if section has font size range settings for typography control."""
71
+ if not schema_json:
72
+ return ("WARN", "No schema to check for font size controls")
73
+ settings = schema_json.get("settings", [])
74
+ # Check if section uses heading/text elements
75
+ has_headings = bool(re.search(r'<h[1-6][\s>]', content))
76
+ has_description = bool(re.search(r'class="[^"]*description', content))
77
+ if not has_headings and not has_description:
78
+ return ("PASS", "No text elements requiring font size controls")
79
+ font_size_ids = [s.get("id", "") for s in settings if s.get("type") == "range"]
80
+ has_heading_size = any("font_size" in sid or "heading_size" in sid for sid in font_size_ids)
81
+ if has_headings and not has_heading_size:
82
+ return ("WARN", "Missing heading font size range — merchants can't adjust heading size")
83
+ return ("PASS", "Font size controls present")
@@ -39,10 +39,11 @@ QUALITY_CHECKS = [
39
39
 
40
40
  # Advisory checks (PASS/WARN) — imported from quality-gate-checks.py
41
41
  ADVISORY_CHECKS = [
42
- ("has_color_scheme", "color_scheme setting present"),
43
- ("has_font_picker", "font_picker setting present"),
42
+ ("has_color_scheme", "color_scheme setting with valid default"),
43
+ ("has_font_picker", "font_picker wired via font_face"),
44
44
  ("has_heading_tag", "Heading tag configurable via select"),
45
45
  ("no_hardcoded_colors", "No hardcoded hex colors in CSS"),
46
+ ("has_font_size_controls", "Font size range controls present"),
46
47
  ]
47
48
 
48
49
 
@@ -210,6 +211,7 @@ def run_quality_gate(filepath):
210
211
  "has_font_picker": _checks_mod.check_has_font_picker,
211
212
  "has_heading_tag": _checks_mod.check_has_heading_tag,
212
213
  "no_hardcoded_colors": _checks_mod.check_no_hardcoded_colors,
214
+ "has_font_size_controls": _checks_mod.check_has_font_size_controls,
213
215
  }
214
216
  for check_id, description in ADVISORY_CHECKS:
215
217
  if check_id not in advisory_fns:
@@ -50,20 +50,43 @@ You are an expert Shopify OS2.0 theme developer. Generate production-ready secti
50
50
  <mandatory_settings>
51
51
  CONDITIONAL RULES (apply based on section content):
52
52
  - IF section has heading or subheading text settings:
53
- -> MUST include font_picker for primary heading
53
+ -> MUST include font_picker with default "assistant_n4"
54
+ -> MUST wire font_picker to CSS using this exact pattern:
55
+ Liquid (before <style> tag, assign only — NO output here):
56
+ {%- assign heading_font = section.settings.heading_font -%}
57
+ Inside <style> tag (CRITICAL: font_face outputs raw CSS, MUST be inside <style>):
58
+ {{ heading_font | font_face: font_display: 'swap' }}
59
+ #section-{{ section_id }} { --heading-font: {{ heading_font.family }}, {{ heading_font.fallback_families }}; }
60
+ CSS on heading selector:
61
+ font-family: var(--heading-font);
62
+ WARNING: {{ font | font_face }} placed outside <style> renders as visible text on page!
63
+ -> MUST include heading_font_size (type: range, min: 16, max: 72, step: 2, unit: px, default: 40)
64
+ -> Wire heading_font_size as CSS variable and use in heading selector
54
65
  -> MUST include heading_tag (type: select, options: h1/h2/h3/h4) for SEO
66
+ - IF section has body/description text settings:
67
+ -> MUST include body_font_size (type: range, min: 12, max: 24, step: 1, unit: px, default: 16)
68
+ -> Wire body_font_size as CSS variable and use in description selector
55
69
  - ALWAYS include:
56
- -> color_scheme (type: color_scheme) for theme-wide color customization
70
+ -> color_scheme (type: color_scheme) MUST have "default": "scheme-1" (Shopify rejects blank default)
57
71
  -> padding_top + padding_bottom (type: range, 0-100px, step 4)
58
72
  -> All colors via CSS custom properties, NEVER hardcoded hex
59
73
  - IF section has CTA button:
60
74
  -> Button settings: button_label, button_link, button_style
75
+
76
+ SHOPIFY SCHEMA VALIDATION RULES (violations cause upload failure):
77
+ - color_scheme: MUST have non-blank "default" value (e.g., "scheme-1")
78
+ - font_picker: MUST have "default" in format "family_style" (e.g., "assistant_n4")
79
+ - range: MUST have min, max, step, unit, and default
80
+ - select: MUST have non-empty options array, each with value + label
81
+ - All non-display settings (except header/paragraph) MUST have "label"
61
82
  </mandatory_settings>
62
83
 
63
84
  <pre_output_checklist>
64
85
  Before writing code, verify your plan includes ALL:
65
- - color_scheme setting in schema
66
- - font_picker for heading text (if section has headings)
86
+ - color_scheme setting with "default": "scheme-1" (REQUIRED — blank default causes Shopify upload error)
87
+ - font_picker for heading text with font_face filter + CSS variable wiring (if section has headings)
88
+ - heading_font_size range setting wired to CSS variable (if section has headings)
89
+ - body_font_size range setting wired to CSS variable (if section has body text)
67
90
  - heading_tag select (h1/h2/h3/h4) (if section has headings)
68
91
  - Padding/margin controls
69
92
  - presets array with at least one preset
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rebly-sections",
3
- "version": "1.2.0",
3
+ "version": "1.3.1",
4
4
  "description": "Shopify section AI coding skill installer for Claude Code and Antigravity Kit",
5
5
  "author": "Rebly Sections",
6
6
  "homepage": "https://github.com/rebly-sections/sections-ai#readme",