Bloom Grace
A responsive React + Vite flower shop SPA focused on performance and accessibility — ARIA roles, keyboard navigation, semantic HTML, the works.
- Type
- Web
- Role
- Solo
- Status
- Archived
- Tech
- React Vite JavaScript CSS
- Started
- Jun 2023
Overview
Bloom Grace is a single-page flower shop web app built with React and Vite. It was a learning exercise in two things: doing accessibility the right way from the start (not retrofitted at the end), and performance tuning on a Vite-first project with real images and interactions. The result is a responsive, screen-reader-friendly storefront with smooth navigation and an elegant browsing experience.
Features
- Product showcase — floral arrangements with high-quality images and descriptions, grouped by category for different occasions (weddings, bouquets, holiday arrangements).
- Search — quick filtering across the catalog so users can find specific flowers.
- Profile settings — edit basic user information locally.
- Subscription modal — a pop-up for newsletter / promotions signup with proper focus-trap behavior.
- Shopping cart (partial) — add / edit / remove items; checkout was left as out-of-scope for the exercise.
- Responsive design — works cleanly from 360px phones up to wide desktop.
Accessibility first
This is the part I’m most proud of. Instead of bolting on accessibility after the visual pass, every component was built with it as a first-class constraint:
- ARIA roles on interactive widgets (dialogs, menus, toggles) so screen readers announce them correctly.
- Keyboard navigation throughout — every button, link, and form field is reachable via Tab, activatable via Space/Enter. Modals trap focus while open and restore it when closed.
- Semantic HTML —
<nav>,<main>,<article>,<button>used for their actual semantic meaning rather than styled<div>everywhere. - High contrast & system-pref awareness — color choices checked against WCAG contrast ratios.
Stack
- React — component-based UI.
- Vite — dev server + build tool. Chose Vite over CRA for speed and modern tooling.
- CSS / styled components — custom responsive layouts, no UI library.
- React Router (partial wire-up) — smooth client-side navigation between pages.
Notable bits
- Accessibility as the design constraint — forced every component to use real semantic elements instead of divs, which ended up making the code cleaner and more maintainable. Best side effect of the exercise.
- Vite DX — coming from Create-React-App, the startup time difference alone made the project feel worth building in Vite.
- Scoped learning — I intentionally left cart checkout and real backend integration out of scope so I could focus on the frontend craftsmanship parts.