rebly-sections 1.5.0 → 1.6.0

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.
@@ -76,6 +76,32 @@ def check_no_hardcoded_colors(content, schema_json):
76
76
  return ("PASS", "No hardcoded colors in CSS")
77
77
 
78
78
 
79
+ def check_has_responsive_visibility(content, schema_json):
80
+ """Check if section has show_on_mobile/tablet/desktop checkbox settings."""
81
+ if not schema_json:
82
+ return ("WARN", "No schema to check for responsive visibility")
83
+ settings = schema_json.get("settings", [])
84
+ setting_ids = [s.get("id", "") for s in settings]
85
+ required = ["show_on_mobile", "show_on_tablet", "show_on_desktop"]
86
+ missing = [r for r in required if r not in setting_ids]
87
+ if missing:
88
+ return ("WARN", f"Missing responsive visibility settings: {', '.join(missing)} — merchants can't hide section per breakpoint")
89
+ return ("PASS", "Responsive visibility settings present")
90
+
91
+
92
+ def check_has_section_dimensions(content, schema_json):
93
+ """Check if section has width and height dimension controls."""
94
+ if not schema_json:
95
+ return ("WARN", "No schema to check for section dimensions")
96
+ settings = schema_json.get("settings", [])
97
+ setting_ids = [s.get("id", "") for s in settings]
98
+ required = ["section_width", "section_width_custom", "section_min_height"]
99
+ missing = [r for r in required if r not in setting_ids]
100
+ if missing:
101
+ return ("WARN", f"Missing section dimension settings: {', '.join(missing)} — merchants can't control section size")
102
+ return ("PASS", "Section dimension settings present")
103
+
104
+
79
105
  def check_has_font_size_controls(content, schema_json):
80
106
  """Check if section has font size range settings for typography control."""
81
107
  if not schema_json:
@@ -46,6 +46,8 @@ ADVISORY_CHECKS = [
46
46
  ("has_heading_tag", "Heading tag configurable via select"),
47
47
  ("no_hardcoded_colors", "No hardcoded hex colors in CSS"),
48
48
  ("has_font_size_controls", "Font size range controls present"),
49
+ ("has_responsive_visibility", "Responsive visibility settings present"),
50
+ ("has_section_dimensions", "Section dimension settings present"),
49
51
  ("naming_rebly_prefix", "Schema name uses Rebly: prefix"),
50
52
  ("naming_bem_classes", "CSS classes follow BEM rebly-{component} convention"),
51
53
  ]
@@ -106,8 +108,11 @@ def check_no_liquid_in_style(content):
106
108
  return True
107
109
  style_content = style_match.group(1)
108
110
  # Allow simple output tags {{ }} but flag complex logic {% %}
109
- complex_tags = re.findall(r'\{%[-\s]*(if|for|case|unless|elsif)\s', style_content)
110
- return len(complex_tags) == 0
111
+ # Safe patterns: unless/case/when used by responsive visibility and section dimension controls
112
+ complex_tags = re.findall(r'\{%[-\s]*(if|for|case|unless|elsif|when)\s', style_content)
113
+ safe_patterns = {'unless', 'case', 'when'}
114
+ unsafe_tags = [t for t in complex_tags if t not in safe_patterns]
115
+ return len(unsafe_tags) == 0
111
116
 
112
117
 
113
118
  def check_has_section_tag(content):
@@ -267,6 +272,8 @@ def run_quality_gate(filepath):
267
272
  "has_heading_tag": _checks_mod.check_has_heading_tag,
268
273
  "no_hardcoded_colors": _checks_mod.check_no_hardcoded_colors,
269
274
  "has_font_size_controls": _checks_mod.check_has_font_size_controls,
275
+ "has_responsive_visibility": _checks_mod.check_has_responsive_visibility,
276
+ "has_section_dimensions": _checks_mod.check_has_section_dimensions,
270
277
  }
271
278
  # Built-in naming convention advisory checks (always available)
272
279
  advisory_fns.update({
@@ -119,6 +119,10 @@ CONDITIONAL RULES (apply based on section content):
119
119
  -> color_scheme (type: color_scheme) — MUST have "default": "scheme-1" (Shopify rejects blank default)
120
120
  -> padding_top + padding_bottom (type: range, 0-100px, step 4)
121
121
  -> All colors via CSS custom properties, NEVER hardcoded hex
122
+ -> Responsive visibility: show_on_mobile, show_on_tablet, show_on_desktop (checkbox, default: true)
123
+ Wire via CSS media queries on #shopify-section-{{ section.id }} using {%- unless -%} pattern
124
+ -> Section dimensions: section_width (select: full/page/narrow/custom), section_width_custom (range, 320-1920px, step 10, default 1200), section_min_height (range, 0-1000px, step 10, default 0)
125
+ Wire section_width via Liquid case/when on container max-width; wire min-height conditionally
122
126
  - IF section has CTA button:
123
127
  -> Button settings: button_label, button_link, button_style
124
128
 
@@ -144,6 +148,8 @@ Before writing code, verify your plan includes ALL:
144
148
  - heading_font_size range setting wired to CSS variable (if section has headings)
145
149
  - body_font_size range setting wired to CSS variable (if section has body text)
146
150
  - heading_tag select (h1/h2/h3/h4) (if section has headings)
151
+ - Responsive visibility settings (show_on_mobile, show_on_tablet, show_on_desktop checkboxes)
152
+ - Section dimension settings (section_width select + section_width_custom range + section_min_height range)
147
153
  - Padding/margin controls
148
154
  - presets array with at least one preset
149
155
  - @app block type
@@ -6,6 +6,12 @@
6
6
 
7
7
  {%- liquid
8
8
  assign section_id = section.id
9
+ comment
10
+ Section width: full (100%), page (1200px), narrow (800px), custom (px)
11
+ endcomment
12
+ assign sw = section.settings.section_width | default: 'page'
13
+ assign sw_custom = section.settings.section_width_custom | default: 1200
14
+ assign s_min_h = section.settings.section_min_height | default: 0
9
15
  -%}
10
16
 
11
17
  <section
@@ -29,9 +35,18 @@
29
35
 
30
36
  <style>
31
37
  #section-{{ section_id }} .rebly-{{ slug }}__container {
32
- max-width: 1200px;
33
- margin: 0 auto;
38
+ {%- case sw -%}
39
+ {%- when 'full' -%}
40
+ max-width: 100%;
41
+ {%- when 'narrow' -%}
42
+ max-width: 800px; margin: 0 auto;
43
+ {%- when 'custom' -%}
44
+ max-width: {{ sw_custom }}px; margin: 0 auto;
45
+ {%- else -%}
46
+ max-width: 1200px; margin: 0 auto;
47
+ {%- endcase -%}
34
48
  padding: var(--pt, 80px) 2rem var(--pb, 80px);
49
+ min-height: {{ s_min_h }}px;
35
50
  }
36
51
  /* Theme override: force inheritance within this section.
37
52
  Shopify themes (Dawn, Craft, etc.) set color/font directly on h1-h6, p, a
@@ -52,6 +67,22 @@
52
67
  line-height: inherit;
53
68
  letter-spacing: inherit;
54
69
  }
70
+ /* Responsive visibility — hide section per breakpoint */
71
+ {%- unless section.settings.show_on_mobile -%}
72
+ @media (max-width: 749px) {
73
+ #shopify-section-{{ section_id }} { display: none !important; }
74
+ }
75
+ {%- endunless -%}
76
+ {%- unless section.settings.show_on_tablet -%}
77
+ @media (min-width: 750px) and (max-width: 989px) {
78
+ #shopify-section-{{ section_id }} { display: none !important; }
79
+ }
80
+ {%- endunless -%}
81
+ {%- unless section.settings.show_on_desktop -%}
82
+ @media (min-width: 990px) {
83
+ #shopify-section-{{ section_id }} { display: none !important; }
84
+ }
85
+ {%- endunless -%}
55
86
  /* Responsive: reduce padding on mobile */
56
87
  @media (max-width: 749px) {
57
88
  #section-{{ section_id }} .rebly-{{ slug }}__container {
@@ -66,7 +97,66 @@
66
97
  "name": "Rebly: {{ display_name }}",
67
98
  "tag": "section",
68
99
  "class": "rebly-section",
69
- "settings": [],
100
+ "settings": [
101
+ {
102
+ "type": "header",
103
+ "content": "Responsive Visibility"
104
+ },
105
+ {
106
+ "type": "checkbox",
107
+ "id": "show_on_mobile",
108
+ "label": "Show on mobile",
109
+ "default": true
110
+ },
111
+ {
112
+ "type": "checkbox",
113
+ "id": "show_on_tablet",
114
+ "label": "Show on tablet",
115
+ "default": true
116
+ },
117
+ {
118
+ "type": "checkbox",
119
+ "id": "show_on_desktop",
120
+ "label": "Show on desktop",
121
+ "default": true
122
+ },
123
+ {
124
+ "type": "header",
125
+ "content": "Section Dimensions"
126
+ },
127
+ {
128
+ "type": "select",
129
+ "id": "section_width",
130
+ "label": "Section width",
131
+ "default": "page",
132
+ "options": [
133
+ { "value": "full", "label": "Full width (100%)" },
134
+ { "value": "page", "label": "Page width (1200px)" },
135
+ { "value": "narrow", "label": "Narrow (800px)" },
136
+ { "value": "custom", "label": "Custom (px)" }
137
+ ]
138
+ },
139
+ {
140
+ "type": "range",
141
+ "id": "section_width_custom",
142
+ "label": "Custom width (px)",
143
+ "min": 320,
144
+ "max": 1920,
145
+ "step": 10,
146
+ "default": 1200,
147
+ "unit": "px"
148
+ },
149
+ {
150
+ "type": "range",
151
+ "id": "section_min_height",
152
+ "label": "Minimum height (px)",
153
+ "min": 0,
154
+ "max": 1000,
155
+ "step": 10,
156
+ "default": 0,
157
+ "unit": "px"
158
+ }
159
+ ],
70
160
  "blocks": [
71
161
  { "type": "@app" }
72
162
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rebly-sections",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
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",