diff --git a/docs/SubscribeCTA-icon-buttons-tooltip.md b/docs/SubscribeCTA-icon-buttons-tooltip.md new file mode 100644 index 0000000..70075aa --- /dev/null +++ b/docs/SubscribeCTA-icon-buttons-tooltip.md @@ -0,0 +1,113 @@ +# SubscribeCTA — Icon-Only Action Buttons with Tooltip Wiring + +**Campaign:** GrantFox FWC26 +**Issue scope:** `src/pages/SubscribeCTA.tsx`, `src/components/Tooltip.tsx` + +--- + +## Overview + +The `SubscribeCTA` sticky bar now includes two icon-only action buttons — **Share** and **Bookmark** — positioned between the price group and the Subscribe button. Both buttons are wired to the shared `Tooltip` primitive with configurable hover-delay and long-press behaviour so users always have an accessible label, regardless of input modality. + +--- + +## New props on `SubscribeCTA` + +| Prop | Type | Default | Description | +|---|---|---|---| +| `onShare` | `() => void` | – | Called when the Share button is clicked. When omitted, the current page URL is copied to the clipboard via `navigator.clipboard.writeText`. | +| `onBookmark` | `(isBookmarked: boolean) => void` | – | Called after each toggle with the **new** bookmarked state. | +| `isBookmarked` | `boolean` | `false` | Initialises the bookmark button in the saved state. | +| `tooltipHoverDelayMs` | `number` | `300` | Milliseconds to wait after `mouseenter` before the tooltip opens. Passed directly to the `Tooltip` `hoverDelayMs` prop for both buttons. | +| `tooltipLongPressMs` | `number` | `500` | Touch-contact duration before the tooltip opens on mobile. Passed to the `Tooltip` `longPressMs` prop for both buttons. | + +All other existing props (`apiName`, `pricePerRequest`, `onSubscribe`, `observeElementSelector`) are unchanged. + +--- + +## Behaviour + +### Share button +- **Default action:** Calls `navigator.clipboard.writeText(window.location.href)` — copies the current URL silently. Clipboard errors are swallowed so the UI never enters an error state. +- **Custom action:** Pass `onShare` to override (e.g. open a native share sheet, fire an analytics event, or open a modal). +- **Tooltip label:** `"Share {apiName}"` — shown after `tooltipHoverDelayMs` ms on hover, immediately on keyboard focus, and after `tooltipLongPressMs` ms on touch. + +### Bookmark button +- **Toggle state:** Internal `bookmarked` state is initialised from the `isBookmarked` prop. Each click flips the state and fires `onBookmark(newState)`. +- **Visual feedback:** When bookmarked, the SVG bookmark is **filled** and the button receives the `.subscribe-cta-bar__icon-btn--active` CSS class (accent-coloured background/border). +- **Tooltip label:** Dynamically reflects toggle state: + - Unsaved: `"Save {apiName}"` + - Saved: `"Remove {apiName} from saved"` +- **`aria-pressed`:** Always present; `"true"` when bookmarked, `"false"` when not. + +--- + +## Accessibility (WCAG 2.1 AA) + +| Criterion | How it is met | +|---|---| +| **1.1.1 Non-text content** | Every button has an explicit `aria-label`. SVG icons are `aria-hidden="true"`. | +| **1.4.1 Use of color** | Toggle state is communicated by `aria-pressed` + icon fill change, not colour alone. | +| **2.1.1 Keyboard** | Both buttons are standard ` + + + {/* Bookmark / save button */} + + + + +