Next Generation Storefront NGS
The Next Generation Storefront™ is a UX & data standard that empowers consumers to make informed flight reservation decisions. NGS presents like options from different airlines taking the guesswork out of the customer journey. It allows travelers to compare apples to apples when shopping online.
This document presents artifacts depicting an NGS implemented design for constructing an accessible, responsive, and progessive single-page booking app.
This design is a startup travel, expense, and itinerary concierge platform that manages flight, car, and hotel reservations for corporate events.
While Vue.js is mentioned explicitly, any modern framework(s) may be implemented (Micro Frontend).
// A popover is a transient view that shows on a content screen when
// a user clicks on a control button or within a defined area.
/* __ __ __ __ __ __ __
/\ \/\ \ /\ \ /\ \/\ \ /\_\_\_\
\ \ \_\ \ \ \ \ \ \ \_\ \ \/_/\_\/_
\ \_____\ \ \_\ \ \_____\ /\_\/\_\
\/_____/ \/_/ \/_____/ \/_/\/_/
🌑🌒🌓🌔🌕🌖🌗🌘🌑*/
let oPopOver = ( ( _win, _doc, _qry ) => {
let arPops = [], ePos, iOffTop=0, iOffLft=0;
return { // Popover UX pattern
"init": function(){ // wire DOM events
arPops= [].slice.call(_doc.querySelectorAll( _qry ));
_win.addEventListener("resize", oPopOver.closeAll);
_win.addEventListener("scroll", oPopOver.closeAll);
_doc.body.addEventListener("click", function( e ){ // Outside Click
let eTarget = e.target, bInside = false;
while( eTarget.tagName !== "HTML" ){
if( eTarget.dataset.popover ){ bInside = true; break; }
eTarget = eTarget.parentNode;
}
if( !bInside ){ // Tapped Outside of Popover
oPopOver.closeAll();
}
}, true);
},
"open": function(id, evPos){ // Open a single Popover
if( arPops.length == 0) return false;
oPopOver.closeAll();
ePos = evPos.currentTarget;
let elPop = arPops.filter(function(el){
return ( el.id == id );
})[0];
iOffTop = Number(elPop.dataset.popoverPos.split("|")[0]);
iOffLft = Number(elPop.dataset.popoverPos.split("|")[1]);
elPop.dataset.popover = "true"; // Open and Active
elPop.style.left = oPopOver.position().left+"px";
elPop.style.top = oPopOver.position().top+"px";
},
"closeAll": function(){ // Close all Popovers
if( arPops.length == 0) return false;
arPops.map(function(el){
el.dataset.popover = "false";
});
},
"position": function(){ // Determine Popover position
let rec = ePos.getBoundingClientRect(),
pxLft = _win.pageXOffset || _doc.documentElement.scrollLeft,
pxTop = _win.pageYOffset || _doc.documentElement.scrollTop;
return { top: (rec.top + pxTop + iOffTop), left: (rec.left + pxLft + iOffLft) }
}
}
})(window, _doc, "[data-popover]"); // Declarative implementation
// DataVis 🚀 Micro Frontend 🚀 PWA
Portfolio Blog | 🦄 Résumé | UX micro-library | Neodigm UX Wiki | NPM | Github | LinkedIn | Gists | Salesforce | Code Pen | Machvive | Arcanus 55 | Medium | W3C | InfoSec