eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ OfferListComponent: () => (/* binding */ OfferListComponent)\n/* harmony export */ });\n/* harmony import */ var _util_html__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./util/html */ \"./docs/examples/01. Decomposing UI Components/src/util/html.ts\");\n/* harmony import */ var _util_EventEmitter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./util/EventEmitter */ \"./docs/examples/01. Decomposing UI Components/src/util/EventEmitter.ts\");\n/**\n * @fileoverview\n * This file comprises a reference implementation\n * of the `IOfferListComponent` interface called simply `OfferListComponent`\n */\n\n\n/**\n * An `OfferListComponent` visualizes a list of short descriptions\n * of offers (“previews”) and allows for interacting with it.\n *\n * The responsibility of this class is:\n * * Rendering previews and react on the preview list change event\n * * Allowing user to select a preview and emit the corresponding event\n */\nclass OfferListComponent {\n constructor(context, container, offerList, options) {\n this.context = context;\n this.container = container;\n this.offerList = offerList;\n this.options = options;\n /**\n * An accessor to subscribe for events or emit them.\n */\n this.events = new _util_EventEmitter__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();\n /**\n * An inner state of the component, whether it's now\n * rendered or not\n */\n this.shown = false;\n /**\n * Event listeners\n */\n this.listenerDisposers = [];\n /**\n * An event handler for the context state change\n * event. Exposed as a protected method to allow\n * for altering the default reaction in subclasses\n */\n this.onOfferListChange = ({ offerList }) => {\n if (this.shown) {\n this.hide();\n }\n this.offerList = offerList;\n if (offerList !== null) {\n this.show();\n }\n };\n /**\n * A listener to the DOM 'click' event. Exposed as a shortcut\n * to allow for enriching the UX in subclasses.\n * If we've taken long and 'proper' way, this should be\n * a spearate composer to route events and data flow between\n * the component and its representation.\n */\n this.onClickListener = (e) => {\n var _a;\n let target = e.target;\n while (target) {\n const offerId = (_a = target.dataset) === null || _a === void 0 ? void 0 : _a.offerId;\n if (offerId !== undefined) {\n this.onOfferClick(offerId);\n break;\n }\n target = target.parentNode;\n }\n };\n this.listenerDisposers.push(this.context.events.on('offerPreviewListChange', this.onOfferListChange));\n if (offerList !== null) {\n this.show();\n }\n }\n /* Provided for consistency for the developer\n to have access to the full state\n of the component */\n getOfferList() {\n return this.offerList;\n }\n /**\n * Destroys the component\n */\n destroy() {\n this.teardownListeners();\n this.hide();\n this.offerList = null;\n }\n /**\n * Allows for programmatically selecting an\n * offer in the list\n */\n selectOffer(offerId) {\n this.events.emit('offerSelect', {\n offerId\n });\n }\n /**\n * A helper method to generate the DOM structure for\n * displaying a preview. Exposed\n */\n generateOfferHtml(offer) {\n return (0,_util_html__WEBPACK_IMPORTED_MODULE_0__.html) `<li\n class=\"our-coffee-sdk-offer-list-offer\"\n data-offer-id=\"${(0,_util_html__WEBPACK_IMPORTED_MODULE_0__.attrValue)(of
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ OfferPanelComponent: () => (/* binding */ OfferPanelComponent)\n/* harmony export */ });\n/* harmony import */ var _test_util__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../test/util */ \"./docs/examples/01. Decomposing UI Components/test/util.ts\");\n/* harmony import */ var _OfferPanelButton__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./OfferPanelButton */ \"./docs/examples/01. Decomposing UI Components/src/OfferPanelButton.ts\");\n/* harmony import */ var _util_EventEmitter__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./util/EventEmitter */ \"./docs/examples/01. Decomposing UI Components/src/util/EventEmitter.ts\");\n/* harmony import */ var _util_html__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./util/html */ \"./docs/examples/01. Decomposing UI Components/src/util/html.ts\");\n/**\n * @fileoverview\n * This file comprises a reference implementation\n * of the `IOfferPanelComponent` interface called simply `OfferPanelComponent`\n */\n\n\n\n\n/**\n * A `OfferPanelComponent` represents a UI to display\n * the detailed information regarding an offer (a “full view”)\n * implying that user can act on the offer (for example,\n * to create an order).\n *\n * The responsibility of the component is:\n * * Displaying detailed information regarding an offer\n * and update it if the corresponding context state\n * change event happens\n * * Rendering “buttons,” i.e. the control elements\n * for user to express their intentions\n * * Emitting “actions” when the user interacts with the buttons\n * * Closing itself if needed\n */\nclassOfferPanelComponent{\nconstructor(context,container,currentOffer,options){\nthis.context=context;\nthis.container=container;\nthis.currentOffer=currentOffer;\nthis.options=options;\n/**\n * An accessor to subscribe for events or emit them.\n */\nthis.events=new_util_EventEmitter__WEBPACK_IMPORTED_MODULE_2__.EventEmitter();\n/**\n * A DOM element container for buttons\n */\nthis.buttonsContainer=null;\n/**\n * An array of currently displayed buttons\n */\nthis.buttons=[];\n/**\n * Event listeners\n */\nthis.listenerDisposers=[];\n/**\n * An inner state of the component, whether it's open\n * or closed\n */\nthis.shown=false;\n/**\n * A listener for the parent context's state change.\n * Exposed as a protected method to allow for adding additional\n * functionality\n */\nthis.onOfferFullViewToggle=({offer})=>{\nif(this.shown){\nthis.hide();\n}\nthis.currentOffer=offer;\nif(offer){\nthis.show();\n}\n};\n/**\n * A listener for button pressing events. Exposed\n * as a protected method to allow for adding custom\n * reactions\n */\nthis.onButtonPress=({target})=>{\nif(this.currentOffer!==null){\nthis.events.emit('action',{\naction:target.action,\ntarget,\ncurrentOfferId:this.currentOffer.offerId\n});\n}\n};\nthis.listenerDisposers.push(this.context.events.on('offerFullViewToggle',this.onOfferFullViewToggle));\nif(currentOffer!==null){\nthis.show();\n}\n}\n/* Exposed for consistency */\ngetOffer(){\nreturnthis.currentOffer;\n}\n/**\n * Destroys the panel and its buttons\n */\ndestroy(){\nthis.currentOffer=null;\nfor(constdisposerofthis.listenerDisposers){\ndisposer.off();\n}\nif(this.shown){\n
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ SearchBox: () => (/* binding */ SearchBox)\n/* harmony export */ });\n/* harmony import */ var _util_EventEmitter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./util/EventEmitter */ \"./docs/examples/01. Decomposing UI Components/src/util/EventEmitter.ts\");\n/* harmony import */ var _SearchBoxComposer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./SearchBoxComposer */ \"./docs/examples/01. Decomposing UI Components/src/SearchBoxComposer.ts\");\n/* harmony import */ var _util_html__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./util/html */ \"./docs/examples/01. Decomposing UI Components/src/util/html.ts\");\n/**\n * @fileoverview\n * This file comprises a reference implementation\n * of the `ISearchBox` interface called simply `SearchBox`\n */\nvar __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value));}catch(e){reject(e);}}\nfunctionstep(result){result.done?resolve(result.value):adopt(result.value).then(fulfilled,rejected);}\nstep((generator=generator.apply(thisArg,_arguments||[])).next());\n});\n};\n\n\n\n/**\n * A `SearchBox` represents a UI component\n * that allows an end user to enter search queries,\n * work with the received results and place orders.\n * The user input which will be propagated\n * to the underlying `ourCoffeeApi` functionality.\n *\n * The responsibility of this class is:\n * * Handling user input consistently\n * * Instantiating the `ISearchBoxComposer` subcomponent\n * that takes care of the offer list UI & UX, and creating\n * orders if a `composers` requests to.\n * * Emitting events when current displayed search results\n * (offers) are changed\n * * Providing methods to programmatically initialize\n * searching a given query and make orders\n */\nclassSearchBox{\n/**\n * A `SearchBox` synchoronously initializes itself\n * in the given HTML element context and will use\n * the given instance of the `ICoffeeApi` interface\n * to run search queries and create orders.\n */\nconstructor(container,coffeeApi,options){\nthis.container=container;\nthis.coffeeApi=coffeeApi;\n/**\n * An accessor to subscribe for events or emit them.\n */\nthis.events=new_util_EventEmitter__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();\n/**\n * The current list of search results (offers) to\n * present to the user. Might be `null`.\n */\nthis.offerList=null;\n/**\n * A current asynchronous request to the search API (if any).\n * Needed to manage a possible race if the user or\n * the developer fires several search queries in a row.\n */\nthis.currentRequest=null;\n/**\n * Event listeners to get disposed upon desructing the `SearchBox`\n */\nthis.listenerDisposers=[];\n/**\n * Handling a 'Search' button press event. Provided as\n * a protected method to allow custom validations\n * or alternative inputs\n */\nthis.onSearchButtonClickListener=()=>{\nconstquery=this.input.value.trim();\nif(query){\nthis.search(query);\n}\n};\nthis.options=\noptions!==undefined\n?Object.assign(Object.assign({},SearchBox.DEFAULT_OPTIONS),options):Object.assign({},SearchBox.DEFAULT_OPTIONS);\nthis.render();\nthis.composer=this.buildC
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ SearchBoxComposer: () => (/* binding */ SearchBoxComposer)\n/* harmony export */ });\n/* harmony import */ var _OfferListComponent__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./OfferListComponent */ \"./docs/examples/01. Decomposing UI Components/src/OfferListComponent.ts\");\n/* harmony import */ var _OfferPanelComponent__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./OfferPanelComponent */ \"./docs/examples/01. Decomposing UI Components/src/OfferPanelComponent.ts\");\n/* harmony import */ var _util_EventEmitter__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./util/EventEmitter */ \"./docs/examples/01. Decomposing UI Components/src/util/EventEmitter.ts\");\n/**\n * @fileoverview\n * This file comprises a reference implementation\n * of the `ISearchBoxComposer` interface called simply `SearchBoxComposer`\n */\n\n\n\n/**\n * A `SearchBoxComposer` stands for an entity which\n * controls the data flow between an abstract `ISearchBox`\n * and a specific UI concept.\n *\n * This reference implementation assumes that each offer\n * might be represented as a list item (a 'preview') and\n * as a detailed representation (a `full view`).\n *\n * The responsibility of the composer is:\n * * Instantiating and destroying nested components\n * that handles previews (`IOfferListComponent`) and\n * a full view (`IOfferPanelComponent`)\n * * Handling an internal state (a list of offers and\n * a currently selected offer) and emitting events when\n * it changes\n * * Generating previews, full views, and UI options when\n * needed\n * * Notifying parent `ISearchBox` about the user's intention\n * to place an order\n */\nclassSearchBoxComposer{\n/**\n * A `SearchBoxComposer` synchoronously initializes itself\n * in the context of the given `SearchBox` with provided\n * options and HTML container element.\n */\nconstructor(context,container,contextOptions){\nthis.context=context;\nthis.container=container;\nthis.contextOptions=contextOptions;\n/**\n * An accessor to subscribe for events or emit them.\n */\nthis.events=new_util_EventEmitter__WEBPACK_IMPORTED_MODULE_2__.EventEmitter();\n/**\n * Instances of subcomponents and HTML element containers\n * to host them\n */\nthis.offerListContainer=null;\nthis.offerListComponent=null;\nthis.offerPanelContainer=null;\nthis.offerPanelComponent=null;\n/**\n * A current state of the composer itself\n */\nthis.offerList=null;\nthis.currentOffer=null;\n/**\n * Event listeners\n */\nthis.onOfferPanelAction=(event)=>{\nthis.performAction(event);\n};\nthis.onOfferListOfferSelect=({offerId})=>this.selectOffer(offerId);\n/**\n * The event subscriber for the parent context `offerListChange`\n * event. Transforms the high-level event into a couple of lover-level\n * ones and maintaints the composer's internal state.\n * Exposed as a protected method to allow custom reactions\n * to parent context state change in subclasses.\n */\nthis.onContextOfferListChange=({offerList})=>{\nif(this.currentOffer!==null){\nthis.currentOffer=null;\nthis.events.emit('offerFullViewToggle',{offer:null});\n}\nthis.offerList=offerList;\nthis.events.emit('offerPreviewListChange',{\nofferList:this.generateOfferPreviews(this.offerList,this.contextOptions)\n});\n};\nthis.offerListContainer=document.createElement('div');\ncontainer.appendChild(this.offerListContainer);\nthis.offerListComponent=this.buildOfferListComponent(this,this.offerL