diff --git a/.github/copilot/integrate-social-share-button.prompt.md b/.github/copilot/integrate-social-share-button.prompt.md
index 6ba9240..e7b4463 100644
--- a/.github/copilot/integrate-social-share-button.prompt.md
+++ b/.github/copilot/integrate-social-share-button.prompt.md
@@ -2,9 +2,9 @@
agent: agent
description: >
Integrate SocialShareButton into any web project. Covers CDN (recommended),
- npm (advanced), and React Wrapper Component (optional). Framework-specific
+ npm (advanced), and React/Preact/Qwik Wrapper Components (optional). Framework-specific
steps for CRA, Next.js App Router, Next.js Pages Router, Vite/Vue/Angular,
- and Vanilla HTML. Use this skill whenever a developer asks how to add the
+ Preact, Qwik, and Vanilla HTML. Use this skill whenever a developer asks how to add the
share button to their project.
---
@@ -25,11 +25,11 @@ You are helping a developer integrate the **SocialShareButton** library
The README defines **3 installation methods**. Ask (or infer) which the developer wants:
-| Method | When to use |
-| ------------------------------------------------- | ------------------------------------------------------------------------- |
-| **Method 1 — CDN (Recommended)** | Most projects. No build step needed. Load via `
+
+
+
+```
+
+**Step 2:** Open your root or layout component (typically `src/components/Header.jsx` or your root `App.jsx`). Add a container element and initialize inside the `useEffect` hook:
+
+```jsx
+import { useEffect, useRef } from "preact/hooks";
+
+// ⬇️ Replace 'Header' with the name of the component where you want the
+// share button to appear — e.g. Navbar, MainLayout, App, etc.
+export default function Header() {
+ const shareButtonRef = useRef(null);
+ const containerRef = useRef(null);
+ const initRef = useRef(false);
+
+ useEffect(() => {
+ if (initRef.current || !window.SocialShareButton || !containerRef.current) return;
+
+ shareButtonRef.current = new window.SocialShareButton({
+ container: "#share-button",
+ });
+ initRef.current = true;
+
+ return () => {
+ if (shareButtonRef.current?.destroy) {
+ shareButtonRef.current.destroy();
+ }
+ initRef.current = false;
+ };
+ }, []);
+
+ return (
+
+
+
+ );
+}
+```
+
+---
+
+### CDN — Qwik
+
+**Step 1:** Add CDN to your root or layout page (e.g. `src/root.tsx` or layout index):
+
+```html
+
+
+
+
+```
+
+**Step 2:** Create a container element and initialize the button in `useVisibleTask$`:
+
+```tsx
+import { component$, useVisibleTask$, useSignal } from "@builder.io/qwik";
+
+export default component$(() => {
+ const containerRef = useSignal();
+
+ useVisibleTask$(({ cleanup }) => {
+ if (typeof window !== "undefined" && (window as any).SocialShareButton && containerRef.value) {
+ const shareButton = new (window as any).SocialShareButton({
+ container: containerRef.value,
+ });
+
+ cleanup(() => {
+ if (shareButton && typeof shareButton.destroy === "function") {
+ shareButton.destroy();
+ }
+ });
+ }
+ });
+
+ return ;
+});
+```
+
+---
+
## Method 2 — npm (Advanced)
Use when the project has a bundler (Webpack, Vite, etc.) and the developer prefers `import` syntax. Works in any framework.
@@ -402,48 +501,87 @@ new SocialShareButton({ container: "#share-button" });
---
-## Method 3 — React Wrapper Component (Optional)
+## Method 3 — React / Preact / Qwik Wrapper Components (Optional)
-Only use this when the developer **explicitly** wants a reusable JSX component.
+Only use this when the developer **explicitly** wants a reusable component wrapper.
-Tell them to copy `src/social-share-button-react.jsx` from the library into their project — **do not create a new file from scratch**.
+### React Wrapper Component
+
+Tell them to copy `src/social-share-button-react.jsx` from the library into their project:
```jsx
-import { SocialShareButton } from "./components/SocialShareButton";
+import SocialShareButton from "./components/SocialShareButton";
function App() {
- return ;
+ return (
+
+ );
+}
+```
+
+### Preact Wrapper Component
+
+Tell them to copy `src/social-share-button-preact.jsx` from the library into their project:
+
+```jsx
+import SocialShareButton from "./components/SocialShareButton";
+
+function App() {
+ return (
+
+ );
}
```
+### Qwik Wrapper Component
+
+Tell them to copy `src/social-share-button-qwik.tsx` from the library into their project:
+
+```tsx
+import { component$ } from "@builder.io/qwik";
+import { SocialShareButton } from "./components/SocialShareButton";
+
+export default component$(() => {
+ return ;
+});
+```
+
---
## All constructor options
-| Option | Type | Default | Description |
-| ------------------ | -------------- | ---------------------- | ---------------------------------------------------------- |
-| `container` | string/Element | — | **Required.** CSS selector or DOM element |
-| `url` | string | `window.location.href` | URL to share |
-| `title` | string | `document.title` | Share title/headline |
-| `description` | string | `''` | Additional description text |
-| `hashtags` | array | `[]` | e.g. `['js', 'webdev']` |
-| `via` | string | `''` | Twitter handle (without @) |
-| `platforms` | array | All platforms | `whatsapp facebook twitter linkedin telegram reddit email` |
-| `buttonText` | string | `'Share'` | Button label text |
-| `buttonStyle` | string | `'default'` | `default` `primary` `compact` `icon-only` |
-| `buttonColor` | string | `''` | Custom button background color |
-| `buttonHoverColor` | string | `''` | Custom button hover color |
-| `customClass` | string | `''` | Additional CSS class for button |
-| `theme` | string | `'dark'` | `dark` or `light` |
-| `modalPosition` | string | `'center'` | Modal position on screen |
-| `showButton` | boolean | `true` | Show/hide the share button |
-| `onShare` | function | `null` | `(platform, url) => void` |
-| `onCopy` | function | `null` | `(url) => void` |
-| `analytics` | boolean | `true` | Set `false` to disable all event emission |
-| `onAnalytics` | function | `null` | `(payload) => void` — direct analytics hook |
-| `analyticsPlugins` | array | `[]` | Adapter instances from `social-share-analytics.js` |
-| `componentId` | string | `null` | Label this instance for analytics tracking |
-| `debug` | boolean | `false` | Log analytics events to console |
+| Option | Type | Default | Description |
+| ------------------ | -------------- | ----------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
+| `container` | string/Element | — | **Required.** CSS selector or DOM element |
+| `url` | string | `window.location.href` | URL to share |
+| `title` | string | `document.title` | Share title/headline |
+| `description` | string | `''` | Additional description text |
+| `hashtags` | array | `[]` | e.g. `['js', 'webdev']` |
+| `via` | string | `''` | Twitter handle (without @) |
+| `platforms` | array | `whatsapp, facebook, twitter, linkedin, telegram, reddit, pinterest, discord` | Platforms to show: `whatsapp facebook twitter linkedin telegram reddit email pinterest discord` |
+| `buttonText` | string | `'Share'` | Button label text |
+| `buttonStyle` | string | `'default'` | `default` `primary` `compact` `icon-only` |
+| `buttonColor` | string | `''` | Custom button background color |
+| `buttonHoverColor` | string | `''` | Custom button hover color |
+| `customClass` | string | `''` | Additional CSS class for button |
+| `theme` | string | `'dark'` | `dark` or `light` |
+| `modalPosition` | string | `'center'` | Modal position on screen |
+| `showButton` | boolean | `true` | Show/hide the share button |
+| `onShare` | function | `null` | `(platform, url) => void` |
+| `onCopy` | function | `null` | `(url) => void` |
+| `analytics` | boolean | `true` | Set `false` to disable all event emission |
+| `onAnalytics` | function | `null` | `(payload) => void` — direct analytics hook |
+| `analyticsPlugins` | array | `[]` | Adapter instances from `social-share-analytics.js` |
+| `componentId` | string | `null` | Label this instance for analytics tracking |
+| `debug` | boolean | `false` | Log analytics events to console |
---
@@ -508,8 +646,8 @@ useEffect(() => {
## Output format
-- Ask the developer their **method** (CDN / npm / React Wrapper) and their **framework** (only needed for CDN).
+- Ask the developer their **method** (CDN / npm / Wrapper Component) and their **framework** (needed to select the correct CDN integration steps or wrapper component).
- Show only the snippet(s) relevant to their choices.
-- Always modify **existing** files — never suggest creating new component files.
+- Always modify **existing** files — never suggest creating new component files (unless they explicitly ask for a Wrapper Component, in which case instruct them to copy the relevant file from `src/` to their components folder).
- When modifying an existing file, mark additions with `// ADD THIS`.
- Do not add abstractions, wrappers, or extra files beyond what the README shows.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index ee20f27..04b5fea 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -146,6 +146,7 @@ Push your branch:
### Code Quality Tools
We use ESLint for linting and Prettier for formatting. Please run these before submitting a PR:
+
- `npm run lint` — Check for code quality and style issues.
- `npm run format` — Automatically format your code to project standards.
- `npm run format:check` — Verify that files are correctly formatted.
diff --git a/README.md b/README.md
index 5005cb1..623ae5d 100644
--- a/README.md
+++ b/README.md
@@ -66,7 +66,6 @@ Lightweight social sharing component for web applications. Zero dependencies, fr
[](https://www.npmjs.com/package/social-share-button-aossie)
[](LICENSE)
-
---
## Features
@@ -556,7 +555,8 @@ new SocialShareButton({
- **Email:** Subject = `title`, Body = `description` + link
- **Pinterest:** `title` + `description` + `hashtags` + link
- **Discord:** `title` + `description` + `hashtags` + link
--
+-
+
### Customize Button Color & Appearance
**Option 1: Use Pre-built Styles** (Easiest)
diff --git a/docs/Roadmap.md b/docs/Roadmap.md
index 98ae879..bee023d 100644
--- a/docs/Roadmap.md
+++ b/docs/Roadmap.md
@@ -1,7 +1,7 @@
# 🚀 SocialShareButton — Project Roadmap
> **Version:** 2.0 Draft
-> **Status:** Living Document
+> **Status:** Living Document
---
@@ -27,23 +27,23 @@ This section is the ground truth before any planning.
### ✅ What Already Exists
-| Feature | Status | Notes |
-|---|---|---|
-| CDN distribution (jsDelivr) | ✅ | `v1.0.3` |
-| npm package | ✅ | Published as `social-share-button-aossie` (unscoped) |
-| 7 share platforms | ✅ | WhatsApp, Facebook, X, LinkedIn, Telegram, Reddit, Email |
-| `onShare` callback | ✅ | `(platform, url) => {}` |
-| `onCopy` callback | ✅ | `(url) => {}` |
-| `theme: 'dark' \| 'light'` | ✅ | Basic two-mode theming |
-| `buttonColor` / `buttonHoverColor` | ✅ | Programmatic color overrides |
-| `customClass` | ✅ | Escape hatch for custom CSS |
-| `modalPosition` | ✅ | Modal placement config |
-| `updateOptions()` | ✅ | SPA dynamic URL updates |
-| React wrapper | ✅ | Exists as `src/social-share-button-react.jsx` (copy-paste only) |
-| TypeScript types | ❌ | None shipped |
-| Scoped npm package | ❌ | Not yet (`@social-share/core` etc.) |
-| Framework packages | ❌ | No installable Vue / Qwik / Solid packages |
-| Proper CSS build artifact | ❌ | CSS imported from `src/` path — breaks in most bundlers |
+| Feature | Status | Notes |
+| ---------------------------------- | ------ | --------------------------------------------------------------- |
+| CDN distribution (jsDelivr) | ✅ | `v1.0.3` |
+| npm package | ✅ | Published as `social-share-button-aossie` (unscoped) |
+| 7 share platforms | ✅ | WhatsApp, Facebook, X, LinkedIn, Telegram, Reddit, Email |
+| `onShare` callback | ✅ | `(platform, url) => {}` |
+| `onCopy` callback | ✅ | `(url) => {}` |
+| `theme: 'dark' \| 'light'` | ✅ | Basic two-mode theming |
+| `buttonColor` / `buttonHoverColor` | ✅ | Programmatic color overrides |
+| `customClass` | ✅ | Escape hatch for custom CSS |
+| `modalPosition` | ✅ | Modal placement config |
+| `updateOptions()` | ✅ | SPA dynamic URL updates |
+| React wrapper | ✅ | Exists as `src/social-share-button-react.jsx` (copy-paste only) |
+| TypeScript types | ❌ | None shipped |
+| Scoped npm package | ❌ | Not yet (`@social-share/core` etc.) |
+| Framework packages | ❌ | No installable Vue / Qwik / Solid packages |
+| Proper CSS build artifact | ❌ | CSS imported from `src/` path — breaks in most bundlers |
### ⚠️ Known Issues to Fix Before Any New Features
@@ -108,13 +108,13 @@ social-share-button/ ← Turborepo monorepo root
### Layer Responsibilities
-| Layer | Package | Responsibility |
-|---|---|---|
-| Core Engine | `@social-share/core` | Platform logic, URL building, config validation |
-| Analytics | `@social-share/analytics` | Event emission, consent, adapter routing |
-| Theme | `@social-share/theme` | CSS tokens, presets, Theme Designer, export |
-| Framework Wrappers | `@social-share/react` etc. | Framework-specific components using core |
-| CDN Build | `apps/cdn-build` | Bundles core + wrappers into single distributable |
+| Layer | Package | Responsibility |
+| ------------------ | -------------------------- | ------------------------------------------------- |
+| Core Engine | `@social-share/core` | Platform logic, URL building, config validation |
+| Analytics | `@social-share/analytics` | Event emission, consent, adapter routing |
+| Theme | `@social-share/theme` | CSS tokens, presets, Theme Designer, export |
+| Framework Wrappers | `@social-share/react` etc. | Framework-specific components using core |
+| CDN Build | `apps/cdn-build` | Bundles core + wrappers into single distributable |
---
@@ -122,7 +122,7 @@ social-share-button/ ← Turborepo monorepo root
---
-### ✅ Phase 0 — Stabilization *(Now — before any refactoring)*
+### ✅ Phase 0 — Stabilization _(Now — before any refactoring)_
**Goal:** Fix the broken npm package experience and document the full API surface. No new features.
@@ -181,6 +181,7 @@ export function executeShare(platform: Platform, config: ShareConfig): void { ..
**Goal:** Replace the copy-paste React wrapper with installable framework packages. React first since it already exists as `.jsx`.
**Priority order:**
+
1. `@social-share/react` — replaces `src/social-share-button-react.jsx`
2. `@social-share/vue` — Composition API component
3. `@social-share/qwik` — Resumable, SSR-safe (open issue)
@@ -191,26 +192,27 @@ export function executeShare(platform: Platform, config: ShareConfig): void { ..
```typescript
interface SocialShareButtonProps {
- url?: string; // default: window.location.href
- title?: string; // default: document.title
+ url?: string; // default: window.location.href
+ title?: string; // default: document.title
description?: string;
hashtags?: string[];
via?: string;
platforms?: Platform[];
buttonText?: string;
- buttonStyle?: 'default' | 'primary' | 'compact' | 'icon-only';
- buttonColor?: string; // existing API
- buttonHoverColor?: string; // existing API
- customClass?: string; // existing API
- theme?: 'dark' | 'light' | ThemeTokens; // string shorthand still works
- analytics?: AnalyticsConfig; // Phase 3
+ buttonStyle?: "default" | "primary" | "compact" | "icon-only";
+ buttonColor?: string; // existing API
+ buttonHoverColor?: string; // existing API
+ customClass?: string; // existing API
+ theme?: "dark" | "light" | ThemeTokens; // string shorthand still works
+ analytics?: AnalyticsConfig; // Phase 3
componentId?: string;
- onShare?: (platform: Platform, url: string) => void; // same signature as today
- onCopy?: (url: string) => void; // same signature as today
+ onShare?: (platform: Platform, url: string) => void; // same signature as today
+ onCopy?: (url: string) => void; // same signature as today
}
```
**Migration for existing React wrapper users:**
+
```tsx
// Before (copy-paste)
import { SocialShareButton } from "./components/SocialShareButton";
@@ -226,7 +228,7 @@ import { SocialShareButton } from "@social-share/react";
---
-### 🔬 Phase 3 — Analytics Module
+### 🔬 Phase 3 — Analytics Module
**Goal:** Ship `@social-share/analytics` — a privacy-first, pluggable analytics layer that uses the existing `onShare` / `onCopy` callbacks as its internal trigger mechanism.
@@ -234,25 +236,25 @@ import { SocialShareButton } from "@social-share/react";
```typescript
// Path 1: DOM Events — zero config, works with any analytics tool
-document.addEventListener('ssb:share', (e) => console.log(e.detail));
-document.addEventListener('ssb:copy', (e) => console.log(e.detail));
-document.addEventListener('ssb:modal_open', (e) => console.log(e.detail));
-document.addEventListener('ssb:modal_close', (e) => console.log(e.detail));
+document.addEventListener("ssb:share", (e) => console.log(e.detail));
+document.addEventListener("ssb:copy", (e) => console.log(e.detail));
+document.addEventListener("ssb:modal_open", (e) => console.log(e.detail));
+document.addEventListener("ssb:modal_close", (e) => console.log(e.detail));
// Path 2: Single callback hook — simplest npm integration
new SocialShareButton({
analytics: {
- onEvent: (event: SSBEvent) => myAnalytics.track(event.name, event.data)
- }
+ onEvent: (event: SSBEvent) => myAnalytics.track(event.name, event.data),
+ },
});
// Path 3: Named adapter — built-in wiring for popular tools
-import { GA4Adapter } from '@social-share/analytics/adapters/ga4';
+import { GA4Adapter } from "@social-share/analytics/adapters/ga4";
new SocialShareButton({
analytics: {
- adapter: new GA4Adapter({ measurementId: 'G-XXXXXXXX' })
- }
+ adapter: new GA4Adapter({ measurementId: "G-XXXXXXXX" }),
+ },
});
```
@@ -260,31 +262,31 @@ new SocialShareButton({
```typescript
interface SSBEvent {
- name: 'ssb:share' | 'ssb:copy' | 'ssb:modal_open' | 'ssb:modal_close';
+ name: "ssb:share" | "ssb:copy" | "ssb:modal_open" | "ssb:modal_close";
platform?: Platform;
- componentId?: string; // developer-defined identifier
+ componentId?: string; // developer-defined identifier
url: string;
timestamp: number;
- sessionId: string; // anonymous, ephemeral, never persisted
+ sessionId: string; // anonymous, ephemeral, never persisted
}
```
#### Built-in Adapters
-| Adapter | Notes |
-|---|---|
-| `GA4Adapter` | `gtag('event', ...)` — no PII sent |
-| `MixpanelAdapter` | `mixpanel.track()` — requires Mixpanel loaded |
-| `SegmentAdapter` | `analytics.track()` — wraps Segment's standard API |
-| `PlausibleAdapter` | `plausible()` custom event — cookieless by default |
-| `PostHogAdapter` | `posthog.capture()` — EU cloud + self-hosted compatible |
-| `CustomAdapter` | Extend `BaseAdapter`, implement `track(event: SSBEvent): void` |
+| Adapter | Notes |
+| ------------------ | -------------------------------------------------------------- |
+| `GA4Adapter` | `gtag('event', ...)` — no PII sent |
+| `MixpanelAdapter` | `mixpanel.track()` — requires Mixpanel loaded |
+| `SegmentAdapter` | `analytics.track()` — wraps Segment's standard API |
+| `PlausibleAdapter` | `plausible()` custom event — cookieless by default |
+| `PostHogAdapter` | `posthog.capture()` — EU cloud + self-hosted compatible |
+| `CustomAdapter` | Extend `BaseAdapter`, implement `track(event: SSBEvent): void` |
#### Privacy Controls
```typescript
-SocialShareButton.analytics.enable(); // call after consent granted
-SocialShareButton.analytics.disable(); // opt-out / consent withdrawn
+SocialShareButton.analytics.enable(); // call after consent granted
+SocialShareButton.analytics.disable(); // opt-out / consent withdrawn
SocialShareButton.analytics.isEnabled(); // boolean
SocialShareButton.analytics.debug(true); // log to console, don't send
```
@@ -298,7 +300,7 @@ SocialShareButton.analytics.debug(true); // log to console, don't send
---
-### 🎨 Phase 4 — Theme System + Theme Designer
+### 🎨 Phase 4 — Theme System + Theme Designer
**Goal:** Extend existing `dark` / `light` theming into a full CSS-variable-based system with an interactive Theme Designer. All existing `theme`, `buttonColor`, `buttonHoverColor`, `customClass` options remain fully supported.
@@ -311,7 +313,7 @@ SocialShareButton.analytics.debug(true); // log to console, don't send
--ssb-btn-bg: #1da1f2;
--ssb-btn-bg-hover: #0d8fd9;
--ssb-btn-radius: 6px;
- --ssb-btn-shadow: 0 2px 8px rgba(0,0,0,0.12);
+ --ssb-btn-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
/* Per-platform icon colors */
--ssb-icon-twitter: #1da1f2;
@@ -327,7 +329,7 @@ SocialShareButton.analytics.debug(true); // log to console, don't send
--ssb-modal-animation-speed: 200ms;
--ssb-font-family: system-ui, sans-serif;
- --ssb-shape: rounded; /* rounded | pill | square */
+ --ssb-shape: rounded; /* rounded | pill | square */
}
```
@@ -336,6 +338,7 @@ SocialShareButton.analytics.debug(true); // log to console, don't send
Hosted at `apps/playground`.
**Controls:**
+
- Colors & Gradients — solid + gradient builder per button
- Shapes — rounded / pill / square
- Border — width, color, style
@@ -344,6 +347,7 @@ Hosted at `apps/playground`.
- Font family, shadow intensity, hover effect selector
**Export formats:**
+
- CSS variables block
- `.json` theme file (SDK-importable)
- Shareable URL (theme as URL params)
@@ -369,38 +373,41 @@ import myTheme from './my-theme.json'; // from Theme Designer
**Goal:** CDN and SDK reach full feature parity. Complete all planned server-side and CMS integrations.
**CDN feature parity:**
+
- Bundle includes analytics + theming (opt-in at build config level)
- Config via `data-ssb-*` HTML attributes or `window.SocialShareButtonConfig`
- SRI hash generation in CI, hosted on jsDelivr + unpkg
**Platform integrations:**
-| Integration | Delivery | Issue Status |
-|---|---|---|
-| Remix | `@social-share/react` + SSR guide | 🟡 Open |
-| Solid.js | `@social-share/solid` | 🟡 Open |
-| Rails | Gem wrapper + CDN tag helper | 🟡 Open |
-| Django | Template tag + CDN | 🟡 Open |
-| Laravel | Blade component + CDN | 🟡 Open |
-| WordPress | Plugin (CDN-backed) | 🟡 Open |
-| Hugo | Shortcode + CDN | 🟡 Open |
-| Jekyll | Include template + CDN | 🟡 Open |
-| Web Components (Lit) | `@social-share/wc` | 🟡 Open |
-| Alpine.js | `x-data` binding guide + CDN | 🟡 Open |
+| Integration | Delivery | Issue Status |
+| -------------------- | --------------------------------- | ------------ |
+| Remix | `@social-share/react` + SSR guide | 🟡 Open |
+| Solid.js | `@social-share/solid` | 🟡 Open |
+| Rails | Gem wrapper + CDN tag helper | 🟡 Open |
+| Django | Template tag + CDN | 🟡 Open |
+| Laravel | Blade component + CDN | 🟡 Open |
+| WordPress | Plugin (CDN-backed) | 🟡 Open |
+| Hugo | Shortcode + CDN | 🟡 Open |
+| Jekyll | Include template + CDN | 🟡 Open |
+| Web Components (Lit) | `@social-share/wc` | 🟡 Open |
+| Alpine.js | `x-data` binding guide + CDN | 🟡 Open |
CI smoke test per integration: spin up minimal app, assert button renders and emits share event.
---
-### ⚡ Phase 6 — Advanced Features & Ecosystem
+### ⚡ Phase 6 — Advanced Features & Ecosystem
**Accessibility:**
+
- Full ARIA — `role="button"`, `aria-label`, `aria-expanded` on modal
- Keyboard navigation — Tab, Enter, Escape
- `prefers-reduced-motion` support (maps to `--ssb-modal-animation-speed: 0ms`)
- WCAG 2.1 AA tested with axe-core in CI
**Performance:**
+
- CDN bundle: target < 8KB gzipped
- npm packages: tree-shakeable — twitter-only import ~1KB
- CSS: single `@layer` block, no `@import` chains
@@ -409,22 +416,24 @@ CI smoke test per integration: spin up minimal app, assert button renders and em
```typescript
SocialShareButton.registerPlatform({
- id: 'bluesky',
- label: 'Bluesky',
+ id: "bluesky",
+ label: "Bluesky",
icon: BlueskyIcon,
buildURL: (config) => `https://bsky.app/intent/compose?text=${config.title} ${config.url}`,
});
```
**Native Web Share API:**
+
```typescript
new SocialShareButton({
- preferNativeShare: 'mobile-only', // true | false | 'mobile-only'
+ preferNativeShare: "mobile-only", // true | false | 'mobile-only'
});
// Falls back to custom modal when navigator.share() is unavailable
```
**Monorepo tooling maturity:**
+
- Changesets-based automated releases via GitHub Actions
- Per-package changelogs
- Canary / beta release channel
@@ -434,20 +443,20 @@ new SocialShareButton({
## 🤝 Contribution Opportunities
-| Area | Skills Needed | Phase |
-|---|---|---|
-| Fix CSS export path + `exports` field | npm packaging | 0 |
-| Write `.d.ts` TypeScript declarations | TypeScript | 0 |
-| Core engine extraction | TypeScript, DOM APIs | 1 |
-| Turborepo + pnpm workspace setup | Monorepo tooling | 1 |
-| `@social-share/react` (from existing jsx) | React | 2 |
-| `@social-share/vue` / `solid` / `qwik` | Vue / Solid / Qwik | 2 |
-| Analytics adapters | GA4 / PostHog / Segment APIs | 3 |
-| Theme Designer UI | React, CSS variables | 4 |
-| CMS / server-side integrations | Rails / Django / Laravel / WP | 5 |
-| Accessibility audit | WCAG, axe-core | 6 |
-| Docs site | Next.js, MDX | Ongoing |
-| CI/CD pipelines | GitHub Actions, Changesets | Ongoing |
+| Area | Skills Needed | Phase |
+| ----------------------------------------- | ----------------------------- | ------- |
+| Fix CSS export path + `exports` field | npm packaging | 0 |
+| Write `.d.ts` TypeScript declarations | TypeScript | 0 |
+| Core engine extraction | TypeScript, DOM APIs | 1 |
+| Turborepo + pnpm workspace setup | Monorepo tooling | 1 |
+| `@social-share/react` (from existing jsx) | React | 2 |
+| `@social-share/vue` / `solid` / `qwik` | Vue / Solid / Qwik | 2 |
+| Analytics adapters | GA4 / PostHog / Segment APIs | 3 |
+| Theme Designer UI | React, CSS variables | 4 |
+| CMS / server-side integrations | Rails / Django / Laravel / WP | 5 |
+| Accessibility audit | WCAG, axe-core | 6 |
+| Docs site | Next.js, MDX | Ongoing |
+| CI/CD pipelines | GitHub Actions, Changesets | Ongoing |
> 💡 Phase 0 tasks are labeled `good-first-issue` and require no monorepo knowledge — ideal starting point for new contributors.
@@ -465,16 +474,16 @@ new SocialShareButton({
## 📊 Distribution Strategy
-| Path | Audience | Package | Status |
-|---|---|---|---|
-| CDN (`