Easter

Web UI

altText

Summary

What if media and apps could be hidden and unlocked with a secret code? Easter is a UI modal system that does this. It runs as an imported script on any webpage, acts like a micro-CMS with custom themes, responds to keyboard and browser events, and includes a hidden gamepad controller. Media can be independently-developed and loaded as "eggs". Click here for a sample prototype modeled after the tech educational platform Boot.dev.

Media

Design / Tech

Code:

  • TypeScript
  • HTML
  • CSS

Libs:

  • Vue
  • Vite

Design:

  • Tailwind

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 include 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.