Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 107 additions & 0 deletions .changeset/phase-2-presentation-layer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
---
"@prosdevlab/experience-sdk": minor
"@prosdevlab/experience-sdk-plugins": minor
---

**Phase 2: Presentation Layer - Modal & Inline Plugins**

This release introduces two powerful new rendering plugins with built-in form support, completing the presentation layer for the Experience SDK.

## 🎉 New Features

### Modal Plugin
- **Rich Content Modals**: Display announcements, promotions, and interactive content
- **Built-in Forms**: Email capture, surveys, and feedback forms with validation
- **Size Variants**: Small, medium, large, and extra-large sizes
- **Hero Images**: Full-width images for visual impact
- **Responsive Design**: Mobile fullscreen mode for optimal UX
- **Keyboard Navigation**: Focus trap, Escape key, Tab navigation
- **Animations**: Smooth fade-in/fade-out transitions
- **Form States**: Success, error, and loading states
- **API Methods**: `show()`, `remove()`, `isShowing()`, `showFormState()`, `resetForm()`, `getFormData()`

### Inline Plugin
- **DOM Insertion**: Embed content anywhere in your page
- **5 Insertion Methods**: `replace`, `append`, `prepend`, `before`, `after`
- **CSS Selector Targeting**: Use any valid selector to target elements
- **Dismissal with Persistence**: Users can dismiss and it persists in localStorage
- **No Layout Disruption**: Seamlessly integrates with existing page structure
- **API Methods**: `show()`, `remove()`, `isShowing()`

### Forms (Built into Modal)
- **Field Types**: text, email, url, tel, number, textarea, select, checkbox, radio
- **Validation**: Required, email, URL, pattern, custom validation, min/max length
- **Real-time Feedback**: Validates on blur, shows errors inline
- **Submission Handling**: Emits `experiences:modal:form:submit` event
- **Success/Error States**: Built-in UI for post-submission states
- **Pure Functions**: Validation and rendering logic easily extractable

## 🎨 Theming & Customization

### CSS Variables
All plugins now support CSS variable theming:
- **Modal**: `--xp-modal-*` variables for backdrop, dialog, title, content, buttons
- **Forms**: `--xp-form-*` variables for inputs, labels, errors, submit button
- **Banner**: `--xp-banner-*` variables (refactored from inline styles)
- **Inline**: `--xp-inline-*` variables for custom styling

See the [Theming Guide](https://prosdevlab.github.io/experience-sdk/guides/theming) for full reference.

## 🔧 API Improvements

### Runtime
- **Auto-registration**: Modal and inline plugins are automatically registered
- **Plugin API Access**: Expose plugin APIs via singleton (`experiences.modal.show()`)
- **Trigger Event Handling**: Explicit listeners for each trigger type (exit intent, scroll depth, time delay)

### Display Conditions
Seamless integration with existing display condition plugins:
- **Exit Intent + Modal**: Capture emails before users leave
- **Scroll Depth + Inline**: Progressive feature discovery
- **Time Delay + Modal**: Time-sensitive promotions
- **Page Visits + Banner**: Returning user messages

## 📦 Bundle Size
- **Core SDK**: 13.4 KB gzipped (under 15 KB target ✅)
- **All Plugins**: ~26 KB gzipped total (smaller than competitors like Pathfora at ~47 KB)
- **Excellent Compression**: CSS-in-JS with CSS variables maintains small footprint

## 🧪 Testing
- **432 tests passing** (unit, integration, browser tests)
- **Modal Plugin**: 56 tests for core functionality, forms, keyboard nav, accessibility
- **Inline Plugin**: 24 tests for DOM insertion, dismissal, persistence
- **Form Validation**: 35 tests for all field types and edge cases
- **Integration Tests**: 10 tests for plugin interactions
- **Exit Intent**: 21 tests with timing and sensitivity validation

## 📚 Documentation
- **Modal Plugin Reference**: Complete API docs with examples
- **Inline Plugin Reference**: Full insertion method documentation
- **Theming Guide**: CSS variable reference with examples
- **Use Case Examples**: 4 complete implementation guides in playground

## 🚀 Playground Enhancements
- **Layout Gallery Hub**: Visual directory for banner, modal, and inline layouts
- **Navigation System**: Breadcrumbs and sub-navigation tabs
- **Use Case Examples**:
- Exit Intent Email Capture (exit intent + modal forms)
- Feature Discovery Journey (scroll depth + inline + modal)
- Time-Delayed Promotions (time delay + hero image modal)
- Promotions & Announcements (banner examples)
- **Interactive Demos**: Live examples with SDK integration

## ⚠️ Breaking Changes
None. This is a **minor** release with backward compatibility.

## 🔜 Next Steps (Phase 3+)
- Browser tests for form focus management
- Composable form plugin (separate from modal)
- Additional layout plugins (tooltip, slideout, sticky bar)
- Multi-instance support with `instanceId` tracking

---

**Migration Guide**: No migration needed. Simply upgrade and start using the new plugins!

**Full Changelog**: See [Phase 2 Spec](https://github.com/prosdevlab/experience-sdk/blob/main/specs/phase-2-presentation-layer/spec.md)

22 changes: 20 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,21 @@ jobs:
- name: Install dependencies
run: pnpm install

- name: Get Playwright version
id: playwright-version
run: echo "version=$(node -p "require('./package.json').devDependencies.playwright")" >> $GITHUB_OUTPUT

- name: Cache Playwright browsers
uses: actions/cache@v4
id: playwright-cache
with:
path: ~/.cache/ms-playwright
key: ${{ runner.os }}-playwright-${{ steps.playwright-version.outputs.version }}

- name: Install Playwright browsers
if: steps.playwright-cache.outputs.cache-hit != 'true'
run: npx playwright install --with-deps chromium

- name: Lint
run: pnpm lint

Expand All @@ -38,5 +53,8 @@ jobs:
- name: Type check
run: pnpm typecheck

- name: Test
run: pnpm test
- name: Test (Unit)
run: pnpm test

- name: Test (Browser)
run: pnpm test:browser
135 changes: 95 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,61 +4,96 @@

**A lightweight, explainable client-side experience runtime built on [@lytics/sdk-kit](https://github.com/lytics/sdk-kit)**

Experience SDK decides if/when/why experiences (banners, modals, tooltips) should render. Every decision comes with structured reasons, making debugging and testing effortless.
Experience SDK enables marketers and developers to create personalized experiences (modals, banners, inline content) with powerful targeting and explainability. Every decision comes with structured reasons, making debugging and testing effortless.

## Features

- 🔍 **Explainability-First** - Every decision includes structured reasons
- 🧩 **Plugin-Based** - Built on @lytics/sdk-kit's powerful plugin system
- 📦 **Script Tag Ready** - Works without build tools
- 🎨 **Presentation Plugins** - Modal, banner, and inline content rendering
- 📝 **Built-in Forms** - Email capture, surveys, feedback with validation
- 🎯 **Smart Triggers** - Exit intent, scroll depth, time delay, page visits
- 📦 **Script Tag Ready** - Works without build tools (marketers love it!)
- 💅 **CSS Variables** - Easy theming with CSS custom properties
- 🎯 **Type-Safe** - Full TypeScript support
- 🪶 **Lightweight** - < 15KB gzipped
- 🪶 **Lightweight** - ~26KB gzipped with all plugins (13.4KB core)
- 🔧 **Developer-Friendly** - Built for inspection and debugging

## Quick Start

### Script Tag
### Script Tag (For Marketers)

```html
<script src="https://sdk.prosdevlab.com/experience-sdk.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@prosdevlab/experience-sdk@latest/dist/experience-sdk.global.js"></script>
<script>
// Initialize
experiences.init({ debug: true });

// Register an experience
experiences.register('welcome-banner', {
type: 'banner',
// Exit intent modal with email capture
experiences.register('exit-intent-modal', {
type: 'modal',
content: {
title: '🚀 Wait! Before You Go...',
message: 'Join 10,000+ subscribers for exclusive content',
form: {
fields: [
{ name: 'email', type: 'email', label: 'Email', required: true }
],
submitButton: { text: 'Subscribe', variant: 'primary' }
}
},
targeting: {
url: { contains: '/' },
frequency: { max: 1, per: 'session' }
url: { contains: '/pricing' }
},
content: {
title: 'Welcome!',
message: 'Thanks for visiting.'
display: {
trigger: 'exitIntent',
frequency: { max: 1, per: 'session' }
}
});

// Evaluate (shows if rules match)
const decision = experiences.evaluate();

// See why
console.log(decision.reasons);
// ['✅ URL contains "/"', '✅ Not shown this session (0/1)']
// Listen for form submissions
experiences.on('experiences:modal:form:submit', (event) => {
console.log('Email submitted:', event.formData.email);
// Send to your API, analytics, etc.
});
</script>
```

### npm
### npm (For Developers)

```bash
npm install @prosdevlab/experience-sdk
npm install @prosdevlab/experience-sdk @prosdevlab/experience-sdk-plugins
```

```typescript
import experiences from '@prosdevlab/experience-sdk';
import { createInstance } from '@prosdevlab/experience-sdk';
import { modalPlugin, inlinePlugin, bannerPlugin } from '@prosdevlab/experience-sdk-plugins';

const sdk = createInstance({ debug: true });

// Use plugins
sdk.use(modalPlugin);
sdk.use(inlinePlugin);
sdk.use(bannerPlugin);

// Register experiences
sdk.register('feature-tip', {
type: 'inline',
content: {
selector: '#feature-section',
position: 'after',
message: '<div>💡 New: Check out our analytics dashboard!</div>'
},
display: {
trigger: 'scrollDepth',
triggerData: { threshold: 50 }
}
});

experiences.init({ debug: true });
experiences.register('welcome', { ... });
const decision = experiences.evaluate();
// Listen to events
sdk.on('experiences:shown', (event) => {
analytics.track('Experience Shown', { id: event.experienceId });
});
```

### Event-Driven Architecture
Expand Down Expand Up @@ -90,18 +125,38 @@ See the [Events Reference](https://your-docs-url/api/events) for comprehensive d

## Documentation

See [notes/IMPLEMENTATION_PLAN.md](notes/IMPLEMENTATION_PLAN.md) for detailed implementation guide.
- **[Plugin Reference](https://prosdevlab.github.io/experience-sdk/reference/plugins)** - Modal, Banner, Inline plugins
- **[Theming Guide](https://prosdevlab.github.io/experience-sdk/guides/theming)** - CSS variables customization
- **[Playground](https://experience-sdk-playground.vercel.app)** - Live demos and use cases

## Project Status

🚧 **v0.1.0 in development** - Foundation phase

- [ ] Core runtime with explainability
- [ ] Storage plugin (frequency capping)
- [ ] Debug plugin (event emission)
- [ ] Banner plugin (delivery)
- [ ] Demo site
- [ ] UMD bundle
✅ **v0.2.0** - Presentation Layer Complete

**Core Runtime:**
- ✅ Explainability-first evaluation engine
- ✅ Plugin system (sdk-kit)
- ✅ Event-driven architecture
- ✅ Hybrid API (singleton + instance)

**Display Condition Plugins:**
- ✅ Exit Intent - Detect users about to leave
- ✅ Scroll Depth - Trigger at scroll thresholds
- ✅ Time Delay - Time-based triggers
- ✅ Page Visits - Session/total visit tracking
- ✅ Frequency Capping - Impression limits

**Presentation Plugins:**
- ✅ Modal - Announcements, promotions, forms
- ✅ Banner - Top/bottom dismissible messages
- ✅ Inline - Embed content in page DOM

**Features:**
- ✅ Built-in form support (validation, submission)
- ✅ CSS variable theming
- ✅ TypeScript support
- ✅ 432 tests passing
- ✅ ~26KB gzipped (all plugins)

## Development

Expand Down Expand Up @@ -149,13 +204,13 @@ Built on [@lytics/sdk-kit](https://github.com/lytics/sdk-kit), Experience SDK sh

## Roadmap

- **Phase 0 (v0.1.0)**: Foundation - Runtime + 3 plugins + demo
- **Phase 1 (v0.2.0)**: Chrome Extension - DevTools integration
- **Phase 2 (v0.3.0)**: Advanced plugins - More experience types
- **Phase 3 (v0.4.0)**: Developer tools - Playground & testing
- **Phase 4 (v1.0.0)**: Production-ready
- **Phase 0 (v0.1.0)**: Foundation - Core runtime, display condition plugins, banner plugin
- **Phase 1 (v0.2.0)**: Presentation Layer - Modal & inline plugins with forms
- 🚧 **Phase 2 (v0.3.0)**: Developer Experience - Chrome DevTools extension
- 🚧 **Phase 3 (v0.4.0)**: Advanced Features - Tooltip plugin, multi-instance support
- 🚧 **Phase 4 (v1.0.0)**: Production Ready - Performance optimizations, advanced targeting

See [notes/vision-and-roadmap.md](notes/vision-and-roadmap.md) for full roadmap.
See the [full roadmap](notes/vision-and-roadmap.md) for details.

## License

Expand Down
6 changes: 6 additions & 0 deletions biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,16 @@
"includes": [
"packages/core/src/types.ts",
"packages/core/src/runtime.ts",
"packages/core/src/singleton.ts",
"packages/plugins/src/types.ts",
"packages/plugins/src/exit-intent/exit-intent.ts",
"packages/plugins/src/scroll-depth/scroll-depth.ts",
"packages/plugins/src/page-visits/page-visits.ts",
"packages/plugins/src/time-delay/time-delay.ts",
"packages/plugins/src/modal/modal.ts",
"packages/plugins/src/modal/types.ts",
"packages/plugins/src/inline/inline.ts",
"packages/plugins/src/inline/types.ts",
"packages/plugins/src/utils/sanitize.ts",
"specs/**/contracts/types.ts",
"docs/**/*.tsx"
Expand Down
1 change: 1 addition & 0 deletions docs/pages/_meta.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"index": "Introduction",
"getting-started": "Getting Started",
"guides": "Guides",
"demo": "Examples",
"reference": "API Reference"
}
Expand Down
4 changes: 4 additions & 0 deletions docs/pages/guides/_meta.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"theming": "CSS Theming"
}

Loading