Easter

Media

altText

Summary

Modal windows are typically used for notifications and advertisements. But they'd also work for asides, callouts, mini-applications, games, and more. What if they could be hidden or unlocked with a secret code? Easter is a flexible modal system that does this. It runs as an imported script on a web page, and acts like a micro-CMS and includes a hidden game controller. Media can be independently-developed and loaded as "eggs".

Click here for a sample prototype modeled after the tech educational platform Boot.dev.

Like embedded video and analytics services, Easter media can be distributed on any webpage using an imported script. When combined with custom triggers and interactions, it allows being helpful and sparking intrigue, surprise, and joy. Although Easter can streamline lightweight media distribution across multiple internal web domains, perhaps the larger opportunity is with 3rd parties who can easily include content, promotions, games, or application functionality.


Media

Features

  • Embeddable on any website
  • Plug and play different modals as "eggs"
  • Use keyboard shortcuts, event handlers, and a game controller
  • Independently create and share eggs
  • Custom themes

Design / Tech

Code:

  • TypeScript
  • HTML
  • CSS

Libs:

  • Vue
  • Tailwind
  • Vite

Dive Deeper

Process

Easter's first implementation was inspired by the zsh plugin system, and was overly decoupled using separate repos, local web servers, and Tigris object storage in production. Although this worked, file caching became a problem.

Using the shadow-DOM was also explored. The key finding was that it'll selectively inherit properties from the parent document. Hosting media on 3rd party sites using shadow DOM requires setting reset styles and unique variable names that will unlikely conflict with the host.

The project was then rewritten as a simple monorepo, with additional features like a game controller and display for entering secret codes to unlock media.

Technical Details

Built with TypeScript, VueJS, and Vite. The system can display, trigger, and load independently-developed modals. Styling uses Tailwind and a host's stylesheets and images. For multiple domains, a shadow-DOM implementation has been successfully tested. For full-decoupling, the system can be adapted to dynamically load manifests and modules via server calls. This allows each usage to select the modals and affordances it's interested in, and load them on demand.

Known Issues

The modal fade-in uses a short (200ms) delay before showing content, unless the egg component explicitly signals readiness via a callback. This is a workaround for the lack of a true Vue Suspense or asset preloading mechanism. Eggs with images or assets can call the `notifyContentReady` prop to control when the modal appears, but most eggs will simply fade in after the delay. This may not be robust for long-loading assets.

Improvement Opportunities

Accessibility

  • Add ARIA roles (e.g., `role="dialog"`), `aria-modal="true"`, and proper labeling to the modal.
  • Implement a focus trap so keyboard users can't tab out of the modal.
  • Ensure the close button is always accessible and labeled.

Dynamic Egg Imports

Refactor egg registration to use dynamic imports for performance and bundle size reduction. Consider using a web server to list and serve available eggs.

Extending the Generic Trigger System

  • Add support for more trigger types (e.g. multi-click, long-press).
  • Optionally, unify multi-click into the generic system for even more consistency.