Files
cms-SiteForge/themes/trade-pro/_professional_components.html
T
浅念 22b614118b feat: SVG icon macro library replaces bare text arrows in trade-pro
Task 9 (new design, not a cms port): _professional_components.html gains
an icon(name, size, cls) macro — 10 inline line-style glyphs (arrow-right,
arrow-left, chevron-down, check, phone, mail, location, download, search,
quote), 24x24 viewBox, stroke=currentColor, stroke-width 1.5, round
caps/joins, decorative aria-hidden + focusable=false, default size
var(--sf-tp-icon-size-md, 20px), unknown names fall back to arrow-right.
Every glyph is a single <path> so the d attribute needs no |safe.

All bare text arrows (->, <-, ↗, ▾, ⌕) in the macro library, pro.html,
site.html and pages/* are replaced with macro calls (site.html keeps a
self-contained copy of the arrow glyph because its rendering envs cannot
import the macro library); the filters macro search box gains an inline
search icon; footer links gain small arrows. theme.css adds .sf-tp-icon
alignment, in-button icon spacing, and search-box icon positioning.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-23 08:35:52 +08:00

44 lines
5.2 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{# trade-pro macro library: passthrough copy of the shared
themes/_professional_components.html with English strings, plus the
trade-pro inline SVG icon set (Task 9). Icons are decorative
server-side inlines: no JS dependency, currentColor strokes. #}
{# ── SVG icon set (Task 9) ──────────────────────────────────────────────
Style contract: 24×24 viewBox, stroke=currentColor, stroke-width 1.5,
fill none, round caps/joins — the same modern line language as the
ported cms design. Every glyph is ONE <path> (subpaths allowed) so the
d attribute survives autoescaping without |safe. Unknown names fall
back to arrow-right instead of raising (page code typos must never
take a build down). #}
{% set _tp_icon_paths={
'arrow-right':'M5 12h14M12 5l7 7-7 7',
'arrow-left':'M19 12H5M12 19l-7-7 7-7',
'chevron-down':'M6 9l6 6 6-6',
'check':'M20 6 9 17 4 12',
'phone':'M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6A19.79 19.79 0 0 1 2.12 4.18 2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.13.96.36 1.9.7 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.91.34 1.85.57 2.81.7A2 2 0 0 1 22 16.92z',
'mail':'M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2Zm18 2-10 7L2 6',
'location':'M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0ZM12 13a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z',
'download':'M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M7 10l5 5 5-5M12 15V3',
'search':'M11 3a8 8 0 1 0 0 16 8 8 0 0 0 0-16ZM21 21l-4.35-4.35',
'quote':'M8 3a2 2 0 0 1 2 2v6a2 2 0 0 1-2 2 1 1 0 0 0-1 1v1a1 1 0 0 0 1 1 2 2 0 0 1 2 2v2a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2v-2a2 2 0 0 1 2-2 1 1 0 0 0 1-1v-1a1 1 0 0 0-1-1 2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4ZM16 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a1 1 0 0 1-1 1 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2h4a2 2 0 0 0 2-2v-2a2 2 0 0 0-2-2 1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1 2 2 0 0 0 2-2V5a2 2 0 0 0-2-2h-4Z'
} %}
{% macro icon(name, size=None, cls='') -%}
{%- set _d=_tp_icon_paths.get(name) or _tp_icon_paths['arrow-right'] -%}
<svg class="sf-tp-icon{% if cls %} {{ cls }}{% endif %}" width="{{ size if size else 'var(--sf-tp-icon-size-md, 20px)' }}" height="{{ size if size else 'var(--sf-tp-icon-size-md, 20px)' }}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="{{ _d }}"/></svg>
{%- endmacro %}
{% macro cover(item, kind='product') %}
{% if item.cover %}<img class="pro-photo" src="{{ safe_image(item.cover) }}" alt="{{ item.title }}" loading="lazy">
{% else %}<div class="pro-art pro-art-{{ kind }}"><span class="pro-art-ring"></span><span class="pro-art-center">{{ (item.title or 'SF')[:2] }}</span><span class="pro-art-label">{{ kind|upper }}</span></div>{% endif %}
{% endmacro %}
{% macro card(item, kind='product', position=0) %}
<a class="pro-card pro-card-{{ kind }}" href="{{ safe_href(item.route) }}" data-category="{{ fields_of(item).get('category','') }}" data-brand="{{ fields_of(item).get('brand','') }}">
<div class="pro-card-cover">{{ cover(item,kind) }}</div>
<div class="pro-card-body"><div class="pro-card-meta"><span>{{ fields_of(item).get('brand') or fields_of(item).get('category') or {'product':'PRODUCT','vehicle':'VEHICLE','post':'NEWS','case':'CASE','brand':'BRAND','service':'SERVICE'}.get(item.type,'CONTENT') }}</span><span>{{ '%02d'|format(position+1) }}</span></div>
<h3>{{ item.title }}</h3><p>{{ (item.summary or '')[:128] }}</p><span class="pro-card-link">View details {{ icon('arrow-right') }}</span></div>
</a>
{% endmacro %}
{% macro grid(items,kind='product') %}<div class="pro-grid pro-grid-{{ kind }}">{% for item in items %}{{ card(item,kind,loop.index0) }}{% else %}<div class="pro-empty">No published content in this section yet.</div>{% endfor %}</div>{% endmacro %}
{% macro section_title(eyebrow,heading,href='') %}<div class="pro-section-head"><div><span class="pro-eyebrow">{{ eyebrow }}</span><h2>{{ heading }}</h2></div>{% if href %}<a class="pro-text-link" href="{{ href }}">Browse all {{ icon('arrow-right') }}</a>{% endif %}</div>{% endmacro %}
{% macro filters() %}<div class="pro-filter-panel"><label><span>Search</span><span class="pro-filter-search-box">{{ icon('search') }}<input type="search" data-pro-filter-search placeholder="Filter by name or content"></span></label><label><span>Brand</span><select data-pro-filter-brand><option value="">All brands</option></select></label><label><span>Category</span><select data-pro-filter-category><option value="">All categories</option></select></label><span class="pro-filter-count" data-pro-filter-count role="status"></span></div>{% endmacro %}
{% macro footer_links(nav) %}<ul>{% for item in nav[:7] %}<li><a href="{{item.route}}">{{item.title}} {{ icon('arrow-right', size='var(--sf-tp-icon-size-sm, 16px)') }}</a></li>{% endfor %}</ul>{% endmacro %}
{% macro body_copy(content,page) %}{% if content %}<div class="pro-rich">{{ content }}</div>{% elif page.summary %}<p class="pro-lead">{{ page.summary }}</p>{% else %}<p class="pro-muted">Complete this page's content in the admin console.</p>{% endif %}{% endmacro %}