diff options
Diffstat (limited to 'docs/superpowers/specs/2026-04-17-social-share-widget-design.md')
| -rw-r--r-- | docs/superpowers/specs/2026-04-17-social-share-widget-design.md | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/docs/superpowers/specs/2026-04-17-social-share-widget-design.md b/docs/superpowers/specs/2026-04-17-social-share-widget-design.md new file mode 100644 index 0000000..0a0ccba --- /dev/null +++ b/docs/superpowers/specs/2026-04-17-social-share-widget-design.md @@ -0,0 +1,199 @@ +# Social Sharing Widget — Design Spec + +**Date:** 2026-04-17 +**Status:** Approved +**Scope:** New partial + integration into sidebar and repository page + +--- + +## Problem + +The site has i18n keys for sharing (`share`, `copyLink`, `twitter`, `facebook`) but no implemented sharing UI. Users have no in-page way to share content on social platforms. + +## Goal + +A reusable, icon-only social sharing widget that: +- Works in the narrow sidebar column (2-col grid) +- Works embedded in full-width pages like the Repository (5-col centered grid) +- Covers 9 share targets: Copy link, Email, Facebook, Twitter/X, Reddit, Pinterest, WhatsApp, Telegram, Signal +- Meets WCAG 2.1 AA accessibility requirements +- Is visually consistent with the existing theme system + +--- + +## Architecture + +### New File +`themes/danix-xyz-hacker/layouts/partials/social-share.html` + +A single partial with a `mode` parameter that controls grid layout: + +```hugo +{{ partial "social-share.html" (dict "page" . "mode" "sidebar") }} +{{ partial "social-share.html" (dict "page" . "mode" "inline") }} +``` + +| Mode | Grid class | Use case | +|---|---|---| +| `sidebar` (default) | `grid-cols-2 gap-2` | Inside `sidebar.html` | +| `inline` | `grid-cols-5 gap-3 justify-items-center` | Full-width pages (repository) | + +### Modified Files +- `layouts/partials/sidebar.html` — add sidebar call after author widget +- `layouts/repository/list.html` — add inline call after `.Content`, before cards +- `themes/.../i18n/en.yaml`, `themes/.../i18n/it.yaml` — add 7 new keys +- `i18n/en.yaml`, `i18n/it.yaml` — keep in sync + +--- + +## Icon Strategy + +Feather Icons (already loaded via CDN) lacks brand icons. Solution: + +| Button | Source | Details | +|---|---|---| +| Copy link | Feather `copy` / `check` | Toggles via Alpine.js | +| Email | Feather `mail` | — | +| Facebook | Inline SVG | Facebook "f" path | +| Twitter/X | Inline SVG | X logo path | +| Reddit | Inline SVG | Reddit alien path | +| Pinterest | Inline SVG | Pinterest "P" path | +| WhatsApp | Inline SVG | WhatsApp logo path | +| Telegram | Inline SVG | Telegram paper-plane path | +| Signal | Inline SVG | Signal logo path | + +All inline SVGs use: `width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"` — matches Feather Icon visual style exactly. `aria-hidden="true" focusable="false"` on every SVG/icon. + +--- + +## Share URL Patterns + +All URLs built server-side in Hugo using `.Permalink` and `.Title | urlquery`. + +| Target | URL | +|---|---| +| Facebook | `https://www.facebook.com/sharer/sharer.php?u={url}` | +| Twitter/X | `https://twitter.com/intent/tweet?url={url}&text={title}` | +| Reddit | `https://www.reddit.com/submit?url={url}&title={title}` | +| Pinterest | `https://pinterest.com/pin/create/button/?url={url}&description={title}` | +| WhatsApp | `https://api.whatsapp.com/send?text={title}%20{url}` | +| Telegram | `https://t.me/share/url?url={url}&text={title}` | +| Signal | `https://signal.me/#p/{url}` | +| Email | `mailto:?subject={title}&body={title}%0A%0A{url}` | + +--- + +## Copy to Clipboard + +Alpine.js local state — no dependency on the toast/modal system: + +```html +<div x-data="{ copied: false }"> + <button + @click="navigator.clipboard.writeText('{{ $page.Permalink }}').then(() => { + copied = true; setTimeout(() => copied = false, 2000) + })" + :aria-label="copied ? '{{ i18n "linkCopied" }}' : '{{ i18n "copyLink" }}'" + class="btn-icon hover:text-accent hover:bg-surface transition-colors" + > + <i x-show="!copied" data-feather="copy" class="w-5 h-5" aria-hidden="true"></i> + <i x-show="copied" data-feather="check" class="w-5 h-5 text-accent2" aria-hidden="true"></i> + </button> +</div> +``` + +Icon swaps from `copy` → `check` (green, `text-accent2`) for 2 seconds, then resets. Feather replaces both `<i>` elements at page load; Alpine.js toggles visibility via `x-show`. + +--- + +## Accessibility (WCAG 2.1 AA) + +- `<nav aria-label="{{ i18n "share" }}">` wraps the button grid as a landmark +- Every button/link has a descriptive `aria-label` sourced from i18n +- Copy button `aria-label` updates dynamically: `"Copy link"` → `"Link copied!"` during the 2s feedback window +- All SVGs: `aria-hidden="true" focusable="false"` — label lives on the parent interactive element +- Minimum 40×40px touch targets via `.btn-icon` (existing enforced class) +- Focus ring: Tailwind `focus-visible:ring-2 focus-visible:ring-accent` — consistent with rest of theme +- External links: `target="_blank" rel="noopener noreferrer"` +- Color contrast: `currentColor` inherits `--text`; hover uses `--accent` (already WCAG-validated in theme audit) + +--- + +## Theme Consistency + +| Element | Class / Value | Matches | +|---|---|---| +| Widget container | `p-4 border border-border/30 rounded mb-6` | Author widget, Related posts widget | +| Widget heading | `text-lg font-semibold text-accent mb-3` | Author, Related posts headings | +| Button base | `.btn-icon` (existing) | Download button in shortcodes | +| Hover state | `hover:text-accent hover:bg-surface transition-colors` | Nav links, card CTAs | +| Copy success color | `text-accent2` | Pinned badge, download actions | +| SVG stroke style | `stroke="currentColor" stroke-width="2"` | All Feather icons | + +--- + +## i18n Keys + +### New keys (add to all 4 i18n files) + +**English** (`themes/.../i18n/en.yaml` and `i18n/en.yaml`): +```yaml +# Social Sharing (new) +reddit: "Reddit" +pinterest: "Pinterest" +whatsapp: "WhatsApp" +telegram: "Telegram" +signal: "Signal" +shareViaEmail: "Share via email" +linkCopied: "Link copied!" +``` + +**Italian** (`themes/.../i18n/it.yaml` and `i18n/it.yaml`): +```yaml +# Condivisione Social (new) +reddit: "Reddit" +pinterest: "Pinterest" +whatsapp: "WhatsApp" +telegram: "Telegram" +signal: "Signal" +shareViaEmail: "Condividi via email" +linkCopied: "Link copiato!" +``` + +### Existing keys reused +`share`, `copyLink`, `twitter`, `facebook`, `email` (already in both languages) + +--- + +## Integration + +### sidebar.html +Insert between author widget and related posts widget: +```hugo +{{ partial "social-share.html" (dict "page" . "mode" "sidebar") }} +``` +Visible on all content types (articles and pages) — no type gate. + +### repository/list.html +Insert after `{{ .Content }}` prose block, before the `<section>` cards grid: +```hugo +<div class="mb-12"> + {{ partial "social-share.html" (dict "page" . "mode" "inline") }} +</div> +``` + +--- + +## Verification Checklist + +1. `hugo server -D` → article sidebar shows 9 icon buttons in 2-col grid +2. Page (e.g. `/is/`) → sidebar also shows widget (no type restriction) +3. `/repository` → inline widget between prose and cards, 5-col centered +4. Copy button: icon swaps to green checkmark, resets after 2s +5. Twitter/X link → `twitter.com/intent/tweet` with correct URL + title in new tab +6. Email link → mail client opens with pre-filled subject and body +7. Dark/light theme toggle → icons and hover states render correctly +8. Italian `/it/` page → heading "Condividi", aria-labels in Italian +9. Keyboard navigation → all 9 buttons focusable, visible focus ring +10. Screen reader test → aria-labels announced correctly, SVGs silent +11. No console errors (feather.replace() handles x-show hidden icons) |
