-
Notifications
You must be signed in to change notification settings - Fork 0
feat: Phase 2 - Modal & Inline Plugins with Forms (v0.2.0) #45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
- Implement modal plugin with centered overlay layout - Add focus trap and keyboard navigation (Tab, Escape) - Include ARIA attributes for screen readers - Support multi-button layouts with primary/secondary variants - Add custom className and style props for customization - Auto-register in core runtime - Comprehensive test coverage (31 tests) Features: - Dismissable (close button, backdrop click, Escape key) - Configurable zIndex, backdrop dismiss, and dismissable options - HTML sanitization for XSS prevention - Event emission (shown, dismissed, action, trigger) - Focus management (trap focus, return on close) - Button variants (primary, secondary) with hover states Also fixed: - Update all display condition plugins to use 'sdk:destroy' event - Add ExperienceButton type (replaces BannerButton) - Update modal trigger state in Context interface
…testing Modal Enhancements: - Add size variants (sm/md/lg/fullscreen/auto) - Add mobile fullscreen behavior (auto-enables for lg on <640px) - Add hero image support with lazy loading and responsive sizing - Add animations (fade, slide-up, none) with configurable duration - Add position options (center, bottom) - Update types to support new features Testing Infrastructure: - Set up Vitest Browser Mode with Playwright for real browser testing - Add 5 browser tests for mobile viewport behavior - Integrate happy-dom for faster unit tests (2x speed improvement) - Update modal tests to use happy-dom environment - Add vitest.browser.config.ts for browser-specific test configuration - Exclude browser tests from regular unit test runs CI/CD: - Add browser tests to GitHub Actions workflow - Add Playwright browser caching for faster CI runs - Install Chromium with system dependencies in CI Test Coverage: - Modal plugin: 50 tests total (45 unit + 5 browser) - All tests passing (359 unit + 5 browser = 364 total) - Mobile auto-fullscreen tested in real Chromium browser Dependencies: - Add @vitest/browser@4.0.16 - Add @vitest/browser-playwright@4.0.16 - Add playwright@1.57.0 - Add happy-dom@20.0.11 Relates to #40
Add comprehensive form support to modal plugin: Form Types & Validation: - Add FormConfig, FormField, FormState, ValidationResult types - Implement pure validation functions (validateField, validateForm) - Support email, url, tel, number, text, textarea field types - Custom validation with regex patterns and functions - 35 validation tests passing Form Rendering: - Pure rendering functions (renderForm, renderFormField, renderSubmitButton) - Tailwind-inspired CSS styles (form-styles.ts) - Success/error state rendering - Accessibility: ARIA attributes, labels, error messages - Responsive design with focus states Modal Integration: - Detect content.form and render form instead of buttons - Backward compatible with existing button-based modals - Forms easily extractable to separate plugin later Tests: 80 total (45 modal + 35 validation)
Convert hardcoded CSS values to CSS variables for better theming: Modal Plugin: - Create modal-styles.ts with CSS variable helpers - Refactor modal.ts inline styles to use CSS variables - Variables for colors, spacing, typography, shadows - Support for custom hover states via CSS variables Form Styles: - Refactor form-styles.ts to use CSS variables - All form elements (inputs, labels, buttons, states) themeable - Consistent naming convention: --xp-form-*, --xp-input-*, etc. Banner Plugin: - Convert banner CSS <style> tag to use CSS variables - Support for light/dark mode via CSS variables - Variables for all colors, spacing, typography - Responsive variables (mobile padding, etc.) Benefits: - Users can theme without !important - Clean CSS variable API - Dark mode support - Better design system integration - No breaking changes (defaults match previous styles) Bundle Size: - Plugins: 56.35 KB -> 62.11 KB uncompressed (+5.76 KB) - Gzipped: 12.7 KB -> 13.7 KB (+1 KB) Tests: 125 passing (45 banner + 45 modal + 35 validation)
Add complete form event handling and state management: Event Listeners: - input: Track form data changes, emit change events - blur: Validate field on blur, show/clear errors - submit: Validate entire form, emit submit event Form State Management: - Track form data by experienceId - Show inline validation errors - Disable submit button during submission - Update aria-invalid and error messages API Methods: - showFormState(id, 'success'|'error'): Replace form with state UI - resetForm(id): Clear all form data and errors - getFormData(id): Get current form data Events Emitted: - experiences:modal:form:change: Field value changed - experiences:modal:form:validation: Field/form validated - experiences:modal:form:submit: Form submitted (validation passed) - experiences:modal:form:state: Form state changed Validation: - Uses pure validateField/validateForm functions - Real-time feedback on blur - All fields validated on submit - Custom validation function support Tests (11 new): - Render form with fields and labels - Input change events and data tracking - Field validation on blur - Clear errors when field becomes valid - Full form validation on submit - Submit event with valid data - Disable submit button during submission - Get/reset form data - Show success/error states Tests: 405 passing (56 modal, 35 form validation, 11 form integration)
Add inline plugin supporting 5 insertion methods: replace, append, prepend, before, after. Implementation: - types.ts: InlineContent, InlinePlugin, InsertionPosition types - insertion.ts: Pure DOM manipulation functions - inline.ts: Plugin implementation with CSS variables - Auto-register in core runtime Features: - CSS selector targeting - Dismissal with localStorage persistence - Error events when selector not found - Multi-instance support - Custom className and style props - Auto-loads storage plugin if needed Events: - experiences:shown, experiences:dismissed - experiences:inline:error - trigger:inline Bundle: 54 KB -> 57.6 KB (+3.6 KB)
- 24 tests covering all inline plugin functionality - Insertion methods: replace, append, prepend, before, after - Dismissal with persistence - Custom styling (className, style props) - Multi-instance support - Error handling (selector not found) - HTML sanitization - Cleanup on destroy - Event emission (shown, dismissed, error) Fixed: - Use sdk:destroy event instead of destroy - Add config parameter to plugin function signature - Remove unused InlineContent import All 429 tests passing
- Created modal plugin docs with form examples - Created inline plugin docs with insertion methods - Updated plugins overview and navigation - Updated core README with new features - Updated plugins README with all plugins - Added CSS variables documentation - Added comprehensive examples for all layouts
- Hide existing modal before showing new one - Only one modal visible at a time - Add test for modal replacement behavior - Fix linter errors (use for...of instead of forEach) All 427 tests passing
- Register listeners for each trigger type individually - Workaround for sdk-kit emitter not passing event name to wildcard handlers - Prevents 't.replace is not a function' error - Supports: exitIntent, scrollDepth, timeDelay, pageVisits, modal, inline Note: sdk-kit's emitter passes only data to wildcard handlers, not the event name. This is a known limitation. For now, we register each trigger explicitly. All 427 tests passing
- Add getter properties for modal, inline, banner on singleton - Allows script tag users to access window.experiences.modal.show() - Fixes playground getting stuck at 'Loading Experience SDK...' Now window.experiences.modal, .inline, .banner are available
- Make ExperienceRuntime.sdk public (not readonly) for Proxy access - Add default export for IIFE build to expose singleton correctly - Update singleton Proxy to dynamically access defaultInstance.sdk - Remove manual window assignment (handled by IIFE build) - Fixes playground integration where experiences.modal was undefined This enables script tag users to access plugin APIs via global: experiences.modal.show(), experiences.inline.show(), etc.
- Prevent duplicate inline experiences from being shown - Fix scroll depth threshold evaluation to match specific percentages - Remove trigger:inline emission that caused infinite event loops - Add scrollDepth.reset() method to clear triggered thresholds - Expand HTML sanitizer to allow div, ul, li tags for rich content - Add smooth fade-in animations to inline experiences - Add display conditions evaluation for trigger-based experiences - Add inline to Experience type union - Add tests for new functionality (432 tests passing)
- Update main README with v0.2.0 features and examples - Update packages/core/README.md (already accurate) - Fix duplicate header in packages/plugins/README.md - Update changeset test counts (432 tests, 56 modal tests) - Add script tag and ESM usage examples - Update roadmap and project status
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Phase 2: Presentation Layer - Modal & Inline Plugins
Closes #40 - Modal Plugin
Closes #41 - Inline Plugin
Closes #42 - Testing - Modal, Inline, and Integration
Closes #43 - Documentation
Closes #44 - Playground Examples
What's New
This release completes the presentation layer with two powerful new rendering plugins and built-in form support.
Modal Plugin (#40)
show(),remove(),isShowing(),showFormState(),resetForm(),getFormData()Inline Plugin (#41)
replace,append,prepend,before,aftershow(),remove(),isShowing()Forms (Built into Modal)
experiences:modal:form:submiteventTheming
All plugins now support CSS variable theming:
--xp-modal-*variables--xp-form-*variables--xp-banner-*variables (refactored)--xp-inline-*variablesSee Theming Guide for full reference.
Bundle Size
Testing (#42)
432 tests passing (unit, integration, browser)
Coverage: 100% for modal, inline, and form validation logic
Documentation (#43)
Complete documentation added:
docs/pages/reference/plugins/modal.mdx)docs/pages/reference/plugins/inline.mdx)docs/pages/guides/theming.mdx)Playground Examples (#44)
Interactive demos added:
Breaking Changes
None. This is a minor release with backward compatibility.
Next Steps
All Phase 2 tasks complete