Skip to content

v1.3.0

Choose a tag to compare

@github-actions github-actions released this 12 Jul 19:12

What's Changed

Added

  • Flexible color model (#71). colors: palettes accept a free swatches: list
    (named colors, optional per-swatch css_variable) alongside the existing Tailwind-style
    shades: map — projects without a 50–950 scale finally render a sane overview. Both
    shapes normalize through the new ColorPalettes/ColorUtil layer; swatch text color
    (light/dark) is now computed from the hex via WCAG relative luminance instead of the
    hardcoded shade-name list, so dark 100s and light 700s stop guessing wrong. Foundations
    markup adapts to small palettes (capped swatch tiles, wrapping strip, truncating labels).
    All swatch data is html_attr-escaped into the Alpine attributes in foundations.twig
    (autoescape is off in this package), so free-form swatch names carrying apostrophes or
    quotes render safely. OKLCH values are computed from the hex when the yaml omits them and
    are the preferred lightness basis.

  • Contrast / a11y layer (#72). Every swatch on the overview now grades white/black
    text against WCAG AA (4.5:1) — dot badges on the tile, exact ratios in the tooltip and
    hero — and an expandable matrix grades every color × color pair (all palettes + white +
    black) with AAA / AA / AA-large / fail verdicts. Computed server-side from the hex via
    the #71 normalization layer; zero yaml changes needed (new labels.contrast_matrix*
    keys are optional with English defaults).

  • Favicon audit section (#73). Foundations gains a #favicon section: the favicon
    rendered in simulated contexts (browser tab light/dark, iOS home-screen icon, Android/PWA
    maskable icon) plus a server-side audit checklist — file existence, real pixel dimensions
    vs. expectations (png_96 96×96, apple_touch 180×180), parsed ICO contents, manifest
    JSON validity with per-icon existence checks, and the theme_color swatch. Audited by the
    new FaviconAudit class, which runs entirely server-side against static_path; every
    configured path (and every manifest icon src) is containment-checked to stay under
    static_path before any filesystem read. Checklist labels are overridable via optional
    labels.favicon* keys, all with English defaults — no yaml changes are required beyond
    the existing favicon: block.

  • OG image audit section (#74). Foundations gains an #og-image section: the optional
    og_image: yaml key renders as share-card mockups — Facebook/LinkedIn (1.91:1 crop),
    X/Twitter summary_large_image (2:1 crop), and a Slack unfurl — plus a compact server-side
    audit checklist covering existence, real pixel dimensions vs. the ≥ 1200×630 recommendation,
    aspect ratio vs. the 1.91:1 convention, and file size against platform limits (warn > 1 MB,
    error > 8 MB). Audited by the new OgImageAudit class, which shares the containment-hardened
    PathGuard helper with FaviconAudit (#73) rather than duplicating its scheme-URI rejection
    and realpath-under-static_path checks. The section always renders — an empty-state prompt
    covers the unconfigured case, since an OG image is expected on every project. Checklist
    labels are overridable via optional labels.og_* keys, all with English defaults.

Changed

  • Foundations interactivity no longer requires the consumer to ship Alpine (#79).
    templates/foundations.twig drops all Alpine directives; swatch switching, copy-to-clipboard
    and the contrast-matrix toggle now live in a package-shipped, dependency-free
    dist/foundations.[hash].js, injected for foundations renders exactly like the existing
    foundations CSS bundle. The hero server-renders the default swatch, so the no-JS view shows
    real data. Consumer component demos inside the iframe are unaffected — they keep using
    whatever the consumer bundles.

  • |resizer now emits tuple-declared variants for real fixture images too, not only
    placeholder() fakes
    (#70). Every tuple
    becomes an entry reusing the ORIGINAL src (no image pipeline — the browser downloads one
    file) with the tuple's declared width/height/media, so the styleguide <picture> DOM
    mirrors the multi-source markup the CMS resizer emits in production — what DOM-structural
    checks (tailwind-base's picture.contract.js sharpness contract) assert against. With
    real-content fixtures (the picture.md "prefer real content" default) previously passing
    through untouched, the contract silently skipped exactly the fixtures projects prefer.
    Missing tuple axes derive from the fixture's width/height metadata; without metadata the
    provided axis is kept and the other omitted (never invented). .gif fixtures pass through
    whole — parity with timber-kit Resizer::$skip_animated (animation can't be cheaply proven
    from a URL, and flattening an animated preview is the dangerous direction). Verified against
    a real consumer (pm-a): 220 visual baselines unchanged, behavior picture-contract coverage
    grew from 16 to 26 renders with no failures.

  • Malformed metadata YAML now surfaces in GET /styleguide/api/health instead of silently
    dropping the component from the catalogue.
    ComponentParser::parseTwigComment() throws
    ParseException on invalid YAML (previously degraded to false); the existing resilience
    paths in parse()/parseAll() catch it and record a getWarnings() entry, so the walk
    continues and the broken file is named. Variant sibling annotations keep the old
    fall-back-silently behaviour (caught at the discoverVariants() call-site). Real-world
    trigger: an unquoted { padding-top: 0 } in a field description made two sloneek
    components vanish with no trace. Behavioural note for direct parseTwigComment()
    consumers: wrap in try/catch (ParseException) if you relied on the false return.

  • styleguide lint reports metadata-yaml-invalid (Error) for malformed metadata YAML instead
    of crashing on the propagated ParseException — distinct from unindexed (no metadata comment
    at all), because the author DID write metadata and the component is guaranteed missing from the
    catalogue.

Pull Requests

  • #69 — fix(parser): malformed metadata YAML surfaces in health warnings instead of silently dropping the component
  • #75 — feat(resizer): tuple varianty i pro reálné fixture obrázky — DOM parita s produkcí (#70)

Full Changelog: v1.2.0...v1.3.0